delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/04/26/09:59:34

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

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 <dos.h>
#include <iostream.h>
#include <stdlib.h>
#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 : "<<Event.ScanCode<<endl;
      cout<<" ASCII : "<<Event.ASCII<<endl;
      cout<<" What : "<<Event.What<<endl;
      cout<<" Alt : "<<Event.Alt<<endl;
      cout<<" Ctrl : "<<Event.Ctrl<<endl;
      cout<<" Shift : "<<Event.Shift<<endl;
      cout<<" Caps lock : "<<Event.CapsLock<<endl;
      cout<<" Num lock : "<<Event.NumLock<<endl;
      cout<<" Scroll lock : "<<Event.ScrollLock<<endl;
    }
    EnableInts;
  }
  while (Scan!=1);

  return 0;
}
#else
int main()
{
  unsigned char Scan=0;
  StringC String;

  do
  {
    cout<<"Scan code : ";
    cin>>String;
    if (String!="")
    {
      String.ToUnsignedChar(Scan<<endl;
      KeyBoardISR(Scan<<endl;
      cout<<" Scan code : "<<Event.ScanCode<<endl;
      cout<<" ASCII : "<<Event.ASCII<<endl;
      cout<<" What : "<<Event.What<<endl;
      cout<<" Alt : "<<Event.Alt<<endl;
      cout<<" Ctrl : "<<Event.Ctrl<<endl;
      cout<<" Shift : "<<Event.Shift<<endl;
      cout<<" Caps lock : "<<Event.CapsLock<<endl;
      cout<<" Num lock : "<<Event.NumLock<<endl;
      cout<<" Scroll lock : "<<Event.ScrollLock<<endl;
    }
  }
  while (Scan!=1);
  return 0;
}
#endif

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019