100 lines
2.7 KiB
C
100 lines
2.7 KiB
C
/*
|
|
* keyboard.c
|
|
*
|
|
* This file is part of Emu48
|
|
*
|
|
* Copyright (C) 1995 Sebastien Carlier
|
|
*
|
|
*/
|
|
#include "pch.h"
|
|
#include "Emu48.h"
|
|
|
|
static WORD Keyboard_GetIR(VOID)
|
|
{
|
|
WORD r = 0;
|
|
|
|
if (Chipset.out==0) return 0;
|
|
if (Chipset.out&0x001) r|=Chipset.Keyboard_Row[0];
|
|
if (Chipset.out&0x002) r|=Chipset.Keyboard_Row[1];
|
|
if (Chipset.out&0x004) r|=Chipset.Keyboard_Row[2];
|
|
if (Chipset.out&0x008) r|=Chipset.Keyboard_Row[3];
|
|
if (Chipset.out&0x010) r|=Chipset.Keyboard_Row[4];
|
|
if (Chipset.out&0x020) r|=Chipset.Keyboard_Row[5];
|
|
if (Chipset.out&0x040) r|=Chipset.Keyboard_Row[6];
|
|
if (Chipset.out&0x080) r|=Chipset.Keyboard_Row[7];
|
|
if (Chipset.out&0x100) r|=Chipset.Keyboard_Row[8];
|
|
return r;
|
|
}
|
|
|
|
VOID ScanKeyboard(BOOL bReset)
|
|
{
|
|
// bReset = TRUE -> Reset Chipset.in interrupt state register
|
|
// FALSE -> generate interrupt only for new pressed keys
|
|
|
|
EnterCriticalSection(&csKeyLock); // synchronize
|
|
{
|
|
BOOL bKbdInt;
|
|
|
|
WORD wOldIn = Chipset.in; // save old Chipset.in state
|
|
|
|
UpdateKdnBit(); // update KDN bit
|
|
// 22.11.99 cg, changed, DWORD casting
|
|
Chipset.dwKdnCycles = (DWORD) (Chipset.cycles & 0xFFFFFFFF);
|
|
|
|
// update Chipset.in register
|
|
Chipset.in = Keyboard_GetIR() | Chipset.IR15X;
|
|
|
|
// interrrupt for any new pressed keys ?
|
|
bKbdInt = ((Chipset.in & (Chipset.in ^ wOldIn)) != 0) || bReset;
|
|
|
|
// update keyboard interrupt pending flag
|
|
Chipset.intd = Chipset.intd || (bKbdInt && !Chipset.intk);
|
|
|
|
// keyboard interrupt enabled
|
|
bKbdInt = bKbdInt && (Chipset.intk || Chipset.IR15X != 0) && Chipset.inte;
|
|
|
|
if (Chipset.in != 0) // any key pressed
|
|
{
|
|
if (bKbdInt) // interrupt enabled
|
|
{
|
|
Chipset.SoftInt = TRUE; // interrupt request
|
|
bInterrupt = TRUE; // exit emulation loop
|
|
}
|
|
|
|
if (Chipset.Shutdn) // cpu sleeping
|
|
{
|
|
Chipset.bShutdnWake = TRUE; // wake up from SHUTDN mode
|
|
SetEvent(hEventShutdn); // wake up emulation thread
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Chipset.intd = FALSE; // no keyboard interrupt pending
|
|
}
|
|
}
|
|
LeaveCriticalSection(&csKeyLock);
|
|
|
|
return;
|
|
}
|
|
|
|
VOID KeyboardEvent(BOOL bPress, UINT out, UINT in)
|
|
{
|
|
if (nState != 0) // not in running state
|
|
return; // ignore key
|
|
if (in == 0x8000) // ON key ?
|
|
{
|
|
Chipset.IR15X = bPress?0x8000:0x0000; // refresh special ON key flag
|
|
}
|
|
else
|
|
{
|
|
_ASSERT(out<9);
|
|
if (bPress) // key pressed
|
|
Chipset.Keyboard_Row[out] |= in; // set key marker in keyboard row
|
|
else
|
|
Chipset.Keyboard_Row[out] &= (~in); // clear key marker in keyboard row
|
|
}
|
|
ScanKeyboard(FALSE); // update Chipset.in register
|
|
bKeySlow = FALSE; // break key slow down
|
|
Sleep(50); // hold key state for a definite time
|
|
return;
|
|
}
|