Page 1 of 5

Advanced Power Management

Posted: Sun Apr 30, 2006 3:45 pm
by Ghost
SYSTEM CALL

eax = 70
dx = номер функции APM BIOS (аналогичен ax в реальном режиме)
остальные (bx, cx) регистры по спецификации (см. http://iam.gorodok.net/apm.zip )
результат : по спецификации (включая CF), старшая часть 32 битных регистров не определена


MEMORY MAP

Boot:
0x9040 - dword - entry point of APM BIOS
0x9044 - word - version (BCD)
0x9046 - word - flags


ИЗМЕНЕНИЯ

sys32.inc
syscall.inc
kernel.asm
bootcode.inc

##############[core\sys32.inc]#####################

Три новых дескриптора

.............
.............

; GDT TABLE

gdts:

dw gdte-$-1
dd gdts
dw 0

int_code_l:
os_code_l:

dw 0xffff
dw 0x0000
db 0x00
dw 11011111b *256 +10011010b
db 0x00

int_data_l:
os_data_l:

dw 0xffff
dw 0x0000
db 0x00
dw 11011111b *256 +10010010b
db 0x00
; --------------- APM ---------------------
apm_code_32:
dw 0x10 ; limit 64kb
db 0, 0, 0
dw 11011111b *256 +10011010b
db 0x00
apm_code_16:
dw 0x10
db 0, 0, 0
dw 10011111b *256 +10011010b
db 0x00
apm_data_16:
dw 0x10
db 0, 0, 0
dw 10011111b *256 +10010010b
db 0x00
; -----------------------------------------
app_code_l:
dw ((0x80000000-std_application_base_address) shr 12) and 0xffff
dw 0
db 0
dw 11010000b*256+11111010b+256*((0x80000000-std_application_base_address) shr 28)
db std_application_base_address shr 24

app_data_l:
dw (0x80000000-std_application_base_address) shr 12 and 0xffff
dw 0
db 0
dw 11010000b*256+11110010b+256*((0x80000000-std_application_base_address) shr 28)
db std_application_base_address shr 24

graph_data_l:

dw 0x3ff
dw 0x0000
db 0x00
dw 11010000b *256 +11110010b
db 0x00

tss0_l:
times (max_processes+10) dd 0,0

.............
.............

##############[core\syscall.inc]###################

.............
.............


dd undefined_syscall ; 65-UTF
dd sys_process_def ; 66-Process definitions - keyboard
dd sys_window_move ; 67-Window move or resize
dd sys_internal_services ; 68-Some internal services
dd sys_debug_services ; 69-Debug
dd sys_apm ; 70-APM


.............
.............

##############[kernel.asm]#########################


Часть 1 (после метки "; SAVE REAL MODE VARIABLES"):

.............
.............

; SAVE REAL MODE VARIABLES

; --------------- APM ---------------------
mov eax, [0x2f0000 + 0x9040] ; entry point
mov dword[apm_entry], eax
mov word [apm_entry + 4], apm_code_32 - gdts

mov eax, [0x2f0000 + 0x9044] ; version & flags
mov [apm_vf], eax
; -----------------------------------------

.............
.............

Часть 2 (системный вызов, расположение не критично,
я расположил перед меткой "undefined_syscall:")

.............
.............

; --------------- APM ---------------------
apm_entry dp 0
apm_vf dd 0
align 4
sys_apm:
cmp word [apm_vf], 0 ; Check APM BIOS enable
jne @f
or [esp + 40], byte 1 ; error
mov [esp + 36], dword 8 ; 32-bit protected-mode interface not supported
ret

@@: xchg eax, ecx
xchg ebx, ecx

cmp al, 3
ja @f
and [esp + 40], byte 0xfe ; emulate func 0..3 as func 0
mov eax, [apm_vf]
mov [esp + 36], eax
shr eax, 16
mov [esp + 32], eax
ret

@@: call pword [apm_entry] ; call APM BIOS
mov [esp + 8 ], edi
mov [esp + 12], esi
mov [esp + 24], ebx
mov [esp + 28], edx
mov [esp + 32], ecx
mov [esp + 36], eax
setc al
and [esp + 40], byte 0xfe
or [esp + 40], al
ret
; -----------------------------------------

align 4

undefined_syscall: ; Undefined system call

.............
.............

##############[boot\bootcode.inc]##################

Перед меткой "; DISPLAY VESA INFORMATION"

.............
.............

; --------------- APM ---------------------
push 0
pop es
mov word [es : 0x9044], 0 ; ver = 0.0 (APM not found)
mov ax, 0x5300
xor bx, bx
int 0x15
jc apm_end ; APM not found
test cx, 2
jz apm_end ; APM 32-bit protected-mode interface not supported
mov [es : 0x9044], ax ; Save APM Version
mov [es : 0x9046], cx ; Save APM flags

; Write APM ver ----
jmp @f
msg_apm:db ' APM x.x ', 0
@@: and ax, 0xf0f
add ax, '00'
mov [msg_apm - 0x10000 + 5], ah
mov [msg_apm - 0x10000 + 7], al
_setcursor 0, 3
mov si, msg_apm - 0x10000
call printplain
_setcursor d80x25_top_num,0
; ------------------

mov ax, 0x5304 ; Disconnect interface
xor bx, bx
int 0x15
mov ax, 0x5303 ; Connect 32 bit mode interface
xor bx, bx
int 0x15
; init selectors
movzx eax, ax ; real-mode segment base address of protected-mode 32-bit code segment
shl eax, 4
mov [apm_code_32 - 0x10000 + 2], ax
shr eax, 16
mov [apm_code_32 - 0x10000 + 4], al
movzx ecx, cx ; real-mode segment base address of protected-mode 16-bit code segment
shl ecx, 4
mov [apm_code_16 - 0x10000 + 2], cx
shr ecx, 16
mov [apm_code_16 - 0x10000 + 4], cl
movzx edx, dx ; real-mode segment base address of protected-mode 16-bit data segment
shl edx, 4
mov [apm_data_16 - 0x10000 + 2], dx
shr edx, 16
mov [apm_data_16 - 0x10000 + 4], dl
mov [es : 0x9040], ebx ; offset of APM entry point
apm_end:
; -----------------------------------------


; DISPLAY VESA INFORMATION

.............
.............

Posted: Sun Apr 30, 2006 4:02 pm
by Ghost
Вот пример который выключает монитор на 5 сек

include 'MACROS.INC'

MEOS_APP_START
CODE
mov dx, 0x5308
mov bx, 1
mov cx, bx
mov eax, 70
int 0x40

mov dx, 0x530E
xor bx, bx
mov cx, 0x0102
mov eax, 70
int 0x40

mov dx, 0x530D
mov bx, 1
mov cx, bx
mov eax, 70
int 0x40

mov dx, 0x530F
mov bx, 1
mov cx, bx
mov eax, 70
int 0x40

mov dx, 0x5307
mov cx, 0x3
mov bx, 0x1ff
mov eax, 70
int 0x40

mov eax, 5
mov ebx, 500
int 0x40

mov dx, 0x5307
mov cx, 0x0
mov bx, 0x1ff
mov eax, 70
int 0x40

mov eax, -1 ; close this program
int 0x40
;---------------------------------------------------------------------
DATA
UDATA
MEOS_APP_END

Владельцы ноутбуков могут написать программу показываюшую заряд аккумуляторов, и bспользуюшую CPU IDLE

Posted: Sun Apr 30, 2006 9:23 pm
by Mario79
Ghost
Хорошая работа! Замечательно.
Но функция 70 уже забита для новых функций работы с файловой системой (на SVN уже имеется код), так что придется размещать как 71 или подфункцию 18 функции.

Posted: Sun Apr 30, 2006 10:17 pm
by Mario79
Ghost
Я проверил код. Все работает как часы. Молодец!

Posted: Mon May 01, 2006 10:21 pm
by Mario79
На старом компе Cyrix233MX пример выключающий экран повесил систему намертво, экран не погас. Видимо версия APM старая.

Posted: Wed May 03, 2006 5:10 pm
by diamond
Ну зачем сразу 71? Есть же несколько зарезервированных функций: 36,49,54,65.
А идея хорошая, поддерживаю.

Posted: Wed May 03, 2006 10:06 pm
by Heavyiron
Тогда определяйтесь в какую все таки функцию включить данный код, да надо выложить на SVN, я считаю. Код проверил (переделал для 71-й функции) : действительно работает как часы :).

