- PCI i/o and memory base address initialization added
[gplbios.git] / apmbios.S
blobd8ac16084825367292aec2ff151714c6126e7c48
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 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
47   
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
57   
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
65   
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
101   
102   mov eax,ebx
103   call APMSYM(put_num)
104   
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
116   
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)
136   
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
152   
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
170   
171   mov bh, #0x50 // 'P'
172   mov bl, #0x4d // 'M'
173   
174   // bit 0 : 16 bit interface supported
175   // bit 1 : 32 bit interface supported
176   mov cx, #0x3
177   jmp APMSYM(ok)
178   
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
193   
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(07)
221   jmp APMSYM(ok)
223 ;-----------------
224 ; APM Set Power State
225 APMSYM(07):
226   cmp al, #0x07
227   jne APMSYM(0a)
228   
229   cmp bx, #1
230   jne APMSYM(ok)
231   
232   cmp cx, #3
233   je APMSYM(07_poweroff)
234   
235   cmp cx, #2
236   je APMSYM(07_suspend)
237   
238   cmp cx, #1
239   je APMSYM(07_standby)
240   
241   jne APMSYM(ok)
242   
243 APMSYM(07_poweroff):  
244   // send power off event to emulator
245   cli
246   mov dx, #0x8900
247   mov ax, #APMSYM(07_poweroff_str)
248   call APMSYM(out_str)
250 APMSYM(07_1):
251   hlt
252   jmp APMSYM(07_1)
254 APMSYM(07_suspend):
255   push edx
256   mov dx, #0x8900
257   mov ax, #APMSYM(07_suspend_str)
258   call APMSYM(out_str)
259   pop edx
260   jmp APMSYM(ok)
262 APMSYM(07_standby):
263   push edx
264   mov dx, #0x8900
265   mov ax, #APMSYM(07_standby_str)
266   call APMSYM(out_str)
267   pop edx
268   jmp APMSYM(ok)
270 ;-----------------
271 ; Get Power Status
272 APMSYM(0a):
273   cmp al, #0x0a
274   jne APMSYM(0b)
275   mov bh, #0x01 // on line
276   // mov bh, #0x02 // battery
277   mov bl, #0xff // unknown battery status
278   // mov bl, #0x03 // charging
279   mov ch, #0x80 // no system battery
280   // mov ch, #0x8 // charging
281   mov cl, #0xff // unknown remaining time
282   // mov cl, #50
283   mov dx, #0xffff // unknown remaining time 
284   mov si, #0      // zero battery
285   // mov si, #1      // one battery
286   jmp APMSYM(ok)
288 ;-----------------
289 ; Get PM Event
290 APMSYM(0b):
291   cmp al, #0x0b
292   jne APMSYM(0e)
293   mov ah, #0x80 // no event pending
294   jmp APMSYM(error)
295    
296 ;-----------------
297 ; APM Driver Version
298 APMSYM(0e):
299   cmp al, #0x0e
300   jne APMSYM(unimplemented)
301   
302   mov ah, #1
303   mov al, #2
304   
305   jmp APMSYM(ok)
307 ;-----------------
308 APMSYM(ok):
309   popf
310   clc
311 #if defined(APM_REAL)
312   jmp iret_modify_cf
313 #else
314   retf  
315 #endif
316 APMSYM(unimplemented):
317 APMSYM(error):
318   popf
319   stc
320 #if defined(APM_REAL)
321   jmp iret_modify_cf
322 #else
323   retf
324 #endif
326 #undef APM_PROT32
327 #undef APM_PROT16
328 #undef APM_REAL
329 #undef APMSYM