Reputation:
I am trying to implement APM to my OS. While I can enable APM in real mode (using int 0x15), how I can switch power states in protected mode? I need to jump to real mode or vm86 mode? I readed the documentation and I got more confused
This interface allows a protected mode APM Driver to invoke the APM BIOS functions without the need to first switch into real or virtual-86 mode.
So, how can I call the 0x15 interrupt (to use the APM functions) if I'm in protected mode? I can't do that!
I know that APM is kinda obsolete, but ACPI is too overcomplicated, I just want things simple for now.
btw, here is my code so far:
extern print_string
global set_power_stateoff
enableAPM:
; Installation check
mov ah, 0x53
mov al, 0x00
xor bx, bx
int 0x15
jc .error
; Conecting to protected mode APM interface
mov ah, 0x53
mov al, [0x3]
xor bx, bx
int 0x15
jc .error
; Enabling power mngm. for all devices
mov al, 0x53
mov ah, 0x08
mov bx, 0001h
mov cx, 0001h
int 0x15
jc .error ; if carry = 1, we have an error
.error:
mov si, apmerrno
call print_string
ret
set_power_stateoff:
; All devices off
mov ah, 0x53
mov al, 0x07
mov bx, 0x0001
mov cx, [0x0003]
int 0x15
section .data:
apmerrno: db "APM interface not supported! :(", 0x0A, 0x0D, 0
EDIT: I discovered that something called "BIOS32", which is used to call BIOS interrupts from protected mode. It can be used for APM procmode call?
Upvotes: 1
Views: 408
Reputation: 37242
As far as I know; the "int 0x15, ax=0x5303" BIOS function returns information that you need to use to set up three consecutive descriptors (e.g. in your GDT) plus the offset in one of those areas for the 32-bit entry point. After you've created the descriptors you'd call the specified entry point in the code segment that the first descriptor you created describes (e.g. with call far dword [ ..]
) and it'd behave the same as "int 0x15" would have in real mode (with same input and output parameters in the same registers, etc).
Note: For the code you've posted, the mov al, [0x3]
is a bug and should be mov al,0x03
(but I'd combine it with the previous instruction - e.g. mov ax,(0x53 << 8) | 0x03
).
Upvotes: 2