[syslinux] com16/com32 module for APM powerdown
Luciano Miguel Ferreira Rocha
strange at nsk.no-ip.org
Sat Sep 17 16:41:18 PDT 2005
Hello,
In case anyone is interested, here are the source code for comboot and
com32 modules for powering down a computer using APM.
I started work on the ACPI version of it, but it will take some time to
parse the spec.
Regards,
Luciano Rocha
--
lfr
0/0
-------------- next part --------------
; ****************************************************************************
;
; apmoff.asm
;
; A program to power down a machine, using APM.
;
; Copyright (C) 1999,2005 Luciano Rocha
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
; Boston MA 02111-1307, USA; either version 2 of the License, or
; (at your option) any later version; incorporated herein by reference.
;
; ****************************************************************************
%macro print 1
mov dx, %1
mov ah, 0x9
int 0x21
%endmacro
%macro apm 3
mov ah, 0x53
mov al, %1
mov bx, %2
mov cx, %3
int 0x15
%endmacro
section .text
cpu 8086
org 0100h
_start:
; echo (C)
print msg_cpy
; check APM support
apm 0, 0, 0
jnc apm_checkver
; APM not found
noapm:
print msg_noapm
jmp exit
; check bx for PM
apm_checkver:
cmp bx, 0x504d
jne noapm
; save flags and version
mov [apm_flags], cx
mov [apm_version], ax
; show apm version
add ax, 0x3030
mov [apm_ver_maj], ah
mov [apm_ver_min], al
print msg_apmver
; connect to APM
apm 1, 0, 0
jnc apmc
; try to break any other connection
apm 4, 0, 0
; try again
apm 1, 0, 0
jnc apmc
; connection error
print msg_apm_error_connect
jmp exit
; apm connected
apmc:
print msg_apm_connected
mov cx, [apm_version]
cmp cx, 0x0101
jl apm_enable
; report driver version
apm 0xe, 0, cx
jnc apm_enable
print msg_apm_vreport_err
; must enable apm bios?
apm_enable:
mov cx, [apm_flags]
and cx, 0x4
jz apm_off
; enable apm bios
apm 8, 1, 1
jc apm_off
print msg_apm_enabled
; send shutdown command
apm_off:
apm 7, 1, 3
jnc apmerr
print msg_apm_off_err
; apm failed, disconnect
apmerr:
print msg_apm_disconnecting
apm 4, 0, 0
exit:
mov ax, 0x4c01
int 0x21
apm_flags dw 0
apm_version dw 0
%define endl 0x2e, 0x0a, 0x0d, 0x24
msg_cpy db "APM/ACPI Off", 0x0a, 0x0d
db "Copyright (C) 1999,2005 Luciano Rocha", endl
msg_noapm db "APM not detected", endl
msg_apmver db "APM BIOS Version "
apm_ver_maj db 0, "."
apm_ver_min db 0
db " found", endl
msg_apm_error_connect db "Error connecting to APM BIOS", endl
msg_apm_connected db "Connected to APM BIOS", endl
msg_apm_enabled db "APM enabled", endl
msg_apm_off_err db "APM shutdown command failed", endl
msg_apm_disconnecting db "APM disconnected", endl
msg_apm_vreport_err db "Error reporting driver version", endl
-------------- next part --------------
/* ----------------------------------------------------------------------- *
*
* Copyright 1999,2005 Luciano Rocha
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, Inc., 53 Temple Place Ste 330,
* Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
/*
* apmoff.c
*
* Power down a computer, using APM.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <console.h>
#include <com32.h>
int main(void)
{
com32sys_t in, out;
int flags;
int version;
openconsole(&dev_null_r, &dev_stdcon_w);
printf("APM/ACPI Off\nCopyright (C) 1999,2005 Luciano Rocha.\n");
/* clear input registers */
memset(&in, '\0', sizeof in);
/* check APM support and version */
in.eax.w[0] = 0x5300;
__intcall(0x15, &in, &out);
/* version in ax, bx must be equal to "PM" */
if (out.eflags.l & EFLAGS_CF || out.ebx.w[0] != 0x504d) {
printf("APM not detected.\n");
return 1;
}
printf("APM BIOS Version %x.%x found.\n", out.eax.b[1], out.eax.b[0]);
flags = out.ecx.w[0];
version = out.eax.w[0];
/* establish connection to APM */
in.eax.b[0] = 1;
__intcall(0x15, &in, &out);
/* connection failed, break any existing connection and try again */
if (out.eflags.l & EFLAGS_CF) {
in.eax.b[0] = 4;
__intcall(0x15, &in, &out);
in.eax.b[0] = 1;
__intcall(0x15, &in, &out);
}
if (out.eflags.l & EFLAGS_CF) {
printf("Error connecting to APM BIOS.\n");
return 1;
}
printf("Connected to APM BIOS.\n");
/* register with APM BIOS, if version >= 1.1 */
if (version > 0x100) {
in.ecx.w[0] = version;
in.eax.b[0] = 0xe;
__intcall(0x15, &in, &out);
if (out.eflags.l & EFLAGS_CF) {
printf("Error reporting driver version.\n");
}
}
/* if APM disabled, enable it */
if (flags & 0x4) {
in.ecx.w[0] = 1;
in.ebx.w[0] = 1;
in.eax.b[0] = 8;
__intcall(0x15, &in, &out);
if (!(out.eflags.l & EFLAGS_CF)) {
printf("APM enabled.\n");
}
}
/* send shutdown command */
in.ecx.w[0] = 3;
in.ebx.w[0] = 1;
in.eax.b[0] = 7;
__intcall(0x15, &in, &out);
if (out.eflags.l & EFLAGS_CF) {
printf("APM shutdown command failed.\n");
}
/* if we reach this point, shutdown failed. disconnect from BIOS */
printf("APM disconnected\n");
in.ecx.w[0] = 0;
in.ebx.w[0] = 0;
in.eax.b[0] = 4;
__intcall(0x15, &in, &out);
return 1;
}
More information about the Syslinux
mailing list