- APM and system shutdown support for 16-bit real mode and 32-bit protected mode

(patch from Fabrice Bellard)
This commit is contained in:
Volker Ruppert 2004-06-20 18:28:40 +00:00
parent a7cad86666
commit 1f33aa72b8
6 changed files with 265 additions and 23 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

233
bochs/bios/apmbios.S Normal file
View File

@ -0,0 +1,233 @@
// APM BIOS support for the Bochs BIOS
// Copyright (C) 2004 Fabrice Bellard
//
// 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
#endif
#if DEBUG_APM
APMSYM(put_str):
push eax
push ebx
push edx
mov ebx, eax
mov dx, #INFO_PORT
APMSYM(put_str1):
SEG CS
mov al, byte ptr [bx]
cmp al, #0
je APMSYM(put_str2)
outb dx, al
inc ebx
jmp APMSYM(put_str1)
APMSYM(put_str2):
pop edx
pop ebx
pop eax
ret
; print the hex number in eax
APMSYM(put_num):
push eax
push ebx
push ecx
push edx
mov ecx, eax
mov bx, #8
mov dx, #INFO_PORT
APMSYM(put_num1):
mov eax, ecx
shr eax, #28
add al, #0x30
cmp al, #0x39
jbe APMSYM(put_num2)
add al, #0x27
APMSYM(put_num2):
outb dx, al
shl ecx, #4
dec bx
jne APMSYM(put_num1)
mov al, #0x0a
outb dx, al
pop edx
pop ecx
pop ebx
pop eax
ret
APMSYM(msg_ax):
.ascii "APM: EAX="
db 0
#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
push eax
mov eax, #APMSYM(msg_ax)
call APMSYM(put_str)
pop eax
call APMSYM(put_num)
#endif
#if defined(APM_REAL)
;-----------------
; APM installation check
APMSYM(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, #0x2
jmp APMSYM(ok)
;-----------------
; APM real mode interface connect
APMSYM(01):
cmp al, #0x01
jne APMSYM(03)
jmp APMSYM(ok)
;-----------------
; APM 32 bit protected mode interface connect
APMSYM(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 disconnect
APMSYM(04):
cmp al, #0x04
jne APMSYM(07)
jmp APMSYM(ok)
;-----------------
; APM Set Power State
APMSYM(07):
cmp al, #0x07
jne APMSYM(0a)
cmp bx, #1
jne APMSYM(ok)
cmp cx, #3
jne APMSYM(ok)
// send power off event to emulator
cli
mov dx, #0x8900
mov al, #0x53 // 'S'
out dx, al
mov al, #0x68 // 'h'
out dx, al
mov al, #0x75 // 'u'
out dx, al
mov al, #0x74 // 't'
out dx, al
mov al, #0x64 // 'd'
out dx, al
mov al, #0x6f // 'o'
out dx, al
mov al, #0x77 // 'w'
out dx, al
mov al, #0x6e // 'n'
out dx, al
APMSYM(07_1):
hlt
jmp APMSYM(07_1)
;-----------------
; Get Power Status
APMSYM(0a):
cmp al, #0x0a
jne APMSYM(0b)
mov bh, #0x01 // on line
mov bl, #0xff // unknown battery status
mov ch, #0x80 // no system battery
mov cl, #0xff // unknown remaining time
mov dx, #0xffff // unknown remaining time
mov si, #0 // zero battery
jmp APMSYM(ok)
;-----------------
; Get PM Event
APMSYM(0b):
cmp al, #0x0b
jne APMSYM(0e)
mov ah, #0x80 // no event pending
jmp APMSYM(error)
;-----------------
; APM Driver Version
APMSYM(0e):
cmp al, #0x0e
jne APMSYM(unimplemented)
mov ah, ch
mov al, cl
jmp APMSYM(ok)
;-----------------
APMSYM(ok):
popf
clc
#if defined(APM_REAL)
jmp iret_modify_cf
#else
retf
#endif
APMSYM(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

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: rombios.c,v 1.110 2004-05-31 13:11:27 vruppert Exp $
// $Id: rombios.c,v 1.111 2004-06-20 18:25:50 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
@ -137,6 +137,7 @@
#define DEBUG_INT16 0
#define DEBUG_INT1A 0
#define DEBUG_INT74 0
#define DEBUG_APM 0
#define BX_CPU 3
#define BX_USE_PS2_MOUSE 1
@ -145,6 +146,7 @@
#define BX_SUPPORT_FLOPPY 1
#define BX_FLOPPY_ON_CNT 37 // 2 seconds
#define BX_PCIBIOS 1
#define BX_APM 1
#define BX_USE_ATADRV 1
#define BX_ELTORITO_BOOT 1
@ -230,17 +232,6 @@ MACRO HALT
out dx,ax
MEND
MACRO HALT2
;; the HALT macro is called with the line number of the HALT call.
;; The line number is then sent to the PANIC_PORT, causing Bochs/Plex
;; to print a BX_PANIC message. This will normally halt the simulation
;; with a message such as "BIOS panic at rombios.c, line 4091".
;; However, users can choose to make panics non-fatal and continue.
mov dx,#PANIC_PORT2
mov ax,#?1
out dx,ax
MEND
MACRO JMP_AP
db 0xea
dw ?2
@ -925,10 +916,10 @@ Bit16u cdrom_boot();
#endif // BX_ELTORITO_BOOT
static char bios_cvs_version_string[] = "$Revision: 1.110 $";
static char bios_date_string[] = "$Date: 2004-05-31 13:11:27 $";
static char bios_cvs_version_string[] = "$Revision: 1.111 $";
static char bios_date_string[] = "$Date: 2004-06-20 18:25:50 $";
static char CVSID[] = "$Id: rombios.c,v 1.110 2004-05-31 13:11:27 vruppert Exp $";
static char CVSID[] = "$Id: rombios.c,v 1.111 2004-06-20 18:25:50 vruppert Exp $";
/* Offset to skip the CVS $Id: prefix */
#define bios_version_string (CVSID + 4)
@ -1543,15 +1534,12 @@ bios_printf(action, s)
}
if (action & BIOS_PRINTF_HALT) {
// freeze in a busy loop. If I do a HLT instruction, then in versions
// 1.3.pre1 and earlier, it will panic without ever updating the VGA
// display, so the panic message will not be visible. By waiting
// forever, you are certain to see the panic message on screen.
// After a few more versions have passed, we can turn this back into
// a halt or something.
// do {} while (1);
// freeze in a busy loop.
ASM_START
HALT2(__LINE__)
cli
halt2_loop:
hlt
jmp halt2_loop
ASM_END
}
}
@ -8344,6 +8332,19 @@ int76_handler:
pop ax
iret
;--------------------
#if BX_APM
use32 386
#define APM_PROT32
#include "apmbios.S"
use16 386
#define APM_REAL
#include "apmbios.S"
#endif
;--------------------
#if BX_PCIBIOS
use32 386
@ -9560,6 +9561,10 @@ int11_handler:
.org 0xf859 ; INT 15h System Services Entry Point
int15_handler:
pushf
#if BX_APM
cmp ah, #0x53
je apm_call
#endif
push ds
push es
pushad
@ -9570,6 +9575,10 @@ int15_handler:
popf
//JMPL(iret_modify_cf)
jmp iret_modify_cf
#if BX_APM
apm_call:
jmp _apmreal_entry
#endif
;; Protected mode IDT descriptor
;;