Mail Archives: djgpp/1997/05/11/02:44:14
From: | boylesgj AT lion DOT cs DOT latrobe DOT edu DOT au (Gregary J Boyles)
|
Newsgroups: | comp.os.msdos.djgpp
|
Subject: | Inline assembly instead of ISR wrappers.
|
Date: | 8 May 1997 12:35:35 GMT
|
Organization: | Comp.Sci & Comp.Eng, La Trobe Uni, Australia
|
Lines: | 315
|
Distribution: | world
|
Message-ID: | <5kshan$mlc@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
|
I am trying to develop a series of macros to use in and around and ISR
instead of having to use wrappers.
I might be on to something here because this macro system for setting up
ISR's seems to more or less work. It would be bloody fantastic if you could
piss the wrappers off all together.
It seems to crash some where in ISR_EXIT and I am not sure where. Can any
body pick it?
The other problem is local variables. They would be allocated on the old
stack which means referencing them after changing the stack will cause
catastrophy.
I can see two solutions. Don't use local variables or some how transfer them
to the new stack. Is that possible?
// Macro for setting up a variable which contains the DJGPP data segment.
#define MAKE_DJGPP_DS short unsigned int DJGPPDataSegment=_go32_my_ds()
#define GET_DJGPP_DS DJGPPDataSegment
// Macro for setting up an ISR stack.
#define MAKE_ISR_STACK(ISRName) const long unsigned int StackSize##ISRName=1024*100;\
char Stack##ISRName[StackSize##ISRName]
#define GET_ISR_STACK(ISRName) Stack##ISRName
#define GET_ISR_STACK_SIZE(ISRName) StackSize##ISRName
// Macros for setting ISR entry and exit code.
#define ISR_ENTRY(ISRStack,ISRStackSize,DJGPPDataSegment)\
asm volatile("\npopl %%bp\n"\
"pushal\n"\
"pushw %%ds\n"\
"pushw %%es\n"\
"pushw %%fs\n"\
"pushw %%gs\n"\
"movw %2,%%ax\n"\
"movw %%ax,%%ds\n"\
"movw %%ax,%%es\n"\
"movw %%ax,%%fs\n"\
"movw %%ax,%%gs\n"\
"movw %%ss,%%bx\n"\
"movl %%esp,%%ecx\n"\
"movw %%ax,%%ss\n"\
"movl %0,%%sp\n"\
"addl %1,%%sp\n"\
"pushw %%bx\n"\
"pushl %%ecx\n"\
"pushl %%bp\n"\
"movl %%sp,%%bp\n"\
:\
:"g"(ISRStack),"g"(ISRStackSize),"g"(DJGPPDataSegment)\
)
#define ISR_EXIT\
asm volatile("\npopl %bp\n"\
"popl %ecx\n"\
"popw %bx\n"\
"movw %bx,%ss\n"\
"movl %ecx,%esp\n"\
"popw %gs\n"\
"popw %fs\n"\
"popw %es\n"\
"popw %ds\n"\
"popal\n"\
"sti\n"\
"iret\n"\
)
unsigned char ScanCode=0;
EventC Event;
MAKE_ISR_STACK(KeyBoardISR);
MAKE_DJGPP_DS;
void KeyBoardISR(...)
{
ISR_ENTRY(GET_ISR_STACK(KeyBoardISR),GET_ISR_STACK_SIZE(KeyBoardISR),GET_DJGPP_DS);
ScanCode=ISRTools.GetScanCode();
// 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();
ISR_EXIT;
}
- Raw text -