-
Notifications
You must be signed in to change notification settings - Fork 0
/
LOWBAT.C
125 lines (102 loc) · 2.96 KB
/
LOWBAT.C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/*
* lowbat.c
*
* This file is part of Emu42
*
* Copyright (C) 2006 Christoph Gießelink
*
*/
#include "pch.h"
#include "Emu42.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
{
// battery measurement active when CPU is running or display on
BOOL bEnabled = !Chipset.Shutdn || (Chipset.IORam[DSPCTL]&DON);
GetBatteryState(&bLBI,&bVLBI); // get battery state
// set IO bits
IOBit(&Chipset.IORam[LPD],LBI,bLBI && bEnabled);
IOBit(&Chipset.IORam[LPD],VLBI,bVLBI && bEnabled);
// VLBI detected and VLBI interrupt enabled
if ( (Chipset.IORam[LPD] & VLBI) != 0
&& (Chipset.IORam[LPE] & EVLBI) != 0)
{
Chipset.SoftInt = TRUE;
bInterrupt = TRUE;
if (Chipset.Shutdn) // CPU not running
{
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;
}