- APM and system shutdown support for 16-bit real mode and 32-bit protected mode
(patch from Fabrice Bellard)
This commit is contained in:
parent
a7cad86666
commit
1f33aa72b8
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
233
bochs/bios/apmbios.S
Normal file
233
bochs/bios/apmbios.S
Normal 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
|
@ -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.
|
// Copyright (C) 2002 MandrakeSoft S.A.
|
||||||
@ -137,6 +137,7 @@
|
|||||||
#define DEBUG_INT16 0
|
#define DEBUG_INT16 0
|
||||||
#define DEBUG_INT1A 0
|
#define DEBUG_INT1A 0
|
||||||
#define DEBUG_INT74 0
|
#define DEBUG_INT74 0
|
||||||
|
#define DEBUG_APM 0
|
||||||
|
|
||||||
#define BX_CPU 3
|
#define BX_CPU 3
|
||||||
#define BX_USE_PS2_MOUSE 1
|
#define BX_USE_PS2_MOUSE 1
|
||||||
@ -145,6 +146,7 @@
|
|||||||
#define BX_SUPPORT_FLOPPY 1
|
#define BX_SUPPORT_FLOPPY 1
|
||||||
#define BX_FLOPPY_ON_CNT 37 // 2 seconds
|
#define BX_FLOPPY_ON_CNT 37 // 2 seconds
|
||||||
#define BX_PCIBIOS 1
|
#define BX_PCIBIOS 1
|
||||||
|
#define BX_APM 1
|
||||||
|
|
||||||
#define BX_USE_ATADRV 1
|
#define BX_USE_ATADRV 1
|
||||||
#define BX_ELTORITO_BOOT 1
|
#define BX_ELTORITO_BOOT 1
|
||||||
@ -230,17 +232,6 @@ MACRO HALT
|
|||||||
out dx,ax
|
out dx,ax
|
||||||
MEND
|
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
|
MACRO JMP_AP
|
||||||
db 0xea
|
db 0xea
|
||||||
dw ?2
|
dw ?2
|
||||||
@ -925,10 +916,10 @@ Bit16u cdrom_boot();
|
|||||||
|
|
||||||
#endif // BX_ELTORITO_BOOT
|
#endif // BX_ELTORITO_BOOT
|
||||||
|
|
||||||
static char bios_cvs_version_string[] = "$Revision: 1.110 $";
|
static char bios_cvs_version_string[] = "$Revision: 1.111 $";
|
||||||
static char bios_date_string[] = "$Date: 2004-05-31 13:11:27 $";
|
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 */
|
/* Offset to skip the CVS $Id: prefix */
|
||||||
#define bios_version_string (CVSID + 4)
|
#define bios_version_string (CVSID + 4)
|
||||||
@ -1543,15 +1534,12 @@ bios_printf(action, s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (action & BIOS_PRINTF_HALT) {
|
if (action & BIOS_PRINTF_HALT) {
|
||||||
// freeze in a busy loop. If I do a HLT instruction, then in versions
|
// freeze in a busy loop.
|
||||||
// 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);
|
|
||||||
ASM_START
|
ASM_START
|
||||||
HALT2(__LINE__)
|
cli
|
||||||
|
halt2_loop:
|
||||||
|
hlt
|
||||||
|
jmp halt2_loop
|
||||||
ASM_END
|
ASM_END
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8344,6 +8332,19 @@ int76_handler:
|
|||||||
pop ax
|
pop ax
|
||||||
iret
|
iret
|
||||||
|
|
||||||
|
|
||||||
|
;--------------------
|
||||||
|
#if BX_APM
|
||||||
|
use32 386
|
||||||
|
#define APM_PROT32
|
||||||
|
#include "apmbios.S"
|
||||||
|
use16 386
|
||||||
|
|
||||||
|
#define APM_REAL
|
||||||
|
#include "apmbios.S"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
;--------------------
|
;--------------------
|
||||||
#if BX_PCIBIOS
|
#if BX_PCIBIOS
|
||||||
use32 386
|
use32 386
|
||||||
@ -9560,6 +9561,10 @@ int11_handler:
|
|||||||
.org 0xf859 ; INT 15h System Services Entry Point
|
.org 0xf859 ; INT 15h System Services Entry Point
|
||||||
int15_handler:
|
int15_handler:
|
||||||
pushf
|
pushf
|
||||||
|
#if BX_APM
|
||||||
|
cmp ah, #0x53
|
||||||
|
je apm_call
|
||||||
|
#endif
|
||||||
push ds
|
push ds
|
||||||
push es
|
push es
|
||||||
pushad
|
pushad
|
||||||
@ -9570,6 +9575,10 @@ int15_handler:
|
|||||||
popf
|
popf
|
||||||
//JMPL(iret_modify_cf)
|
//JMPL(iret_modify_cf)
|
||||||
jmp iret_modify_cf
|
jmp iret_modify_cf
|
||||||
|
#if BX_APM
|
||||||
|
apm_call:
|
||||||
|
jmp _apmreal_entry
|
||||||
|
#endif
|
||||||
|
|
||||||
;; Protected mode IDT descriptor
|
;; Protected mode IDT descriptor
|
||||||
;;
|
;;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user