📄 apmbios.s
字号:
// APM BIOS support for the Bochs BIOS// Copyright (C) 2004 Fabrice Bellard//// Debugging extensions, 16-bit interface and extended power options// Copyright (C) 2005 Struan Bartlett//// This library is free software; you can redistribute it and/or// modify it under the terms of the GNU Lesser General Public// License as published by the Free Software Foundation; either// version 2 of the License, or (at your option) any later version.//// This library is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU// Lesser General Public License for more details.//// You should have received a copy of the GNU Lesser General Public// License along with this library; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA#if defined(APM_REAL)#define APMSYM(s) apmreal_ ## s#elif defined(APM_PROT16)#define APMSYM(s) apm16_ ## s#elif defined(APM_PROT32)#define APMSYM(s) apm32_ ## s#else#error unsupported APM mode#endifAPMSYM(out_str): push eax push ebx mov ebx, eaxAPMSYM(out_str1): SEG CS mov al, byte ptr [bx] cmp al, #0 je APMSYM(out_str2) outb dx, al inc ebx jmp APMSYM(out_str1)APMSYM(out_str2): pop ebx pop eax ret APMSYM(07_poweroff_str): .ascii "Shutdown" db 0APMSYM(07_suspend_str): .ascii "Suspend" db 0APMSYM(07_standby_str): .ascii "Standby" db 0 #if DEBUG_APMAPMSYM(put_str): push edx mov dx, #INFO_PORT call APMSYM(out_str) pop edx ret ; print the hex number in eaxAPMSYM(put_num): push eax push ebx push ecx push edx mov ecx, eax mov bx, #8 mov dx, #INFO_PORTAPMSYM(put_num1): mov eax, ecx shr eax, #28 add al, #0x30 cmp al, #0x39 jbe APMSYM(put_num2) add al, #0x27APMSYM(put_num2): outb dx, al shl ecx, #4 dec bx jne APMSYM(put_num1) pop edx pop ecx pop ebx pop eax retAPMSYM(put_reg): outb dx, al shr eax, #8 outb dx, al shr eax, #8 outb dx, al shr eax, #8 outb dx, al mov eax,ebx call APMSYM(put_num) mov al, #0x3b outb dx,al mov al, #0x20 outb dx,al ret APMSYM(put_regs): push eax push edx push ebx mov dx, #INFO_PORT mov ebx, eax mov eax, #0x3d584145 // 'EAX=' call APMSYM(put_reg) pop ebx push ebx mov eax, #0x3d584245 // 'EBX=' call APMSYM(put_reg) mov ebx, ecx mov eax, #0x3d584345 // 'ECX=' call APMSYM(put_reg) mov ebx, edx mov eax, #0x3d584445 // 'EDX=' call APMSYM(put_reg) mov ebx, esi mov eax, #0x3d495345 // 'ESI=' call APMSYM(put_reg) mov ebx, edi mov eax, #0x3d494445 // 'EDI=' call APMSYM(put_reg) mov al, #0x0a outb dx, al pop ebx pop edx pop eax ret#endif#if defined(APM_PROT32)_apm32_entry:#endif#if defined(APM_PROT16)_apm16_entry:#endif pushf #if defined(APM_REAL)_apmreal_entry:#endif#if DEBUG_APM call APMSYM(put_regs)#endif#if defined(APM_REAL);-----------------; APM installation checkAPMSYM(00): cmp al, #0x00 jne APMSYM(01) mov ah, #1 // APM major version mov al, #2 // APM minor version mov bh, #0x50 // 'P' mov bl, #0x4d // 'M' // bit 0 : 16 bit interface supported // bit 1 : 32 bit interface supported mov cx, #0x3 jmp APMSYM(ok) ;-----------------; APM real mode interface connectAPMSYM(01): cmp al, #0x01 jne APMSYM(02) jmp APMSYM(ok);-----------------; APM 16 bit protected mode interface connectAPMSYM(02): cmp al, #0x02 jne APMSYM(03) mov bx, #_apm16_entry mov ax, #0xf000 // 16 bit code segment base mov si, #0xfff0 // 16 bit code segment size mov cx, #0xf000 // data segment address mov di, #0xfff0 // data segment length jmp APMSYM(ok);-----------------; APM 32 bit protected mode interface connectAPMSYM(03): cmp al, #0x03 jne APMSYM(04) mov ax, #0xf000 // 32 bit code segment base mov ebx, #_apm32_entry mov cx, #0xf000 // 16 bit code segment base // 32 bit code segment size (low 16 bits) // 16 bit code segment size (high 16 bits) mov esi, #0xfff0fff0 mov dx, #0xf000 // data segment address mov di, #0xfff0 // data segment length jmp APMSYM(ok)#endif;-----------------; APM interface disconnectAPMSYM(04): cmp al, #0x04 jne APMSYM(05) jmp APMSYM(ok);-----------------; APM cpu idleAPMSYM(05): cmp al, #0x05 jne APMSYM(07) pushf ; XEN sti ; XEN: OS calls us with ints disabled -- better re-enable here! hlt popf ; XEN jmp APMSYM(ok);-----------------; APM Set Power StateAPMSYM(07): cmp al, #0x07 jne APMSYM(08) cmp bx, #1 jne APMSYM(ok) cmp cx, #3 je APMSYM(07_poweroff) cmp cx, #2 je APMSYM(07_suspend) cmp cx, #1 je APMSYM(07_standby) jne APMSYM(ok) APMSYM(07_poweroff): // send power off event to emulator cli mov dx, #0x8900 mov ax, #APMSYM(07_poweroff_str) call APMSYM(out_str)APMSYM(07_1): hlt jmp APMSYM(07_1)APMSYM(07_suspend): push edx mov dx, #0x8900 mov ax, #APMSYM(07_suspend_str) call APMSYM(out_str) pop edx jmp APMSYM(ok)APMSYM(07_standby): push edx mov dx, #0x8900 mov ax, #APMSYM(07_standby_str) call APMSYM(out_str) pop edx jmp APMSYM(ok);-----------------; APM Enable / DisableAPMSYM(08): cmp al, #0x08 jne APMSYM(0a) jmp APMSYM(ok);-----------------; Get Power StatusAPMSYM(0a): cmp al, #0x0a jne APMSYM(0b) mov bh, #0x01 // on line // mov bh, #0x02 // battery mov bl, #0xff // unknown battery status // mov bl, #0x03 // charging mov ch, #0x80 // no system battery // mov ch, #0x8 // charging mov cl, #0xff // unknown remaining time // mov cl, #50 mov dx, #0xffff // unknown remaining time mov si, #0 // zero battery // mov si, #1 // one battery jmp APMSYM(ok);-----------------; Get PM EventAPMSYM(0b): cmp al, #0x0b jne APMSYM(0e) mov ah, #0x80 // no event pending jmp APMSYM(error) ;-----------------; APM Driver VersionAPMSYM(0e): cmp al, #0x0e jne APMSYM(0f) mov ah, #1 mov al, #2 jmp APMSYM(ok);-----------------; APM Engage / DisengageAPMSYM(0f): cmp al, #0x0f jne APMSYM(10) jmp APMSYM(ok);-----------------; APM Get CapabilitiesAPMSYM(10): cmp al, #0x10 jne APMSYM(unimplemented) mov bl, #0 mov cx, #0 jmp APMSYM(ok);-----------------APMSYM(ok): popf clc#if defined(APM_REAL) jmp iret_modify_cf#else retf #endifAPMSYM(unimplemented):APMSYM(error): popf stc#if defined(APM_REAL) jmp iret_modify_cf#else retf#endif#undef APM_PROT32#undef APM_PROT16#undef APM_REAL#undef APMSYM
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -