3 * Advanced Power Management BIOS test program.
4 * (C) 2009-2012 Jonathan Campbell.
5 * Hackipedia DOS library.
7 * This code is licensed under the LGPL.
8 * <insert LGPL legal text here>
10 * Compiles for intended target environments:
11 * - MS-DOS [pure DOS mode, or Windows or OS/2 DOS Box]
13 * This program allows you to play with your APM BIOS interface. It should
14 * not cause harm, but this code is provided under no warranty express or
18 #include <conio.h> /* this is where Open Watcom hides the outp() etc. functions */
28 #include <hw/dos/dos.h>
29 #include <hw/apm/apm.h>
30 #include <hw/8254/8254.h> /* 8254 timer */
31 #include <hw/8259/8259.h> /* 8259 PIC */
32 #include <hw/dos/doswin.h>
35 fprintf(stderr,"test [options] [action]\n");
36 fprintf(stderr,"Test program for APM BIOS functions\n");
37 #if TARGET_MSDOS == 32
38 fprintf(stderr,"32-bit protected mode build\n");
40 fprintf(stderr,"16-bit real mode ");
41 # if defined(__LARGE__)
42 fprintf(stderr,"large");
43 # elif defined(__MEDIUM__)
44 fprintf(stderr,"medium");
45 # elif defined(__COMPACT__)
46 fprintf(stderr,"compact");
48 fprintf(stderr,"small");
50 fprintf(stderr," build\n");
52 fprintf(stderr," /h help\n");
53 fprintf(stderr," /v1.<n> Use APM v1.N interface (v1.0, v1.1, or v1.2)\n");
54 fprintf(stderr," /vn Don't connect to APM\n");
55 fprintf(stderr," /nd Don't disconnect after call\n");
56 fprintf(stderr," /if:<n> Use interface (real");
57 #if TARGET_MSDOS == 32
58 fprintf(stderr,", 16pm, 32pm)\n");
60 fprintf(stderr,")\n");
62 fprintf(stderr,"Commands\n");
63 fprintf(stderr," cpu-idle\n");
64 fprintf(stderr," cpu-busy\n");
65 fprintf(stderr," events\n");
66 fprintf(stderr," status\n");
67 fprintf(stderr," standby\n");
68 fprintf(stderr," suspend\n");
69 fprintf(stderr," off\n");
72 #define REQ_VER_NONE 1
73 int main(int argc,char **argv) {
74 unsigned int req_ver = 0;
75 unsigned int dont_disconnect = 0;
76 unsigned int req_mode = APM_CONNECT_NONE;
77 const char *action = NULL;
81 const char *a = argv[i++];
83 if (*a == '/' || *a == '-') {
84 do { a++; } while (*a == '/' || *a == '-');
86 if (!strncmp(a,"v1.",3)) {
88 req_ver = 0x100 + (atoi(a) & 0xFF);
90 else if (!strcmp(a,"vn")) {
91 req_ver = REQ_VER_NONE;
93 else if (!strcmp(a,"nd")) {
96 else if (!strcmp(a,"h") || !strcmp(a,"help")) {
99 else if (!strncmp(a,"if:",3)) {
101 if (!strcmp(a,"real"))
102 req_mode = APM_CONNECT_REALMODE;
103 else if (!strcmp(a,"16pm"))
104 req_mode = APM_CONNECT_16_PM;
105 else if (!strcmp(a,"32pm"))
106 req_mode = APM_CONNECT_32_PM;
108 fprintf(stderr,"Unknown interface %s\n",a);
113 fprintf(stderr,"Unknown param '%s'\n",a);
118 else if (action == NULL) {
122 fprintf(stderr,"Unknown param\n");
128 printf("Cannot init 8254 timer\n");
132 printf("Cannot init 8259 PIC\n");
137 if (!apm_bios_probe()) {
138 printf("APM BIOS not found\n");
142 if (req_mode == APM_CONNECT_NONE)
143 req_mode = APM_CONNECT_REALMODE;
145 printf("APM BIOS v%u.%u: ",apm_bios->major,apm_bios->minor);
146 if (apm_bios->flags & APM_FL_16BIT_PM) printf("[16-bit pm] ");
147 if (apm_bios->flags & APM_FL_32BIT_PM) printf("[32-bit pm] ");
148 if (apm_bios->flags & APM_FL_CPU_IDLE_SLOWS) printf("[cpu-idle-slow] ");
149 if (apm_bios->flags & APM_FL_PM_DISABLED) printf("[disabled] ");
150 if (apm_bios->flags & APM_FL_PM_DISENGAGED) printf("[disengaged] ");
153 if (req_ver >= 0x100) apm_bios->version_want = req_ver;
155 if (req_ver != REQ_VER_NONE) {
156 if (!apm_bios_connect(req_mode)) {
157 fprintf(stderr,"Failed to connect to APM BIOS (last=0x%02X)\n",apm_bios->last_error);
161 printf("Connected to APM BIOS v%u.%u interface\n",apm_bios->major_neg,apm_bios->minor_neg);
162 printf(" batteries: %u\n",apm_bios->batteries);
163 printf(" capabilities:\n");
164 if (apm_bios->capabilities & 1) printf(" Can enter global standby state\n");
165 if (apm_bios->capabilities & 2) printf(" Can enter global suspend state\n");
166 if (apm_bios->capabilities & 4) printf(" Resume timer will wake from standby\n");
167 if (apm_bios->capabilities & 8) printf(" Resume timer will wake from suspend\n");
168 if (apm_bios->capabilities & 16) printf(" Resume on ring will wake from standby\n");
169 if (apm_bios->capabilities & 32) printf(" Resume on ring will wake from suspend\n");
170 if (apm_bios->capabilities & 64) printf(" PCMCIA ring indicator will wake up from standby\n");
171 if (apm_bios->capabilities & 128) printf(" PCMCIA ring indicator will wake up from suspend\n");
175 if (action == NULL) {
177 else if (!strcmp(action,"cpu-idle")) {
178 printf("Issuing CPU idle command\n");
179 if (!apm_bios_cpu_idle())
180 fprintf(stderr,"CPU Idle failed\n");
182 else if (!strcmp(action,"cpu-busy")) {
183 printf("Issuing CPU busy command\n");
184 if (!apm_bios_cpu_busy())
185 fprintf(stderr,"CPU Busy failed\n");
187 else if (!strcmp(action,"events")) {
189 signed long ev = apm_bios_pm_evnet();
191 printf("Event 0x%04X\n",(unsigned int)ev);
195 if (getch() == 27) break;
199 else if (!strcmp(action,"status")) {
200 apm_bios_update_status();
202 printf("AC=0x%X Batt=0x%X BattFlag=0x%X BattPercent=%u BattLife=%u%s\n",
204 apm_bios->status_battery,
205 apm_bios->status_battery_flag,
206 apm_bios->status_battery_life,
207 apm_bios->status_battery_time&0x7FFF,
208 (apm_bios->status_battery_time&0x8000)?"m":"s");
210 else if (!strcmp(action,"standby")) {
211 if (!apm_bios_power_state(APM_POWER_STANDBY))
212 fprintf(stderr,"Unable to set power state\n");
214 else if (!strcmp(action,"suspend")) {
215 if (!apm_bios_power_state(APM_POWER_SUSPEND))
216 fprintf(stderr,"Unable to set power state\n");
218 else if (!strcmp(action,"off")) {
219 if (!apm_bios_power_state(APM_POWER_OFF))
220 fprintf(stderr,"Unable to set power state\n");
223 if (req_ver != REQ_VER_NONE && !dont_disconnect) {
224 if (!apm_bios_connect(APM_CONNECT_NONE)) {
225 fprintf(stderr,"Failed to disconnect\n");
228 printf("Disconnected APM BIOS\n");