Hi all!
I hadn't tested my code under real hardware for a while, and now I just finished a VESA driver. I whished to test it in my notebook and inserted some code I did using APM to shutdown (I will use ACPI in the future, I'm only using APM for testing). The code executes as expected under bochs, but do weird things in the notebook. When I send a OFF command to all devices, the computer isn't shutdown. Instead, the message "No Operating System found" appears in the upper left corner of the screen and execution continues from where a called APM. I know, some notebooks have crazy hardware, but I wish to know: "Is my notebook's BIOS buggy, or am I doing something wrong?".
Here's the code that executes the APM shutdown:
Code: Select all
;APM -> interrupt 15h, ah = 53h
%define APM_int_n 53h << 8
%define INSTALL_CHECK 0 | APM_int_n
%define CON_INTERF_REAL 1 | APM_int_n
%define CON_INTERF_16_PMODE 2 | APM_int_n
%define CON_INTERF_32_PMODE 3 | APM_int_n
%define APM_DISCON 4 | APM_int_n
%define SET_STATE 7 | APM_int_n
%define SET_POWER_MANAG 8 | APM_int_n
%define APM_NOT_CON_ERROR 3
%define ALL_DEVICES 1
%define POWER_MANAG_ON 1
%define STATE_STANDBY 1
%define STATE_SUSPEND 2
%define STATE_OFF 3
; I'm using size-initiated strings
%macro string 1
%strlen __strlen %1
db __strlen, %1
%endmacro
[org 7C00h]
[bits 16]
cli
cld
jmp 0:SOC
SOC:
;set 80x25
mov ax,3
int 10h
xor di, di
push 0B800h
pop es
mov si, startup_msg
call print
;Test APM:
mov ax, INSTALL_CHECK ;0 = installation check
xor bx, bx ;Device ID (0 = APM BIOS)
int 15h
jnc APM_supported
mov si, APM_not_supported_msg
exit:
call print
xor ah, ah
int 16h
int 19h
APM_supported:
mov si, APM_supported_msg
call print
;Connect to Real Mode interface:
mov ax, CON_INTERF_REAL
xor bx, bx
int 15h
jnc realmode_interface_ok
mov si, no_realmode_interf_msg
jmp exit
realmode_interface_ok:
mov si, realmode_interf_ok_msg
call print
;Ativa Power Management para todos os dispositivos conectados:
mov ax, SET_POWER_MANAG
mov bx, ALL_DEVICES
mov cx, POWER_MANAG_ON
int 15h
jnc set_pm_ok
mov si, pm_set_failed_msg
jmp exit
set_pm_ok:
mov si, pm_set_msg
call print
;Muda estado:
mov ax, SET_STATE
mov bx, ALL_DEVICES
mov cx, STATE_OFF ;OFF, SUSPEND ou STANDBY
int 15h
jnc state_set_ok
mov si, state_set_failed_msg
jmp exit
state_set_ok:
mov si, state_set_ok_msg
call print
.stop:
hlt
jmp .stop
print: ;print and move to a new line.
lodsb
mov cl, al
.loop:
movsb
inc di
dec cl
jnz .loop
mov ax, di
mov bl, 160
div bl ;ax /= bl, al = resultado, ah = sobra
sub bl, ah
xor bh, bh
add di, bx
ret
startup_msg string ">>> APM Initialization and State Setting <<<"
APM_not_supported_msg string "APM not supported!"
APM_supported_msg string "APM supported!"
no_realmode_interf_msg string "No APM Real Mode interface!"
realmode_interf_ok_msg string "APM Real Mode interface OK!"
pm_set_msg string "Power Management set for all devices!"
pm_set_failed_msg string "Failed to set Power Management!"
state_set_failed_msg string "Setting State failed!"
state_set_ok_msg string "Setting State worked!"
times 510 - ($ - $$) db 0
dw 0AA55h
Edit: when I leave the CD and the HD in boot order in the BIOS configuration, it loads the HD bootloader and jumps there when I send the command, but without doing a full reboot (it doesn't shows me the startup BIOS screen, nor does the BIOS ask me for a password). My notebook is a Itautec Notebook Infoway W7645-C3X8T.