- implemented INT 15h/89h (patch by Sebastian Herbszt)
[gplbios.git] / apmbios.S
blob41c9e7ef13cbb1b8edaed6f5013b6bd8da0b7127
1 //  APM BIOS support for the Bochs BIOS
2 //  Copyright (C) 2004 Fabrice Bellard
3 //
4 //  Debugging extensions, 16-bit interface and extended power options
5 //  Copyright (C) 2005 Struan Bartlett
6 //
7 //  This library is free software; you can redistribute it and/or
8 //  modify it under the terms of the GNU Lesser General Public
9 //  License as published by the Free Software Foundation; either
10 //  version 2 of the License, or (at your option) any later version.
12 //  This library is distributed in the hope that it will be useful,
13 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 //  Lesser General Public License for more details.
17 //  You should have received a copy of the GNU Lesser General Public
18 //  License along with this library; if not, write to the Free Software
19 //  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
21 #if defined(APM_REAL)
22 #define APMSYM(s) apmreal_ ## s
23 #elif defined(APM_PROT16)
24 #define APMSYM(s) apm16_ ## s
25 #elif defined(APM_PROT32)
26 #define APMSYM(s) apm32_ ## s
27 #else
28 #error unsupported APM mode
29 #endif
31 APMSYM(out_str):
32   push eax
33   push ebx
34   mov ebx, eax
35 APMSYM(out_str1):
36   SEG CS
37   mov al, byte ptr [bx]
38   cmp al, #0
39   je APMSYM(out_str2)
40   outb dx, al
41   inc ebx
42   jmp APMSYM(out_str1)
43 APMSYM(out_str2):
44   pop ebx
45   pop eax
46   ret
48 APMSYM(07_poweroff_str):
49   .ascii "Shutdown"
50   db 0
51 APMSYM(07_suspend_str):
52   .ascii "Suspend"
53   db 0
54 APMSYM(07_standby_str):
55   .ascii "Standby"
56   db 0
58 #if DEBUG_APM
59 APMSYM(put_str):
60   push edx
61   mov dx, #INFO_PORT
62   call APMSYM(out_str)
63   pop edx
64   ret
66 ; print the hex number in eax
67 APMSYM(put_num):
68   push eax
69   push ebx
70   push ecx
71   push edx
72   mov ecx, eax
73   mov bx, #8
74   mov dx, #INFO_PORT
75 APMSYM(put_num1):
76   mov eax, ecx
77   shr eax, #28
78   add al, #0x30
79   cmp al, #0x39
80   jbe APMSYM(put_num2)
81   add al, #0x27
82 APMSYM(put_num2):
83   outb dx, al
84   shl ecx, #4
85   dec bx
86   jne APMSYM(put_num1)
87   pop edx
88   pop ecx
89   pop ebx
90   pop eax
91   ret
93 APMSYM(put_reg):
94   outb dx, al
95   shr eax, #8
96   outb dx, al
97   shr eax, #8
98   outb dx, al
99   shr eax, #8
100   outb dx, al
102   mov eax,ebx
103   call APMSYM(put_num)
105   mov al, #0x3b
106   outb dx,al
107   mov al, #0x20
108   outb dx,al
109   ret
111 APMSYM(put_regs):
112   push eax
113   push edx
114   push ebx
115   mov dx, #INFO_PORT
117   mov ebx, eax
118   mov eax, #0x3d584145 // 'EAX='
119   call APMSYM(put_reg)
120   pop ebx
121   push ebx
122   mov eax, #0x3d584245 // 'EBX='
123   call APMSYM(put_reg)
124   mov ebx, ecx
125   mov eax, #0x3d584345 // 'ECX='
126   call APMSYM(put_reg)
127   mov ebx, edx
128   mov eax, #0x3d584445 // 'EDX='
129   call APMSYM(put_reg)
130   mov ebx, esi
131   mov eax, #0x3d495345 // 'ESI='
132   call APMSYM(put_reg)
133   mov ebx, edi
134   mov eax, #0x3d494445 // 'EDI='
135   call APMSYM(put_reg)
137   mov al, #0x0a
138   outb dx, al
139   pop ebx
140   pop edx
141   pop eax
142   ret
143 #endif
145 #if defined(APM_PROT32)
146 _apm32_entry:
147 #endif
148 #if defined(APM_PROT16)
149 _apm16_entry:
150 #endif
151   pushf
153 #if defined(APM_REAL)
154 _apmreal_entry:
155 #endif
157 #if DEBUG_APM
158   call APMSYM(put_regs)
159 #endif
161 #if defined(APM_REAL)
162 ;-----------------
163 ; APM installation check
164 APMSYM(00):
165   cmp al, #0x00
166   jne APMSYM(01)
168   mov ah, #1 // APM major version
169   mov al, #2 // APM minor version
171   mov bh, #0x50 // 'P'
172   mov bl, #0x4d // 'M'
174   // bit 0 : 16 bit interface supported
175   // bit 1 : 32 bit interface supported
176   mov cx, #0x3
177   jmp APMSYM(ok)
179 ;-----------------
180 ; APM real mode interface connect
181 APMSYM(01):
182   cmp al, #0x01
183   jne APMSYM(02)
184   jmp APMSYM(ok)
186 ;-----------------
187 ; APM 16 bit protected mode interface connect
188 APMSYM(02):
189   cmp al, #0x02
190   jne APMSYM(03)
192   mov bx, #_apm16_entry
194   mov ax, #0xf000 // 16 bit code segment base
195   mov si, #0xfff0 // 16 bit code segment size
196   mov cx, #0xf000 // data segment address
197   mov di, #0xfff0 // data segment length
198   jmp APMSYM(ok)
200 ;-----------------
201 ; APM 32 bit protected mode interface connect
202 APMSYM(03):
203   cmp al, #0x03
204   jne APMSYM(04)
205   mov ax, #0xf000 // 32 bit code segment base
206   mov ebx, #_apm32_entry
207   mov cx, #0xf000 // 16 bit code segment base
208   // 32 bit code segment size (low 16 bits)
209   // 16 bit code segment size (high 16 bits)
210   mov esi, #0xfff0fff0
211   mov dx, #0xf000 // data segment address
212   mov di, #0xfff0 // data segment length
213   jmp APMSYM(ok)
214 #endif
216 ;-----------------
217 ; APM interface disconnect
218 APMSYM(04):
219   cmp al, #0x04
220   jne APMSYM(05)
221   jmp APMSYM(ok)
223 ;-----------------
224 ; APM cpu idle
225 APMSYM(05):
226   cmp al, #0x05
227   jne APMSYM(07)
228   sti
229   hlt
230   jmp APMSYM(ok)
232 ;-----------------
233 ; APM Set Power State
234 APMSYM(07):
235   cmp al, #0x07
236   jne APMSYM(08)
238   cmp bx, #1
239   jne APMSYM(ok)
241   cmp cx, #3
242   je APMSYM(07_poweroff)
244   cmp cx, #2
245   je APMSYM(07_suspend)
247   cmp cx, #1
248   je APMSYM(07_standby)
250   jne APMSYM(ok)
252 APMSYM(07_poweroff):
253   // send power off event to emulator
254   cli
255   mov dx, #0x8900
256   mov ax, #APMSYM(07_poweroff_str)
257   call APMSYM(out_str)
259 APMSYM(07_1):
260   hlt
261   jmp APMSYM(07_1)
263 APMSYM(07_suspend):
264   push edx
265   mov dx, #0x8900
266   mov ax, #APMSYM(07_suspend_str)
267   call APMSYM(out_str)
268   pop edx
269   jmp APMSYM(ok)
271 APMSYM(07_standby):
272   push edx
273   mov dx, #0x8900
274   mov ax, #APMSYM(07_standby_str)
275   call APMSYM(out_str)
276   pop edx
277   jmp APMSYM(ok)
279 ;-----------------
280 ; APM Enable / Disable
281 APMSYM(08):
282   cmp al, #0x08
283   jne APMSYM(0a)
285   jmp APMSYM(ok)
287 ;-----------------
288 ; Get Power Status
289 APMSYM(0a):
290   cmp al, #0x0a
291   jne APMSYM(0b)
292   mov bh, #0x01 // on line
293   // mov bh, #0x02 // battery
294   mov bl, #0xff // unknown battery status
295   // mov bl, #0x03 // charging
296   mov ch, #0x80 // no system battery
297   // mov ch, #0x8 // charging
298   mov cl, #0xff // unknown remaining time
299   // mov cl, #50
300   mov dx, #0xffff // unknown remaining time
301   mov si, #0      // zero battery
302   // mov si, #1      // one battery
303   jmp APMSYM(ok)
305 ;-----------------
306 ; Get PM Event
307 APMSYM(0b):
308   cmp al, #0x0b
309   jne APMSYM(0e)
310   mov ah, #0x80 // no event pending
311   jmp APMSYM(error)
313 ;-----------------
314 ; APM Driver Version
315 APMSYM(0e):
316   cmp al, #0x0e
317   jne APMSYM(0f)
319   mov ah, #1
320   mov al, #2
322   jmp APMSYM(ok)
324 ;-----------------
325 ; APM Engage / Disengage
326 APMSYM(0f):
327   cmp al, #0x0f
328   jne APMSYM(10)
330   jmp APMSYM(ok)
332 ;-----------------
333 ; APM Get Capabilities
334 APMSYM(10):
335   cmp al, #0x10
336   jne APMSYM(unimplemented)
338   mov bl, #0
339   mov cx, #0
341   jmp APMSYM(ok)
343 ;-----------------
344 APMSYM(ok):
345   popf
346   clc
347 #if defined(APM_REAL)
348   jmp iret_modify_cf
349 #else
350   retf
351 #endif
352 APMSYM(unimplemented):
353 APMSYM(error):
354   popf
355   stc
356 #if defined(APM_REAL)
357   jmp iret_modify_cf
358 #else
359   retf
360 #endif
362 #undef APM_PROT32
363 #undef APM_PROT16
364 #undef APM_REAL
365 #undef APMSYM