123 lines
2.8 KiB
C
123 lines
2.8 KiB
C
|
/*
|
|||
|
* lowbat.c
|
|||
|
*
|
|||
|
* This file is part of Emu48
|
|||
|
*
|
|||
|
* Copyright (C) 2006 Christoph Gie<EFBFBD>elink
|
|||
|
*
|
|||
|
*/
|
|||
|
#include "pch.h"
|
|||
|
#include "Emu48.h"
|
|||
|
#include "io.h" // I/O definitions
|
|||
|
|
|||
|
// #define BAT_SIMULATION // switch low bat simulation
|
|||
|
|
|||
|
#define BAT_FREQ (60*1000) // bat update time in ms (real machine = 60us, HP28C = 60s)
|
|||
|
|
|||
|
BOOL bLowBatDisable = FALSE;
|
|||
|
|
|||
|
static HANDLE hCThreadBat = NULL;
|
|||
|
static HANDLE hEventBat;
|
|||
|
|
|||
|
static DWORD WINAPI LowBatThread(LPVOID pParam)
|
|||
|
{
|
|||
|
BOOL bLBI,bVLBI;
|
|||
|
|
|||
|
do
|
|||
|
{
|
|||
|
GetBatteryState(&bLBI,&bVLBI); // get battery state
|
|||
|
|
|||
|
// very low bat detection
|
|||
|
bVLBI = bVLBI && (Chipset.IORam[LPE] & EVLBI) != 0;
|
|||
|
|
|||
|
IOBit(LPD,VLBI,bVLBI); // set VLBI
|
|||
|
IOBit(SRQ1,VSRQ,bVLBI); // and service bit
|
|||
|
|
|||
|
if (bVLBI) // VLBI detected
|
|||
|
{
|
|||
|
Chipset.SoftInt = TRUE;
|
|||
|
bInterrupt = TRUE;
|
|||
|
|
|||
|
if (Chipset.Shutdn) // CPU shut down
|
|||
|
{
|
|||
|
Chipset.bShutdnWake = TRUE; // wake up from SHUTDN mode
|
|||
|
SetEvent(hEventShutdn); // wake up emulation thread
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
while (WaitForSingleObject(hEventBat,BAT_FREQ) == WAIT_TIMEOUT);
|
|||
|
|
|||
|
return 0;
|
|||
|
UNREFERENCED_PARAMETER(pParam);
|
|||
|
}
|
|||
|
|
|||
|
VOID StartBatMeasure(VOID)
|
|||
|
{
|
|||
|
DWORD dwThreadId;
|
|||
|
|
|||
|
if (hCThreadBat) // Bat measuring thread running
|
|||
|
return; // -> quit
|
|||
|
|
|||
|
// event to cancel Bat refresh loop
|
|||
|
hEventBat = CreateEvent(NULL,FALSE,FALSE,NULL);
|
|||
|
|
|||
|
VERIFY(hCThreadBat = CreateThread(NULL,0,&LowBatThread,NULL,0,&dwThreadId));
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
VOID StopBatMeasure(VOID)
|
|||
|
{
|
|||
|
if (hCThreadBat == NULL) // thread stopped
|
|||
|
return; // -> quit
|
|||
|
|
|||
|
SetEvent(hEventBat); // leave Bat update thread
|
|||
|
WaitForSingleObject(hCThreadBat,INFINITE);
|
|||
|
CloseHandle(hCThreadBat);
|
|||
|
hCThreadBat = NULL; // set flag Bat update stopped
|
|||
|
CloseHandle(hEventBat); // close Bat event
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
VOID GetBatteryState(BOOL *pbLBI, BOOL *pbVLBI)
|
|||
|
{
|
|||
|
#if defined BAT_SIMULATION
|
|||
|
switch (GetPrivateProfileInt(_T("LowBat"),_T("Level"),2,_T(".\\Lowbat.ini")))
|
|||
|
{
|
|||
|
case 0: // empty
|
|||
|
*pbLBI = TRUE;
|
|||
|
*pbVLBI = TRUE;
|
|||
|
break;
|
|||
|
case 1: // low
|
|||
|
*pbLBI = TRUE;
|
|||
|
*pbVLBI = FALSE;
|
|||
|
break;
|
|||
|
default: // full
|
|||
|
*pbLBI = FALSE;
|
|||
|
*pbVLBI = FALSE;
|
|||
|
break;
|
|||
|
}
|
|||
|
#else
|
|||
|
SYSTEM_POWER_STATUS sSps;
|
|||
|
|
|||
|
*pbLBI = FALSE; // no battery warning
|
|||
|
*pbVLBI = FALSE;
|
|||
|
|
|||
|
VERIFY(GetSystemPowerStatus(&sSps));
|
|||
|
|
|||
|
// low bat emulation enabled and battery powered
|
|||
|
if (!bLowBatDisable && sSps.ACLineStatus == AC_LINE_OFFLINE)
|
|||
|
{
|
|||
|
// on critical battery state make sure that lowbat flag is also set
|
|||
|
if ((sSps.BatteryFlag & BATTERY_FLAG_CRITICAL) != 0)
|
|||
|
sSps.BatteryFlag |= BATTERY_FLAG_LOW;
|
|||
|
|
|||
|
// low bat detection
|
|||
|
*pbLBI = ((sSps.BatteryFlag & BATTERY_FLAG_LOW) != 0);
|
|||
|
|
|||
|
// very low bat detection
|
|||
|
*pbVLBI = ((sSps.BatteryFlag & BATTERY_FLAG_CRITICAL) != 0);
|
|||
|
}
|
|||
|
#endif
|
|||
|
return;
|
|||
|
}
|