?? power.asm
字號:
iret ; don't need to chain if BIOS resident
ENDIF
I28_idle endp
;********************* Shell idle check ******************************
; purpose: check idle (INT 2A Function 84h)
; if interrupt is detected than DO_IDLE should be called
; the interrupt should be absorbed.
PUBLIC I2A_idle
I2A_idle proc far
assume ds:nothing, es:nothing
push ds
mov ds, Bios_Data_Word
assume ds:Bios_Data
cmp ah,84h
jne i2Anxt ; check for a service call to us
; load up registers and call do idle
push di
lea di,[INFO].SHELL_TOT
call DO_IDLE
adc word ptr [di],0 ; accumulate idle time
adc word ptr [di]+2,0
pop di
pop ds
iret
i2Anxt:
jmp dword ptr pwr_i2a_next
I2A_idle endp
;************************ I16_IDLE *********************
PUBLIC I16_IDLE
I16_IDLE proc near
assume ds:nothing, es:nothing
push ds
mov ds,Bios_Data_Word
assume ds:Bios_Data
cmp [IN_KYC],0
jne kybxxx
cmp ah,01h
je kbpchk
cmp ah,11h
je kbpchk
or ah,ah
jz kbChkIdle
cmp ah,10h
jz kbChkIdle
kybxxx:
jmp dword ptr pwr_i16_next
kbpchk: inc [KYC].PCOUNT
test [CONTROL].IDLE_FLG,KYC_ACTIVE
jz kybxxx
mov [IN_KYC],1 ; ONLY ALLOW ONE RE-ENTRY
jmp dword ptr pwr_call_i16 ;call old int 16h handler
;
;We return to the label below after calling the previous int 16h handler
;
calli16ret:
mov ds,Bios_Data_Word ;reinit DS to Bios_Data
assume ds:Bios_Data
push bx
lea bx,KYC_TMR0
; if a key is ready, just clear out our timer and
; return. If no key is ready, go through the full
; delay check. Here we check the flags returned
; by the INT 16 handler we called.
jz i16_ChkDelay
; Just clear the timer
push ax
call ClearTimer
pop ax
jmp short kbpret
i16_ChkDelay:
; load up registers and call delay check
push cx
push si
push di
lea si,KYC
lea di,[INFO].KEY_TOT
mov cx,1
call Chk_i16idle
pop di
pop si
pop cx
kbpret:
pop bx
mov [IN_KYC],0 ; can start up again
pop ds
assume ds:nothing
iret
kbChkIdle:
assume ds:Bios_Data
; see if there is a key available
inc ah ; make it to fn 1 or 11
kbChkKey:
push ax ; save function no (1 or 11h)
jmp dword ptr kb_call_i16 ;call old int 16h handler
kbChkRet:
pop ax ; get back orig. polling fn no
jz kbDoIdle ; no key available
dec ah ; get back original get key fn(0 or 10)
jmp kybxxx ; go get the key
; no key available do idle
kbDoIdle:
push ax
push bx
push di
lea bx,KYC_TMR0
lea di,[INFO].KEY_TOT
call DO_IDLE
adc word ptr [di],0 ; accumulate idle time
adc word ptr [di]+2,0
mov word ptr [bx]+2,0 ; avoid speed up error
call ClearTimer
pop di
pop bx
pop ax
jmp short kbChkKey ; go look for key
I16_IDLE endp
;************************ I1C_TIMR *********************
PUBLIC I1c_Timr
I1c_Timr proc
assume ds:nothing, es:nothing
push ds
push ax
mov ax,BIOSDATASEG ; M092 check rollover flag in BIOS
mov ds,ax ; M092
xor al,al ; M096
xchg al,ds:[ROLLOVERFLG] ; M096 get Bios rollover flg and
; reset it
mov ds,Bios_Data_Word
assume ds:Bios_Data
or [CMOSUpdFlg],al ; M092 set update flag if rollover
dec [CMOSPollCount] ; M090
jz itmSetCMOSFlg ; M090
itmNoTmUpdate:
inc [SPDUP_CNT] ; speedup delay
test [POWER_STATUS],1 ; is idle detection on ?
jz i1c_to_end
inc [KYC_TMR0]+2 ; timer over flow
inc [KYC].DELAY ; adjust delay
inc [I28_TMR0]+2 ; timer over flow
inc [I28].DELAY ; adjust delay
add word ptr [INFO].CPU_ON_TIME,1
adc word ptr [INFO].CPU_ON_TIME+2,0
xor ax,ax ; M004 BEGIN
xchg [IDLTIC],ax ; If we were idle during the last
add word ptr [INFO].CPU_IDLE_TIME,ax ; tick period, let's
adc word ptr [INFO].CPU_IDLE_TIME+2,0 ; count it
; M004 END
test [CONTROL].IDLE_FLG,AUTO_ACTIVE ; no AUTO adjust
i1c_to_end:
jz itmxxx
itmot1: inc [SWITCH_CNT] ; time to switch methods?
mov ax,[CONTROL].SWITCH_DLY
cmp [SWITCH_CNT],ax
jb itmxxx ; not yet ...
itmot2: mov [SWITCH_CNT],0
mov ax,[I28].PCOUNT ; If( KYC.COUNT < I28.COUNT)
cmp ax,[KYC].PCOUNT ; occurs in windows ...
ja itmdos
; keyboard count is higher than INT 28 count
; keyboard is highest count, it wins
cmp [KYC].PCOUNT,0 ; avoid thrashing
je itmxxx
mov ax,KYC_ACTIVE
jmp short itmset
itmSetCMOSFlg:
mov al,[CMOSFlg] ; M090 ; need to update from CMOS
or [CMOSUpdFlg],al ; M090 ; only if POWER STD mode in APM
mov ax,MAXCMOSPOLLCOUNT ; machines
mov [CMOSPollCount],ax ; start counting again
jmp itmNoTmUpdate
itmdos: ; INT 28 count higher than keyboard count
; INT 28 count is highest, it wins
or ax,ax ; don't bother if count is 0
jz itmxxx
mov ax,DOS_ACTIVE
itmset: and [CONTROL].IDLE_FLG,NOT ( APP_ACTIVE+DOS_ACTIVE+KYC_ACTIVE)
or [CONTROL].IDLE_FLG,ax
itmskp: xor ax,ax ;reset for next round
mov [KYC].PCOUNT,ax
mov [I28].PCOUNT,ax
itmxxx:
test [POWER_STATUS],2 ; M089 is F/W mgmt on ?
jz itmChain ; M089 No need to poll APM in POWER
; STD mode
IFDEF INCL_APM
; now check to see if we need to call APM for a PMEVENT
cmp fAPM_STATE,0 ; is APM enabled ?
je itmChain
dec APM_POLL_COUNT
jnz itmChain
; time to poll APM for any PM Event
push bx
mov ax,[APM_MAX_POLLCOUNT] ; first reset the counter
mov APM_POLL_COUNT,ax
;
itmPoll:
mov ax,APM_GETPMEVENT_FUNC
int 15h
jc itm_End ; no events -> no work to do
;
; BX = PM Event
; 1 = stand-by request
; 2 = suspend request
; 3 = normal resume
; 4 = crit. resume
; 5 = battery low
cmp bx,APM_NORM_RESUME
je itm_Set_time
cmp bx,APM_CRIT_RESUME
jne itm_broadcast
itm_Set_time:
INC APM_RESUME_COUNT
call Do_APM_CPUBUSY ; M002 bring CPU to full speed
mov [CMOSUpdFlg],1 ; M090
itm_broadcast:
mov ax,I2F_APM_BROADCAST
int 2fh ; broadcast the pm events to other
; apps
; BUGBUG: Warning: the function codes for APM BIOS GetPMEvent and
; the multiplex API broadcast functions are assumed to be the same
cmp bl,APM_NORM_RESUME ; was it a stand-by/suspend request
jae itm_End ; if not, nothing else to do
;
; this was an APM request for system stand-by/suspend
; if no apps/tsrs objected to this request, let us call the APM to suspend/
; stand-by
or bh,bh
jnz itm_End ; somebody objected ? if so quit
push cx ; M093
mov cx,bx ; required power mode in CX
mov bx,APM_SYSTEM_DEV ; full system
mov ax,APM_SETPWSTATE_FUNC
int 15h
pop cx ; M093
IFDEF DEBUG
jnc itm_dbg_Success
dbg_printchar 'f' ; CY for a set power state call
itm_dbg_Success:
ENDIF ; IFDEF DEBUG
; Resumed from a suspend/stand-by; we should get a resume notification
; from APM so that we can go and update the date and time
jmp itmPoll ; go back and poll APM for
; a resume notification event
;
itm_End:pop bx
ENDIF
itmChain:
pop ax
jmp dword ptr pwr_i1c_next
I1C_TIMR endp
;************* I6C_RESUME *****************************
;
; On interrupts 6C, update system date and time from the hardware
; clock. Int 6C is one way a system may signal a resume event.
; Entire routine is part of modification M080.
I6C_Resume proc
assume ds:nothing,es:nothing
push ds
mov ds,cs:Bios_Data_Word
assume ds:Bios_Data
; Bugbug -- need to sti?
; Bugbug -- enough stack space?
push ax
push bx
push cx
push dx
push si
push di
IFDEF POWERALONE ; M081
call far ptr P_UpdFromCMOS
ELSE
call P_UpdFromCMOS_ptr ; M074 update our date and time
; from CMOS RTC
ENDIF
pop di
pop si
pop dx
pop cx
pop bx
pop ax
jmp dword ptr pwr_i6c_next
I6C_Resume endp
;************* APPLICATION ACTIVITY MONITORS ***********
; SPEED UP by setting DOIdle delay count relitive to TIMER interrupts
; that have occurred between polling interrupt ...
; ** REQUIRES TESTING -- At this point APP_SPDUP tends to inhibit idle
PUBLIC APP_SPDUP
App_Spdup proc near
assume ds:Bios_Data, es:nothing
push ax
mov ax,[SPDUP_DLY] ; machine speed dependent
add ax,[CONTROL].SPDUP_RAMP
cmp ax,[CONTROL].SPDUP_MAX ; machine speed dependent
jb asdot3
mov ax,[CONTROL].SPDUP_MAX
asdot3: mov [SPDUP],1 ; indicate activity
mov [SPDUP_DLY],ax
mov [SPDUP_CNT],0
pop ax
asdex0: ret
App_Spdup endp
I9_App proc
assume ds:nothing, es:nothing
push ds
mov ds,Bios_Data_Word
assume ds:Bios_Data
dec [I9_COUNT]
jnz i9ex0
mov [I9_COUNT],2
call APP_SPDUP
i9ex0:
jmp dword ptr Pwr_i9_next
I9_App endp
I10_App proc
assume ds:nothing, es:nothing
push ds
mov ds,Bios_Data_Word
assume ds:Bios_Data
cmp ah,04h ; avoid cursor set
jb i10ex0 ; calls
call APP_SPDUP
i10ex0:
jmp dword ptr Pwr_i10_next
I10_App endp
I13_App proc
assume ds:nothing, es:nothing
push ds
mov ds,Bios_Data_Word
assume ds:Bios_Data
call APP_SPDUP
jmp dword ptr Pwr_i13_next
I13_App endp
I14_App proc
assume ds:nothing, es:nothing
push ds
mov ds,Bios_Data_Word
assume ds:Bios_Data
cmp ah,3 ; avoid status calls
je i14ex0
call APP_SPDUP ; M002
i14ex0:
jmp dword ptr Pwr_i14_next
I14_App endp
I17_App proc
assume ds:nothing, es:nothing
push ds
mov ds,Bios_Data_Word
assume ds:Bios_Data
cmp ah,2 ; avoid status calls
je i17ex0
call APP_SPDUP
i17ex0:
jmp dword ptr Pwr_i17_next
I17_App endp
I21_App proc
assume ds:nothing, es:nothing
push ds
mov ds,Bios_Data_Word
assume ds:Bios_Data
push ax
; upper bound check
cmp ah,MAX_I21_ENTRY
ja i21SpdUp
; get action from the lookup table
push bx
mov bx,offset i21_table ; look up table for APIs
xchg ah,al ; get function code in al
xlat
pop bx
or al,al ; a busy call ?
jz i21SpdUp
inc al ; idle calls ?
jz i21ex0
; special cases
cmp ax,644h ; ioctl get input status call ?
je i21ex0
cmp al,4b
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -