From: boylesgj AT lion DOT cs DOT latrobe DOT edu DOT au (Gregary J Boyles) Newsgroups: comp.os.msdos.djgpp Subject: Function locking problem (for ISR). Date: 26 Apr 1997 12:22:16 GMT Organization: Comp.Sci & Comp.Eng, La Trobe Uni, Australia Lines: 2432 Distribution: world Message-ID: <5jss1o$alv@lion.cs.latrobe.edu.au> NNTP-Posting-Host: lion.cs.latrobe.edu.au To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Precedence: bulk Excuse the size of the file below - you can ignore most of it. Down near the bottom of the file there is a function called DoLocking which calls Allego style macros for locking code and data. It causes a general protection fault because if I comment it out the problem disappears. Any sugestions? #define START_FUNC(x) void x##_start(){} #define END_FUNC(x) void x##_end(){} #define LOCK_FUNC(x) _go32_dpmi_lock_code(x##_start,(long)x##_end-(long)x##_start); #define LOCK_DATA(x) _go32_dpmi_lock_data(x,sizeof(x)); #include #include #include #include "string.hh" #include "misc.hh" //#define DEBUG /****************************************************************************/ /* */ /* CLASS NAME : TimeC */ /* */ /* PURPOSE : Stores a time i.e. hour, minute, second and hundredths of */ /* seconds and contains a function to determine the elapsed time */ /* (in hundredths of seconds). */ /* */ /****************************************************************************/ class TimeC { private: /************************/ /* PRIVATE DATA MEMBERS */ /************************/ unsigned char Hour,Minute,Second,Second100; public: /********************/ /* PUBLIC FUNCTIONS */ /********************/ // Constructor. TimeC(); // Destructor. ~TimeC(); // Calculates the elapsed time between this and the specified time. long unsigned int operator -(TimeC &Time); // Sets the data members. void Set(unsigned char Hour_,unsigned char Minute_,unsigned char Second_,unsigned char Second100_); }; // Constructor. START_FUNCTION(Func1); TimeC::TimeC() { Hour=Minute=Second=Second100=0; } END_FUNCTION(Func1); // Destructor. START_FUNCTION(Func2); TimeC::~TimeC() { Hour=Minute=Second=Second100=0; } END_FUNCTION(Func2); // Sets the data members. START_FUNCTION(Func3); void TimeC::Set(unsigned char Hour_,unsigned char Minute_,unsigned char Second_,unsigned char Second100_) { Hour=Hour_; Minute=Minute_; Second=Second_; Second100=Second100_; } END_FUNCTION(Func3); // Calculates the elapsed time between this and the specified time. START_FUNCTION(Func4); long unsigned int TimeC::operator -(TimeC &Time) { long int HundSec1,HundSec2; HundSec1=(Hour*60*60*100)+(Minute*60*100)+(Second*100)+Second100; HundSec2=(Time.Hour*60*60*100)+(Time.Minute*60*100)+(Time.Second*100)+Time.Second100; return labs(HundSec1-HundSec2); } END_FUNCTION(Func4); /****************************************************************************/ /* */ /* CLASS NAME : EventC */ /* */ /* PURPOSE : Stores the details of an input event and contains functions for*/ /* manipulating the data members. */ /* */ /****************************************************************************/ typedef enum {Mouse,KeyBoard} MouseOrKeyBoardE; typedef enum {Left,Center,Right} WhichMouseKeyE; typedef enum {Pressed,Released} WhatHappenedE; class EventC { public: /***********************/ /* PUBLIC DATA MEMBERS */ /***********************/ // What type of event. MouseOrKeyBoardE Type; // For key board events. unsigned char ASCII; unsigned int ScanCode; // For mouse events. WhichMouseKeyE MouseKey; // Was the key pressed or released. WhatHappenedE What; // Status of state shift keys. bool Alt,Ctrl,Shift,CapsLock,NumLock,ScrollLock; // Position of the mouse. unsigned int MouseX,MouseY; // Time stamp. TimeC Time; // Pointer to another event. EventC *Next; /********************/ /* PUBLIC FUNCTIONS */ /********************/ // Constructor. EventC(); // Desstructor. ~EventC(); // Copy function void operator =(EventC &Event); }; // Constructor. START_FUNCTION(Func5); EventC::EventC():Time() { Type=KeyBoard; ScanCode=ASCII=0; MouseKey=Left; What=Pressed; Alt=Ctrl=Shift=CapsLock=NumLock=ScrollLock=false; MouseX=MouseY=0; Next=NULL; } END_FUNCTION(Func5); // Desstructor. START_FUNCTION(Func6); EventC::~EventC() { Type=KeyBoard; ScanCode=ASCII=0; MouseKey=Left; What=Pressed; Alt=Ctrl=Shift=CapsLock=NumLock=ScrollLock=false; MouseX=MouseY=0; Next=NULL; } END_FUNCTION(Func6); // Copy function START_FUNCTION(Func7); void EventC::operator =(EventC &Event) { Type=Event.Type; ScanCode=Event.ScanCode; ASCII=Event.ASCII; MouseKey=Event.MouseKey; What=Event.What; Alt=Event.Alt; Ctrl=Event.Ctrl; Shift=Event.Shift; CapsLock=Event.CapsLock; NumLock=Event.NumLock; ScrollLock=Event.ScrollLock; MouseX=Event.MouseX; MouseY=Event.MouseY; Next=NULL; } END_FUNCTION(Func7); /****************************************************************************/ /* */ /* CLASS NAME : EventQueueC */ /* */ /* PURPOSE : Implements a circular queue data structure which is used to */ /* store and provide external access to input events. */ /* */ /****************************************************************************/ class EventQueueC { private: /************************/ /* PRIVATE DATA MEMBERS */ /************************/ // Pointer to the last event in the queue. EventC *Last; // The current number and maximum number of events stored. int Num,Max; public: /********************/ /* PUBLIC FUNCTIONS */ /********************/ // Constructor. EventQueueC(); // Destructor. ~EventQueueC(); // Is the queue empty? bool Empty(); // Is the queue full? bool Full(); // Is there one event left in the queue. bool OneOnly(); // Adds an event to the queue. bool Enqueue(EventC &Event); // Removes an event from the queue. bool Dequeue(EventC &Event); // Copies the first event on the queue but doesn't remove it. bool Peek(EventC &Event); }; // Constructor. START_FUNCTION(Func8); EventQueueC::EventQueueC() { Last=NULL; Max=50; Num=0; } END_FUNCTION(Func8); // Destructor. START_FUNCTION(Func9); EventQueueC::~EventQueueC() { EventC Event; while (!Empty()) Dequeue(Event); Max=0; } END_FUNCTION(Func9); // Is the queue empty? START_FUNCTION(Func10); bool EventQueueC::Empty() { return Num==0; } END_FUNCTION(Func10); // Is the queue full? START_FUNCTION(Func11); bool EventQueueC::Full() { return Num==Max; } END_FUNCTION(Func11); // Is there one event left in the queue. START_FUNCTION(Func12); bool EventQueueC::OneOnly() { return Num==1; } END_FUNCTION(Func12); // Adds an event to the queue. START_FUNCTION(Func13); bool EventQueueC::Enqueue(EventC &Event) { bool OK=false; EventC *Temp=NULL; if (!Full()) { Temp=new EventC; *Temp=Event; Num++; OK=true; if (Empty()) { Temp->Next=Temp; Last=Temp; } else { Temp->Next=Last->Next; Last->Next=Temp; } } return OK; } END_FUNCTION(Func13); // Removes an event from the queue. START_FUNCTION(Func14); bool EventQueueC::Dequeue(EventC &Event) { EventC *Temp=NULL; bool OK=false; if (!Empty()) { Temp=Last->Next; Num--; OK=true; Event=*Temp; if (OneOnly()) { Last=NULL; } else { Last->Next=Temp->Next; } delete Temp; } return OK; } END_FUNCTION(Func14); // Copies the first event on the queue but doesn't remove it. START_FUNCTION(Func15); bool EventQueueC::Peek(EventC &Event) { bool OK=false; if (!Empty()) { OK=true; Event=*(Last->Next); } return OK; } END_FUNCTION(Func15); EventQueueC EventQueue; /****************************************************************************/ /* */ /* CLASS NAME : ISRToolsC */ /* */ /* PURPOSE : Used by the ISR's. It contains functions for reading scan codes*/ /* in from the key board port, updating the the key board LED's, */ /* obtaining and changing the flags, obtaining mouse events via */ /* the mouse service interrupt etc. The ISR's do not access the */ /* various data members directly. */ /* */ /****************************************************************************/ class ISRToolsC { private: /************************/ /* PRIVATE DATA MEMBERS */ /************************/ // Ports int KeyDataPort,KeyCommandPort,PICPort; // Interrupt vectors. int KeyIntVect,TimerIntVect,MouseIntVect; // Lock key and extended key flags. bool ExtendedKey,CapsLockOn,NumLockOn,ScrollLockOn,SpecialExtendedKey; // Shift, alt and ctrl key flags. // These are unsigned chars because there are two of each hence 2 means // that both are pressed, 1 means that one is pressed and 0 means that // neither are pressed. unsigned char ShiftOn,CtrlOn,AltOn; // Special key handling flags. bool CtrlBreakHand,CtrlAltDelHand,PrntScnHand; /*********************/ /* PRIVATE FUNCTIONS */ /*********************/ // Waits for the key board to become ready to receive data. bool WaitKeyBoardReady(); // Waits for the key board to acknowledge data sent. bool WaitKeyBoardAcknowledge(); // Sends data to the key board data port. void SendKeyBoardData(unsigned char Data); // Turns of all the LED's. void ClearLEDs(); public: /********************/ /* PUBLIC FUNCTIONS */ /********************/ // Constructor. ISRToolsC(); // Destructor. ~ISRToolsC(); // Updates the key boards LED's. void UpdateLEDs(); // Acknowledges the PIC chip for the hardware interrupt. void AcknowledgeInterrupt(); // Reads the scan code from the key board port. unsigned char GetScanCode(); // Functions for checking and toggling the booloean flags. bool IsExtendedKey(); void ToggleExtendedKey(); bool IsSpecialExtendedKey(); void ToggleSpecialExtendedKey(); bool IsCapsLockOn(); void ToggleCapsLock(); bool IsNumLockOn(); void ToggleNumLock(); bool IsScrollLockOn(); void ToggleScrollLock(); bool IsCtrlBreakHandOn(); void ToggleCtrlBreakHand(); bool IsPrntScnHandOn(); void TogglePrntScnHand(); bool IsCtrlAltDelHandOn(); void ToggleCtrlAltDelHand(); // Functions for checking and altering the non-boolean flags. bool IsCtrlOn(); void CtrlInc(); void CtrlDec(); bool IsAltOn(); void AltInc(); void AltDec(); bool IsShiftOn(); void ShiftInc(); void ShiftDec(); // Returns the ASCII character for the given key. unsigned char GetASCII(unsigned char ScanCode); }; // Forward declartions. void DoLocking(); #ifndef DEBUG void KeyBoardISR(...); #else void KeyBoardISR(unsigned char Scan); #endif void MousePollISR(...); // Constructor. ISRToolsC::ISRToolsC() { // Ports and vectors. KeyDataPort=0x60; KeyCommandPort=0x64; PICPort=0x20; KeyIntVect=0x09; TimerIntVect=0x1C; MouseIntVect=0x33; // Lock all functions and variables touched by the ISR's. DoLocking(); // Flags CtrlBreakHand=CtrlAltDelHand=PrntScnHand=false; AltOn=ShiftOn=CtrlOn=0; ScrollLockOn=NumLockOn=CapsLockOn=ExtendedKey=SpecialExtendedKey=false; ClearLEDs(); #ifndef DEBUG ISRs.Install(KeyIntVect,KeyBoardISR); ISRs.Install(TimerIntVect,MousePollISR); #endif } // Destructor. ISRToolsC::~ISRToolsC() { #ifndef DEBUG ISRs.Restore(KeyIntVect); ISRs.Restore(TimerIntVect); ClearLEDs(); #endif } // Acknowledges the PIC chip for the hardware interrupt. START_FUNCTION(Func16); void ISRToolsC::AcknowledgeInterrupt() { OutPortB(PICPort,PICPort); } END_FUNCTION(Func16); // Reads the scan code from the key board port. START_FUNCTION(Func17); unsigned char ISRToolsC::GetScanCode() { unsigned char ScanCode; InPortB(KeyDataPort,ScanCode); return ScanCode; } END_FUNCTION(Func17); // Functions for checking and toggling the booloean flags. START_FUNCTION(Func18); bool ISRToolsC::IsExtendedKey() { return ExtendedKey; } END_FUNCTION(Func18); START_FUNCTION(Func19); void ISRToolsC::ToggleExtendedKey() { ExtendedKey=!ExtendedKey; } END_FUNCTION(Func19); START_FUNCTION(Func20); bool ISRToolsC::IsSpecialExtendedKey() { return SpecialExtendedKey; } END_FUNCTION(Func20); START_FUNCTION(Func21); void ISRToolsC::ToggleSpecialExtendedKey() { SpecialExtendedKey=!SpecialExtendedKey; } END_FUNCTION(Func21); START_FUNCTION(Func22); bool ISRToolsC::IsCapsLockOn() { return CapsLockOn; } END_FUNCTION(Func22); START_FUNCTION(Func23); void ISRToolsC::ToggleCapsLock() { CapsLockOn=!CapsLockOn; } END_FUNCTION(Func23); START_FUNCTION(Func24); bool ISRToolsC::IsNumLockOn() { return NumLockOn; } END_FUNCTION(Func24); START_FUNCTION(Func25); void ISRToolsC::ToggleNumLock() { NumLockOn=!NumLockOn; } END_FUNCTION(Func25); START_FUNCTION(Func26); bool ISRToolsC::IsScrollLockOn() { return ScrollLockOn; } END_FUNCTION(Func26); START_FUNCTION(Func27); void ISRToolsC::ToggleScrollLock() { ScrollLockOn=!ScrollLockOn; } END_FUNCTION(Func27); START_FUNCTION(Func28); bool ISRToolsC::IsCtrlBreakHandOn() { return CtrlBreakHand; } END_FUNCTION(Func28); START_FUNCTION(Func29); void ISRToolsC::ToggleCtrlBreakHand() { CtrlBreakHand=!CtrlBreakHand; } END_FUNCTION(Func29); START_FUNCTION(Func30); bool ISRToolsC::IsPrntScnHandOn() { return PrntScnHand; } END_FUNCTION(Func30); START_FUNCTION(Func31); void ISRToolsC::TogglePrntScnHand() { PrntScnHand=!PrntScnHand; } END_FUNCTION(Func31); START_FUNCTION(Func32); bool ISRToolsC::IsCtrlAltDelHandOn() { return CtrlAltDelHand; } END_FUNCTION(Func32); START_FUNCTION(Func33); void ISRToolsC::ToggleCtrlAltDelHand() { CtrlAltDelHand=!CtrlAltDelHand; } END_FUNCTION(Func33); // Functions for checking and altering the non-boolean flags. START_FUNCTION(Func34); bool ISRToolsC::IsCtrlOn() { return CtrlOn>0; } END_FUNCTION(Func34); START_FUNCTION(Func35); void ISRToolsC::CtrlInc() { CtrlOn++; } END_FUNCTION(Func35); START_FUNCTION(Func36); void ISRToolsC::CtrlDec() { CtrlOn--; } END_FUNCTION(Func36); START_FUNCTION(Func37); bool ISRToolsC::IsAltOn() { return AltOn>0; } END_FUNCTION(Func37); START_FUNCTION(Func38); void ISRToolsC::AltInc() { AltOn++; } END_FUNCTION(Func38); START_FUNCTION(Func39); void ISRToolsC::AltDec() { AltOn--; } END_FUNCTION(Func39); START_FUNCTION(Func40); bool ISRToolsC::IsShiftOn() { return ShiftOn>0; } END_FUNCTION(Func40); START_FUNCTION(Func41); void ISRToolsC::ShiftInc() { ShiftOn++; } END_FUNCTION(Func41); START_FUNCTION(Func42); void ISRToolsC::ShiftDec() { ShiftOn--; } END_FUNCTION(Func42); // Sends data to the key board data port. START_FUNCTION(Func43); void ISRToolsC::SendKeyBoardData(unsigned char Data) { OutPortB(KeyDataPort,Data); } END_FUNCTION(Func43); // Waits for the key board to become ready to receive data. START_FUNCTION(Func44); bool ISRToolsC::WaitKeyBoardReady() { int I=10000; bool Ready=false; unsigned char Byte; do { I--; InPortB(KeyCommandPort,Byte); Ready=(Byte & 0x02)>0; } while (!Ready && (I>0)); return Ready; } END_FUNCTION(Func44); // Waits for the key board to acknowledge data sent. START_FUNCTION(Func45); bool ISRToolsC::WaitKeyBoardAcknowledge() { int I=10000; bool Acked=false; unsigned char Byte; do { I--; InPortB(KeyCommandPort,Byte); Acked=Byte==0x1C; } while (!Acked && (I>0)); return Acked; } END_FUNCTION(Func45); // Turns of all the LED's. START_FUNCTION(Func46); void ISRToolsC::ClearLEDs() { unsigned char ChangeLEDsCommand=0xED; if (WaitKeyBoardReady()) { SendKeyBoardData(ChangeLEDsCommand); if (WaitKeyBoardAcknowledge()) SendKeyBoardData(0x00); } } END_FUNCTION(Func46); // Updates the key boards LED's. START_FUNCTION(Func47); void ISRToolsC::UpdateLEDs() { unsigned char LEDFlag=0x00,ChangeLEDsCommand=0xED; // Construct the LED flag which is to be sent to the key board. if (CapsLockOn) LEDFlag|=0x04; if (NumLockOn) LEDFlag|=0x02; if (ScrollLockOn) LEDFlag|=0x01; if (WaitKeyBoardReady()) { SendKeyBoardData(ChangeLEDsCommand); if (WaitKeyBoardAcknowledge()) SendKeyBoardData(LEDFlag); } } END_FUNCTION(Func47); // Returns the ASCII character for the given key. START_FUNCTION(Func48); unsigned char ISRToolsC::GetASCII(unsigned char ScanCode) { unsigned char ASCII=0; if (ShiftOn && CapsLockOn && NumLockOn) { switch (ScanCode) { case 1 : ASCII=27;break; case 2 : ASCII='!';break; case 3 : ASCII='@';break; case 4 : ASCII='#';break; case 5 : ASCII='$';break; case 6 : ASCII='%';break; case 7 : ASCII='^';break; case 8 : ASCII='&';break; case 9 : ASCII='*';break; case 10 : ASCII='(';break; case 11 : ASCII=')';break; case 12 : ASCII='_';break; case 13 : ASCII='+';break; case 14 : ASCII=8;break; case 15 : ASCII=9;break; case 16 : ASCII='q';break; case 17 : ASCII='w';break; case 18 : ASCII='e';break; case 19 : ASCII='r';break; case 20 : ASCII='t';break; case 21 : ASCII='y';break; case 22 : ASCII='u';break; case 23 : ASCII='i';break; case 24 : ASCII='o';break; case 25 : ASCII='p';break; case 26 : ASCII='{';break; case 27 : ASCII='}';break; case 28 : ASCII=13;break; case 30 : ASCII='a';break; case 31 : ASCII='s';break; case 32 : ASCII='d';break; case 33 : ASCII='f';break; case 34 : ASCII='g';break; case 35 : ASCII='h';break; case 36 : ASCII='j';break; case 37 : ASCII='k';break; case 38 : ASCII='l';break; case 39 : ASCII=':';break; case 40 : ASCII='"';break; case 41 : ASCII='~';break; case 43 : ASCII='|';break; case 44 : ASCII='z';break; case 45 : ASCII='x';break; case 46 : ASCII='c';break; case 47 : ASCII='v';break; case 48 : ASCII='b';break; case 49 : ASCII='n';break; case 50 : ASCII='m';break; case 51 : ASCII='<';break; case 52 : ASCII='>';break; case 53 : if (ExtendedKey) ASCII='/'; else ASCII='?'; break; case 55 : ASCII='*';break; case 57 : ASCII=' ';break; case 74 : ASCII='-';break; case 78 : ASCII='+';break; } } else if (ShiftOn && NumLockOn) { switch (ScanCode) { case 1 : ASCII=27;break; case 2 : ASCII='!';break; case 3 : ASCII='@';break; case 4 : ASCII='#';break; case 5 : ASCII='$';break; case 6 : ASCII='%';break; case 7 : ASCII='^';break; case 8 : ASCII='&';break; case 9 : ASCII='*';break; case 10 : ASCII='(';break; case 11 : ASCII=')';break; case 12 : ASCII='_';break; case 13 : ASCII='+';break; case 14 : ASCII=8;break; case 15 : ASCII=9;break; case 16 : ASCII='A';break; case 17 : ASCII='W';break; case 18 : ASCII='E';break; case 19 : ASCII='R';break; case 20 : ASCII='T';break; case 21 : ASCII='Y';break; case 22 : ASCII='U';break; case 23 : ASCII='I';break; case 24 : ASCII='O';break; case 25 : ASCII='P';break; case 26 : ASCII='{';break; case 27 : ASCII='}';break; case 28 : ASCII=13;break; case 30 : ASCII='A';break; case 31 : ASCII='S';break; case 32 : ASCII='D';break; case 33 : ASCII='F';break; case 34 : ASCII='G';break; case 35 : ASCII='H';break; case 36 : ASCII='J';break; case 37 : ASCII='K';break; case 38 : ASCII='L';break; case 39 : ASCII=':';break; case 40 : ASCII='"';break; case 41 : ASCII='~';break; case 43 : ASCII='|';break; case 44 : ASCII='Z';break; case 45 : ASCII='X';break; case 46 : ASCII='C';break; case 47 : ASCII='V';break; case 48 : ASCII='B';break; case 49 : ASCII='N';break; case 50 : ASCII='M';break; case 51 : ASCII='<';break; case 52 : ASCII='>';break; case 53 : if (ExtendedKey) ASCII='/'; else ASCII='?'; break; case 55 : ASCII='*';break; case 57 : ASCII=' ';break; case 74 : ASCII='-';break; case 78 : ASCII='+';break; } } else if (ShiftOn && CapsLockOn) { switch (ScanCode) { case 1 : ASCII=27;break; case 2 : ASCII='!';break; case 3 : ASCII='@';break; case 4 : ASCII='#';break; case 5 : ASCII='$';break; case 6 : ASCII='%';break; case 7 : ASCII='^';break; case 8 : ASCII='&';break; case 9 : ASCII='*';break; case 10 : ASCII='(';break; case 11 : ASCII=')';break; case 12 : ASCII='_';break; case 13 : ASCII='+';break; case 14 : ASCII=8;break; case 15 : ASCII=9;break; case 16 : ASCII='q';break; case 17 : ASCII='w';break; case 18 : ASCII='e';break; case 19 : ASCII='r';break; case 20 : ASCII='t';break; case 21 : ASCII='y';break; case 22 : ASCII='u';break; case 23 : ASCII='i';break; case 24 : ASCII='o';break; case 25 : ASCII='p';break; case 26 : ASCII='{';break; case 27 : ASCII='}';break; case 28 : ASCII=13;break; case 30 : ASCII='a';break; case 31 : ASCII='s';break; case 32 : ASCII='d';break; case 33 : ASCII='f';break; case 34 : ASCII='g';break; case 35 : ASCII='h';break; case 36 : ASCII='j';break; case 37 : ASCII='k';break; case 38 : ASCII='l';break; case 39 : ASCII=':';break; case 40 : ASCII='"';break; case 41 : ASCII='~';break; case 43 : ASCII='|';break; case 44 : ASCII='z';break; case 45 : ASCII='x';break; case 46 : ASCII='c';break; case 47 : ASCII='v';break; case 48 : ASCII='b';break; case 49 : ASCII='n';break; case 50 : ASCII='m';break; case 51 : ASCII='<';break; case 52 : ASCII='>';break; case 53 : if (ExtendedKey) ASCII='/'; else ASCII='?'; break; case 55 : ASCII='*';break; case 57 : ASCII=' ';break; case 71 : ASCII='7';break; case 72 : ASCII='8';break; case 73 : ASCII='9';break; case 74 : ASCII='-';break; case 75 : ASCII='4';break; case 76 : ASCII='5';break; case 77 : ASCII='6';break; case 78 : ASCII='+';break; case 79 : ASCII='1';break; case 80 : ASCII='2';break; case 81 : ASCII='3';break; case 82 : ASCII='0';break; case 83 : ASCII='.';break; } } else if (CapsLockOn && NumLockOn) { switch (ScanCode) { case 1 : ASCII=27;break; case 2 : ASCII='1';break; case 3 : ASCII='2';break; case 4 : ASCII='3';break; case 5 : ASCII='4';break; case 6 : ASCII='5';break; case 7 : ASCII='6';break; case 8 : ASCII='7';break; case 9 : ASCII='8';break; case 10 : ASCII='9';break; case 11 : ASCII='0';break; case 12 : ASCII='-';break; case 13 : ASCII='=';break; case 14 : ASCII=8;break; case 15 : ASCII=9;break; case 16 : ASCII='Q';break; case 17 : ASCII='W';break; case 18 : ASCII='E';break; case 19 : ASCII='R';break; case 20 : ASCII='T';break; case 21 : ASCII='Y';break; case 22 : ASCII='U';break; case 23 : ASCII='I';break; case 24 : ASCII='O';break; case 25 : ASCII='P';break; case 26 : ASCII='[';break; case 27 : ASCII=']';break; case 28 : ASCII=13;break; case 30 : ASCII='A';break; case 31 : ASCII='S';break; case 32 : ASCII='D';break; case 33 : ASCII='F';break; case 34 : ASCII='G';break; case 35 : ASCII='H';break; case 36 : ASCII='J';break; case 37 : ASCII='K';break; case 38 : ASCII='L';break; case 39 : ASCII=';';break; case 40 : ASCII='\'';break; case 41 : ASCII='`';break; case 43 : ASCII='\\';break; case 44 : ASCII='Z';break; case 45 : ASCII='X';break; case 46 : ASCII='C';break; case 47 : ASCII='V';break; case 48 : ASCII='B';break; case 49 : ASCII='N';break; case 50 : ASCII='M';break; case 51 : ASCII=',';break; case 52 : ASCII='.';break; case 53 : ASCII='/';break; case 55 : ASCII='*';break; case 57 : ASCII=' ';break; case 71 : ASCII='7';break; case 72 : ASCII='8';break; case 73 : ASCII='9';break; case 74 : ASCII='-';break; case 75 : ASCII='4';break; case 76 : ASCII='5';break; case 77 : ASCII='6';break; case 78 : ASCII='+';break; case 79 : ASCII='1';break; case 80 : ASCII='2';break; case 81 : ASCII='3';break; case 82 : ASCII='0';break; case 83 : ASCII='.';break; } } else if (ShiftOn) { switch (ScanCode) { case 1 : ASCII=27;break; case 2 : ASCII='!';break; case 3 : ASCII='@';break; case 4 : ASCII='#';break; case 5 : ASCII='$';break; case 6 : ASCII='%';break; case 7 : ASCII='^';break; case 8 : ASCII='&';break; case 9 : ASCII='*';break; case 10 : ASCII='(';break; case 11 : ASCII=')';break; case 12 : ASCII='_';break; case 13 : ASCII='+';break; case 14 : ASCII=8;break; case 15 : ASCII=9;break; case 16 : ASCII='Q';break; case 17 : ASCII='W';break; case 18 : ASCII='E';break; case 19 : ASCII='R';break; case 20 : ASCII='T';break; case 21 : ASCII='Y';break; case 22 : ASCII='U';break; case 23 : ASCII='I';break; case 24 : ASCII='O';break; case 25 : ASCII='P';break; case 26 : ASCII='{';break; case 27 : ASCII='}';break; case 28 : ASCII=13;break; case 30 : ASCII='A';break; case 31 : ASCII='S';break; case 32 : ASCII='D';break; case 33 : ASCII='F';break; case 34 : ASCII='G';break; case 35 : ASCII='H';break; case 36 : ASCII='J';break; case 37 : ASCII='K';break; case 38 : ASCII='L';break; case 39 : ASCII=':';break; case 40 : ASCII='"';break; case 41 : ASCII='~';break; case 43 : ASCII='|';break; case 44 : ASCII='Z';break; case 45 : ASCII='X';break; case 46 : ASCII='C';break; case 47 : ASCII='V';break; case 48 : ASCII='B';break; case 49 : ASCII='N';break; case 50 : ASCII='M';break; case 51 : ASCII='<';break; case 52 : ASCII='>';break; case 53 : if (ExtendedKey) ASCII='/'; else ASCII='?'; break; case 55 : ASCII='*';break; case 57 : ASCII=' ';break; case 71 : ASCII='7';break; case 72 : ASCII='8';break; case 73 : ASCII='9';break; case 74 : ASCII='-';break; case 75 : ASCII='4';break; case 76 : ASCII='5';break; case 77 : ASCII='6';break; case 78 : ASCII='+';break; case 79 : ASCII='1';break; case 80 : ASCII='2';break; case 81 : ASCII='3';break; case 82 : ASCII='0';break; case 83 : ASCII='.';break; } } else if (CapsLockOn) { switch (ScanCode) { case 1 : ASCII=27;break; case 2 : ASCII='1';break; case 3 : ASCII='2';break; case 4 : ASCII='3';break; case 5 : ASCII='4';break; case 6 : ASCII='5';break; case 7 : ASCII='6';break; case 8 : ASCII='7';break; case 9 : ASCII='8';break; case 10 : ASCII='9';break; case 11 : ASCII='0';break; case 12 : ASCII='-';break; case 13 : ASCII='=';break; case 14 : ASCII=8;break; case 15 : ASCII=9;break; case 16 : ASCII='Q';break; case 17 : ASCII='W';break; case 18 : ASCII='E';break; case 19 : ASCII='R';break; case 20 : ASCII='T';break; case 21 : ASCII='Y';break; case 22 : ASCII='U';break; case 23 : ASCII='I';break; case 24 : ASCII='O';break; case 25 : ASCII='P';break; case 26 : ASCII='[';break; case 27 : ASCII=']';break; case 28 : ASCII=13;break; case 30 : ASCII='A';break; case 31 : ASCII='S';break; case 32 : ASCII='D';break; case 33 : ASCII='F';break; case 34 : ASCII='G';break; case 35 : ASCII='H';break; case 36 : ASCII='J';break; case 37 : ASCII='K';break; case 38 : ASCII='L';break; case 39 : ASCII=';';break; case 40 : ASCII='\'';break; case 41 : ASCII='`';break; case 43 : ASCII='\\';break; case 44 : ASCII='Z';break; case 45 : ASCII='X';break; case 46 : ASCII='C';break; case 47 : ASCII='V';break; case 48 : ASCII='B';break; case 49 : ASCII='N';break; case 50 : ASCII='M';break; case 51 : ASCII=',';break; case 52 : ASCII='.';break; case 53 : ASCII='/';break; case 55 : ASCII='*';break; case 57 : ASCII=' ';break; case 74 : ASCII='-';break; case 78 : ASCII='+';break; } } else if (NumLockOn) { switch (ScanCode) { case 1 : ASCII=27;break; case 2 : ASCII='1';break; case 3 : ASCII='2';break; case 4 : ASCII='3';break; case 5 : ASCII='4';break; case 6 : ASCII='5';break; case 7 : ASCII='6';break; case 8 : ASCII='7';break; case 9 : ASCII='8';break; case 10 : ASCII='9';break; case 11 : ASCII='0';break; case 12 : ASCII='-';break; case 13 : ASCII='=';break; case 14 : ASCII=8;break; case 15 : ASCII=9;break; case 16 : ASCII='q';break; case 17 : ASCII='w';break; case 18 : ASCII='e';break; case 19 : ASCII='r';break; case 20 : ASCII='t';break; case 21 : ASCII='y';break; case 22 : ASCII='u';break; case 23 : ASCII='i';break; case 24 : ASCII='o';break; case 25 : ASCII='p';break; case 26 : ASCII='[';break; case 27 : ASCII=']';break; case 28 : ASCII=13;break; case 30 : ASCII='a';break; case 31 : ASCII='s';break; case 32 : ASCII='d';break; case 33 : ASCII='f';break; case 34 : ASCII='g';break; case 35 : ASCII='h';break; case 36 : ASCII='j';break; case 37 : ASCII='k';break; case 38 : ASCII='l';break; case 39 : ASCII=';';break; case 40 : ASCII='\'';break; case 41 : ASCII='`';break; case 43 : ASCII='\\';break; case 44 : ASCII='z';break; case 45 : ASCII='x';break; case 46 : ASCII='c';break; case 47 : ASCII='v';break; case 48 : ASCII='b';break; case 49 : ASCII='n';break; case 50 : ASCII='m';break; case 51 : ASCII=',';break; case 52 : ASCII='.';break; case 53 : ASCII='/';break; case 55 : ASCII='*';break; case 57 : ASCII=' ';break; case 71 : ASCII='1';break; case 72 : ASCII='2';break; case 73 : ASCII='3';break; case 74 : ASCII='-';break; case 75 : ASCII='4';break; case 76 : ASCII='5';break; case 77 : ASCII='6';break; case 78 : ASCII='+';break; case 79 : ASCII='1';break; case 80 : ASCII='2';break; case 81 : ASCII='3';break; case 82 : ASCII='0';break; case 83 : ASCII='.';break; } } else { switch (ScanCode) { case 1 : ASCII=27;break; case 2 : ASCII='1';break; case 3 : ASCII='2';break; case 4 : ASCII='3';break; case 5 : ASCII='4';break; case 6 : ASCII='5';break; case 7 : ASCII='6';break; case 8 : ASCII='7';break; case 9 : ASCII='8';break; case 10 : ASCII='9';break; case 11 : ASCII='0';break; case 12 : ASCII='-';break; case 13 : ASCII='=';break; case 14 : ASCII=8;break; case 15 : ASCII=9;break; case 16 : ASCII='q';break; case 17 : ASCII='w';break; case 18 : ASCII='e';break; case 19 : ASCII='r';break; case 20 : ASCII='t';break; case 21 : ASCII='y';break; case 22 : ASCII='u';break; case 23 : ASCII='i';break; case 24 : ASCII='o';break; case 25 : ASCII='p';break; case 26 : ASCII='[';break; case 27 : ASCII=']';break; case 28 : ASCII=13;break; case 30 : ASCII='a';break; case 31 : ASCII='s';break; case 32 : ASCII='d';break; case 33 : ASCII='f';break; case 34 : ASCII='g';break; case 35 : ASCII='h';break; case 36 : ASCII='j';break; case 37 : ASCII='k';break; case 38 : ASCII='l';break; case 39 : ASCII=';';break; case 40 : ASCII='\'';break; case 41 : ASCII='`';break; case 43 : ASCII='\\';break; case 44 : ASCII='z';break; case 45 : ASCII='x';break; case 46 : ASCII='c';break; case 47 : ASCII='v';break; case 48 : ASCII='b';break; case 49 : ASCII='n';break; case 50 : ASCII='m';break; case 51 : ASCII=',';break; case 52 : ASCII='.';break; case 53 : ASCII='/';break; case 55 : ASCII='*';break; case 57 : ASCII=' ';break; case 74 : ASCII='-';break; case 78 : ASCII='+';break; } } return ASCII; } END_FUNCTION(Func48); ISRToolsC ISRTools; /****************************************************************************/ /* */ /* FUNCTION NAMES : KeyBoardISR and MousePollISR. */ /* */ /* PURPOSES : KeyBoardISR is installed at interrupt vector 0x09 and its */ /* purpose is to provide more detailed key information than the */ /* old key board handler does. */ /* */ /* The MousePollISR is installed at interrupt vector 0x1C, which */ /* is chained by the timer interrupt about 18.2 times a second. */ /* Its purpose is to queue the mouse input along with the key */ /* board input. */ /* */ /****************************************************************************/ START_FUNCTION(Func49); #ifndef DEBUG void KeyBoardISR(...) #else void KeyBoardISR(unsigned char Scan) #endif { unsigned char ScanCode; EventC Event; #ifndef DEBUG ScanCode=ISRTools.GetScanCode(); #else ScanCode=Scan; #endif // Update the flags. switch (ScanCode) { case 56 : ISRTools.AltInc();break; case 184 : ISRTools.AltDec();break; case 29 : ISRTools.CtrlInc();break; case 157 : ISRTools.CtrlDec();break; case 54 : ISRTools.ShiftInc();break; case 42 : ISRTools.ShiftInc();break; case 182 : ISRTools.ShiftDec();break; case 170 : ISRTools.ShiftDec();break; case 58 : ISRTools.ToggleCapsLock();break; case 69 : ISRTools.ToggleNumLock();break; case 70 : ISRTools.ToggleScrollLock();break; case 224 : if (!ISRTools.IsExtendedKey()) ISRTools.ToggleExtendedKey(); break; case 225 : if (!ISRTools.IsSpecialExtendedKey()) ISRTools.ToggleSpecialExtendedKey(); break; }; // Update the LED's ISRTools.UpdateLEDs(); // This is a key board event. Event.Type=KeyBoard; Event.MouseX=Event.MouseY=0; Event.MouseKey=Left; // Copy the status of the state shift keys into the event. Event.Alt=ISRTools.IsAltOn(); Event.Ctrl=ISRTools.IsCtrlOn(); Event.Shift=ISRTools.IsShiftOn(); Event.CapsLock=ISRTools.IsCapsLockOn(); Event.NumLock=ISRTools.IsNumLockOn(); Event.ScrollLock=ISRTools.IsScrollLockOn(); // Time stamp the event. TimeS Time; GetTime(Time); Event.Time.Set(Time.Hour,Time.Minute,Time.Second,Time.Second100); // Break key handling. // // Scan codes sent when key is pressed alone // ----------------------------------------- // 225,29,69,225,157,197 // // Scan codes sent when key is pressed and released with ctrl key held // ------------------------------------------------------------------- // 224,70,224,198 if ((ISRTools.IsSpecialExtendedKey() && ((ScanCode==29) || (ScanCode==69) || (ScanCode==157) || (ScanCode==197))) || (ISRTools.IsExtendedKey() && ((ScanCode==70) || (ScanCode==198)))) { // If CtrlBreak was pressed and CtrlBreak handling is on then call the // DOS handler. if ((ScanCode==70) && ISRTools.IsCtrlBreakHandOn()) { } // Otherwise we want to queue the key press or release. // // Since multiple scan codes are sent we need to ignore some of them otherwise // we will end up queueing multiple key presses even though it was pressed // once. // // Hence we will acknowledge the scan code 29 (when the break key is pressed // alone) and the the scan code 70 (when the break key is pressed with the // ctrl key held. In both case we will identify the key with the scan code // 224+70=294. else if ((ScanCode==29) || (ScanCode==157) || (ScanCode==70) || (ScanCode==198)) { Event.ScanCode=224+70; Event.ASCII=0; if ((ScanCode & 0x80) > 0) Event.What=Released; else Event.What=Pressed; EventQueue.Enqueue(Event); } // If the last scan code has been sent then turn off the SpecialExtendedKey // ExtendedKey flags off. if (ScanCode==187) ISRTools.ToggleSpecialExtendedKey(); else if (ScanCode==198) ISRTools.ToggleExtendedKey(); } // Print screen/system request handling. // // Scan codes sent when key is pressed and released // ------------------------------------------------ // 224,42,224,55,224,170,224,183 // // Scan codes sent when key is pressed and released with shift or ctrl keys held // ----------------------------------------------------------------------------- // 224,55,224,183 // // Scan codes sent when key is pressed and released with alt key held // ------------------------------------------------------------------ // 84,212 else if ((ISRTools.IsExtendedKey() && ((ScanCode==42) || (ScanCode==55) || (ScanCode==170) || (ScanCode==183))) || (ISRTools.IsExtendedKey() && ((ScanCode==55) || (ScanCode==183))) || (ScanCode==84) || (ScanCode==212)) { // If PrntScn was pressed and PrntScn handling is on then call the // DOS handler. if ((ScanCode==42) && ISRTools.IsCtrlBreakHandOn()) { } // Otherwise we want to queue the key press or release. // // Since multiple scan codes are sent we need to ignore some of them otherwise // we will end up queueing multiple key presses even though it was pressed // once. // // Hence we will acknowledge the scan code 55 (when the prntscn key is // pressed alone), the the scan code 55 (when the prntscn key is pressed // with a ctrl or shift key held and scan code 84 (when the prntscn key is // pressed with the alt key held). In both case we will identify the key // with the scan code 224+84=308. else if ((ScanCode==55) || (ScanCode==183) || (ScanCode==84) || (ScanCode==212)) { Event.ScanCode=224+84; Event.ASCII=0; if ((ScanCode & 0x80) > 0) Event.What=Released; else Event.What=Pressed; EventQueue.Enqueue(Event); } // If the last scan code has been sent then turn off the ExtendedKey flag // off. if (ISRTools.IsExtendedKey() && (ScanCode==183)) ISRTools.ToggleExtendedKey(); } // CtrlAltDel handling. else if (ISRTools.IsCtrlOn() && ISRTools.IsAltOn() && ((ScanCode==83) || (ScanCode==211))) { // If CtrlAltDel was pressed and CtrlAltDel handling is on then call the // DOS handler. if (ISRTools.IsCtrlAltDelHandOn()) { } // Otherwise just queue the key press or release. else { Event.ScanCode=83; Event.ASCII=0; if ((ScanCode & 0x80) > 0) Event.What=Released; else Event.What=Pressed; EventQueue.Enqueue(Event); } } // Trap extended codes. else if ((ScanCode==224) || (ScanCode==225)) { } // We want to distinguish right ctrl and alt from left ctrl and alt. The // former are extended keys while the latter are not. We will do so by adding // 224 to their scan codes. // Extended keys send the extended code 224 followed by their specific scan // code. else if (ISRTools.IsExtendedKey() && ((ScanCode==56) || (ScanCode==29))) { // Mask off the 7th bit and add 224. Event.ScanCode=224+(ScanCode & 0x7F); // If the 7th bit is set then the key was released. if ((ScanCode & 0x80) > 0) Event.What=Released; else Event.What=Pressed; EventQueue.Enqueue(Event); } else { // Mask out the 7th bit. Event.ScanCode=ScanCode & 0x7F; // Get the ASCII character for this key. Event.ASCII=ISRTools.GetASCII(Event.ScanCode); // If the 7th bit is set then the key was released. if ((ScanCode & 0x80) > 0) Event.What=Released; else Event.What=Pressed; EventQueue.Enqueue(Event); } ISRTools.AcknowledgeInterrupt(); } END_FUNCTION(Func49); START_FUNCTION(Func50); void MousePollISR(...) { } END_FUNCTION(Func50); void DoLocking() { LOCK_FUNCTION(Func1); LOCK_FUNCTION(Func2); LOCK_FUNCTION(Func3); LOCK_FUNCTION(Func4); LOCK_FUNCTION(Func5); LOCK_FUNCTION(Func6); LOCK_FUNCTION(Func7); LOCK_FUNCTION(Func8); LOCK_FUNCTION(Func9); LOCK_FUNCTION(Func10); LOCK_FUNCTION(Func11); LOCK_FUNCTION(Func12); LOCK_FUNCTION(Func13); LOCK_FUNCTION(Func14); LOCK_FUNCTION(Func15); LOCK_FUNCTION(Func16); LOCK_FUNCTION(Func17); LOCK_FUNCTION(Func18); LOCK_FUNCTION(Func19); LOCK_FUNCTION(Func20); LOCK_FUNCTION(Func21); LOCK_FUNCTION(Func22); LOCK_FUNCTION(Func23); LOCK_FUNCTION(Func24); LOCK_FUNCTION(Func25); LOCK_FUNCTION(Func26); LOCK_FUNCTION(Func27); LOCK_FUNCTION(Func28); LOCK_FUNCTION(Func29); LOCK_FUNCTION(Func30); LOCK_FUNCTION(Func31); LOCK_FUNCTION(Func32); LOCK_FUNCTION(Func33); LOCK_FUNCTION(Func34); LOCK_FUNCTION(Func35); LOCK_FUNCTION(Func36); LOCK_FUNCTION(Func37); LOCK_FUNCTION(Func38); LOCK_FUNCTION(Func39); LOCK_FUNCTION(Func40); LOCK_FUNCTION(Func41); LOCK_FUNCTION(Func42); LOCK_FUNCTION(Func43); LOCK_FUNCTION(Func44); LOCK_FUNCTION(Func45); LOCK_FUNCTION(Func46); LOCK_FUNCTION(Func47); LOCK_FUNCTION(Func48); LOCK_FUNCTION(Func49); LOCK_FUNCTION(Func50); LOCK_DATA(ISRTools); LOCK_DATA(EventQueue); } #ifndef DEBUG int main() { char Scan=0; EventC Event; int I=0; do { DisableInts; if (!EventQueue.Empty()) { EventQueue.Dequeue(Event); Scan=Event.ScanCode; cout<<" Scan code : "<>String; if (String!="") { String.ToUnsignedChar(Scan<