Posted: Thu May 04, 2006 7:22 pm
by Mario79
diamond
Хорошо будем вешать на 49 функцию, на нее вроде вообще никто не покушался.

Posted: Sat May 06, 2006 5:36 pm
by Mario79
Ghost
Добавил функцию в ядро на SVN. Порядковый номер 49.

Posted: Tue May 09, 2006 5:17 pm
by Ghost
Ok, на счёт старой тачки я не знаю, на VMWare интересный глюк : 32х битный интерфейс коннектица, а после вызова говорит что не присоединён, и ничего не делает. Отлично работает на MS VirtualPC

Posted: Fri May 12, 2006 3:50 pm
by diamond
При вызове системных функций образ eflags располагается не по [esp+40] (там, кстати говоря, es), а по [esp+56]. На svn-сервере исправление уже залито.
Кстати, а не надо никаких изменений в shutdown.inc, который выключает комп через 16-битный интерфейс APM реального режима?

Posted: Fri May 12, 2006 7:01 pm
by Mario79
Ghost
В общем, после добавления твоего кода перестал работать APM Power OFF. Видимо при обратном переходе в реальный режим процессора, надо восстанавливать исходное состояние или делать принудительный сброс.
После доработки сделанной Diamond'ом (описано выше) на старом компе (Cyrix233MX) демо программа, выключающая монитор перестала намертво вещать систему. Теперь она просто висит в панели 5 секунд и убирается.

Posted: Sat May 13, 2006 11:40 am
by Ghost
при переходе в RM нужно откключить 32х битный интерфейс, и присоединить 16, (хотя там помойму примерно так и делается, нет кода под рукой)
про eflags я думал что они лежат в такомже порядке как в TSS, может общитался?
у меня с демо порграммо монитор показывает чёрный экран, но не выключается и не переходит в ждуший режим

Posted: Sat May 13, 2006 3:38 pm
by Mario79
Ghost
Если можешь, то исправь, пожалуйста, код.
Выключение монитора целиком зависит от него самого. Если у тебя он не выключается, значит, он не просекает, что сигнал с видеокарты отключен. У меня все нормально и монитор гаснет сразу, а потом включается. Это я про новый комп, а не про старый.

Posted: Mon May 15, 2006 3:28 pm
by diamond
Добавил три строчки выключения интерфейса в shutdown.inc. Теперь выключение вроде работает.