?? power.asm
字號:
PAGE ,132
;**************************************************************
;* POWER.SYS - MSDOS 5.0 IDLE DETECTION DEVICE DRIVER
;*
;* Microsoft Confidential
;* Copyright (C) Microsoft Corporation 1991
;* All Rights Reserved.
;*
;* Revision History
;* 90/7/19 [BR] Completed beta DRIVER V0.30
;* 04/29/91 SR Modified to make it ROMmable. Separated CODE,
;* DATA & INIT segments.
;* 06/03/91 MD Merged standalone and resident versions,
;* support idle checking on INT 2F Idle
;* 07/01/91 JRCB Changed STANDALONE to POWERALONE to remove confusion
;* with ROMDRIVE variable of same name.
;* 08/12/91 NSM added APM support (M001)
;*
;* 08/21/91 NSM M002: Removed the comment marks in Int14 hook
; (bug # : printing slowed when POWER is present)
; Added a call to CPU_BUSY after resume
;
; 08/29/91 NSM M003: removed rest of IOCTL support
;
; 09/05/91 NSM M004: Bug# 2587
; Moved CheckV86 calls only for DOING HLT and not
; for OEM_IDLE or for APM_IDLE (2587)
; Also fixed the problem with multiple resumes.
; If we get a resume without a initial suspend notifi.
; then we ignore this resume command now.
; Bug#2574 Count CPU_IDLE time at Int 1c
;
; 09/08/91 DBO M005: Straighten out far calls in BIOS-resident
; driver:
; Do_APM_Enable_Disable -- make near
; Check_and_Init_APM -- list in seg_reinit
; time_to_ticks -- reference via ttticks
; (already in seg_reinit)
; Do_APM_Connect -- make near
;
; 09/11/91 NSM/DBO M074: Replace clock driver functions, so we can manage
; manage system date & time updates after resume events.
;
; 09/11/91 SMR M075: B#2670. Get Idle Algorithm was trashing IDLE_FLG
;
; 09/11/91 SMR M076: B#2668. Statistics were not being copied if the
; user buffer is bigger than the required size.
;
; 09/11/91 SMR M077: B#2669. Registered POWER's 2f channels in mult.inc
;
; 09/11/91 SMR M078: Use HLT even if the processor is in V86 mode
;
; 09/11/91 SMR M079: PWR_API returns 0 in AX instead of no carry flag
; in case of no error
;
; 09/11/91 DBO M080: Power management clock hooks int 6C for
; resume events.
;
; 09/12/91 SMR Call P_UpdFromCMOS directly if power is standalone
;
; 09/12/91 SMR Load ES:DI before dispatching a CLOCK$ call.
;
; 09/17/91 NSM M084: Don't zero out AX for version check int 2f call
;
; 09/19/91 SMR M085: Return break address from clock driver init also
;
; 09/19/91 SMR M086: Save/Restore SI in get/Set statistics calls
;
; 09/23/91 NSM M087: Change signature to 504DH
;
; 09/25/91 NSM M088: (B# 2730) Hang in GET_APM_STAT - missing "push si"
;
; 09/25/91 NSM M089: I2F service routine changes related to UI change.
; (definition of POWER STD needed some extra code)
;
; 09/25/91 NSM M090: CLOCK driver related changes to take care of
; WIN 3 ENH mode eating up I1Cs. Soln. is to update our
; time from CMOS once in 1024 I1c ticks. Do this only
; when win enh mode starts up and discontinue once win
; ends. (Bug# 2729)
;
; 09/25/91 NSM M091: Also update our time from CMOS when POWER STD
; is selected on an APM machine.
;
; 10/25/91 NSM M093: CX reg is getting trashed while making suspend
; standby APM call in Int1C.
; While changing APM_MAX_POLLCOUNT, we should update
; the current APMPoll Counter also (APM_POLL_COUNT).
;
; 10/29/91 NSM M094: AX and BL regs were getting trashed in some of
; the INT 2f service routines.
;
; 11/05/91 NSM M096: Eat the rollover flag in Int 1C before command
; gets it.
;
;**************************************************************
TITLE POWER$ IDLE DETECTION V1.0
.xlist
include version.inc ; M004 set build flags
break macro ; satisfy mult.inc
endm
include mult.inc ; get our int 2f function equates ; M077
IFDEF POWER
IFNDEF POWERALONE ; segment declarations for resident version
include biosseg.inc ; establish bios segment structure
ELSE ; segment declarations for standalonde version
.SEQ
Bios_Code segment word public 'Bios_Code'
Bios_Code ends
Bios_Data segment word public 'Bios_Data'
Bios_Data ends
SysInitSeg segment word public 'system_init'
SysInitSeg ends
Pdb_Data segment at 0h ; JAH Dummy segment for accessing the
org 42h ; JAH active program's PSP
PDB_Idle label BYTE ; JAH
Pdb_Data ends ; JAH
; following segment definitions used by transient part of code
ENDIF
include msequ.inc
include devsym.inc
include bpb.inc
include ioctl.inc
include power.inc
IFDEF INCL_APM
include apmequ.inc ; M001
ENDIF
break macro
endm
include error.inc
.list
include msgroup.inc ; define Bios_Data segment
IFDEF POWERALONE ; standalone device driver version
Bios_Res dw Bios_Code ; Our code segment address
ELSE ; resident BIOS version
extrn Bios_Res:word ; Code segment address supplied externally
extrn ttticks:dword ; far ptr to time_to_ticks routine
extrn P_UpdFromCMOS_Ptr:dword ; ptr to CMOS clock read ; M081
IFDEF INCL_APM
extrn Check_and_Init_APM_Ptr:dword ; ptr to APM init routine
ENDIF ;INCL_APM
ENDIF ;NOT POWERALONE
public RHPTR, KYC, I28, CONTROL, INFO, MSW
public IDLTIC, TOTTIC, SPDUP, SPDUP_DLY, SPDUP_CNT ; M004
public I2F_VEC, I28_TMR0, I28_VEC, KYC_TMR0, KYC_RET, IN_KYC
public I16_VEC, SWITCH_CNT, I1C_VEC, I9_COUNT, I9_VEC, I10_VEC, I13_VEC
public I14_VEC, I17_VEC, I21_VEC,I25_VEC,I26_VEC,I2A_VEC
IFDEF INCL_APM ; M001
public fAPM_PRESENT,APM_FLAGS,APM_VER,APM_POLL_COUNT,fAPM_CONNECT
public APM_MAX_POLLCOUNT,fAPM_STATE,APM_RESUME_COUNT
ENDIF
RHPTR dd 0
; M003 : BEGIN ioctl support removed
; following is indirect entry point into power control module.
; Replacements for Power.exe can plug a different address into
; this space to redirect calls to the Power driver.
;
;EntryPoint dw pow_control, Bios_Code
; M003 END
dbg_printchar macro dispchar
IFDEF DEBUG
push ax
mov ah,0eh
mov al,dispchar
int 10h
pop ax
ENDIF
endm
POWER_DATA label byte
KYC PERIOD_INFO < 0, 20, 20, 0, 0, 0> ; default values for base and
I28 PERIOD_INFO < 0, 100, 20, 0, 0, 0> ; noise are (random)conservative
CONTROL CONTROL_INFO < 00101111b, 8*2, 58982, 4, 40, 0, 1, 8, 0>
; M078
; idle_flg, sw_dly,thres,ad_dl,mx,sp_dl,ramp,sp_mx,386flg
INFO IDLE_INFO < 0, 0, 0, 0, 0, 0, 0>
ErrSampleCount dw 0
MSW dw 0 ; store machine status word
; bit 0 = 1 indicates protected mode
IDLTIC dw 0 ; M004 used as a flag that says CPU was idle
; in the last (I1c) tick period
TOTTIC dw 0 ; running total of halt time
; in 1/1.19 MHZ increments 65536=55ms
SPDUP dw 0 ; Activity indicator 1 active avoid halting
SPDUP_DLY dw 0 ; MAX DELAY set by activity monitor
SPDUP_CNT dw 0 ; incremented via INT 1C
PSPsegment dw (?) ; JAH - Dos DATA seg used to
; access Current PSP
I2F_VEC dw I2F_IDLE, 0 ; holds next pointer in chain
I2F_TMR0 dw 0 ;+0, holds temporary PC timer 0
; values used to compute PERIOD
dw 2 ;+2, Counts number of times PC
; timer has Overflowed
I2A_VEC dw I2A_IDLE, 0 ; holds next pointer in chain
I28_TMR0 dw 0 ;+0, holds temporary PC timer 0
; values used to compute PERIOD
dw 2 ;+2, Counts number of times PC
; timer has Overflowed
I28_VEC dw I28_IDLE, 0
KYC_TMR0 dw 0 ;+0, holds temporary PC timer 0
; values used to compute PERIOD
dw 2 ;+2, Counts number of times PC
; timer has Overflowed
KYC_RET dw 0,0 ; stores 1 return address
IN_KYC dw 0 ; flags re-entry of key board check
I16_VEC dw I16_IDLE, 0 ; stores next key routine in chain
SWITCH_CNT dw 0 ; keeps track of when to
; switch idle detect methods
I1C_VEC dw I1C_TIMR,0
I9_COUNT dw 2 ; for every key press more
; a minimum of 2 INT 9's occur
I9_VEC dw I9_APP,0
I10_VEC dw I10_APP,0
I13_VEC dw I13_APP,0
I14_VEC dw I14_APP,0
I17_VEC dw I17_APP,0
I21_VEC dw I21_APP,0
I25_VEC dw I25_APP,0
I26_VEC dw I26_APP,0
I6C_VEC dw I6C_RESUME, 0 ;M080
IFDEF INCL_APM ; M001
fAPM_PRESENT db 0
fAPM_CONNECT db 0 ; set to 1 if connected
APM_MAX_POLLCOUNT dw 50
APM_FLAGS dw 0
APM_VER dw 0
APM_POLL_COUNT dw 50
; counter for APM polling ; counted in int 1c
; int. time.
fAPM_STATE db 0 ; 0 if APM disabled and 1 if APM enabled
APM_RESUME_COUNT dw 0 ; counter for no of resumes from last
; APM enable
ENDIF ;INCL_APM
PUBLIC CMOSUpdFlg ; M090
PUBLIC CMOSPollCount ; M090
CMOSUpdFlg db 0 ; M090 set to 1 if we need to update from CMOS
CMOSPollCount dw MAXCMOSPOLLCOUNT ; M090
CMOSFlg db 0 ; M091 bit 0 set to 1 in POWER STD mode on APM
; machines
BaseLineRef dw 0 ; counters for counting no of i16s we can get
; through in about 4 secs (done at each
; exec)
BaseLineOvf dw 0 ;
IFDEF POWERALONE ; needed only for standalone version
public daycnt
daycnt dw 0
public daycnt2
daycnt2 dw 0
public base_century
base_century db 19
public base_year
base_year db 80
public month_tab
month_tab db 31,28,31,30,31,30,31,31,30,31,30,31
public bin_date_time
bin_date_time:
db 0 ; year in century (0...99) or minutes (0-59)
db 0 ; century (19 or 20) or hours (0-23)
db 0 ; day in month (1...31)
db 0 ; month in year (1...12) or seconds (0-59)
public month_table
month_table:
dw 0 ; january
dw 31 ; february
dw 59 ; march
dw 90 ; april
dw 120 ; may
dw 151 ; june
dw 181 ; july
dw 212 ; august
dw 243 ; september
dw 273 ; october
dw 304 ; november
dw 334 ; december
ELSE ; for resident version
extrn bin_date_time:byte
extrn month_table:word
extrn daycnt:word
extrn daycnt2:word
ENDIF ; POWERALONE
;-------------------------------------------------------------------
; 1 byte for each int 21 api from functions 0 thro 57h
; an entry of 0ffh means ignore this api for false idle monitoring
; 0 -> this api means we are busy
; any other number -> special cases
i21_table label near
db 0, 0, 0, 0, 0, 0, 5, 0 ; fns 0-7
db 0, 0, 0,0ffh, 0, 0, 0, 0 ; fns 8-0f
db 0, 0, 0, 0, 0, 0, 0, 0 ; fns 10-17
db 0, 0, 0, 0, 0, 0, 0, 0 ; fns 18-1f
db 0, 0, 0, 0, 0,0ffh, 0, 0 ; fns 20-27
db 0, 0,0ffh, 0,0ffh, 0, 0, 0 ; fns 28-2f
db 0, 0, 0, 0, 0,0ffh, 0, 0 ; fns 30-37
db 0, 0, 0, 0, 0, 0, 0, 0 ; fns 38-3f
db 0, 0, 0, 0,043h, 0, 0, 0 ; fns 40-47
db 0, 0, 0,04ah, 0, 0, 0, 0 ; fns 48-4f
db 0ffh,0ffh, 0, 0, 0, 0, 0, 0 ; fns 50-57
db 0, 0, 0, 0, 0, 0, 0,05eh ; fns 58-5f
MAX_I21_ENTRY equ 5fh
;-------------------------------------------------------------------
POWER_STATUS db 1 ; default ;bit 0 - S/W pw.mgmt always enabled
; bit 1 - Take control of APM/FIRMWARE mgmt
; (or get connected to APM)
; M001
; M089 If bit1 is set, We are connected to APM
; but not neccessarily enabled APM
; (look at fAPM_State)
Pwr_i2f_next dw Pwr_i2f_lab
dw Bios_Data
Pwr_i2f_lab:
pop ds
jmp dword ptr cs:I2f_Vec
Pwr_i2a_next dw Pwr_i2a_lab
dw Bios_Data
Pwr_i2a_lab:
pop ds
jmp dword ptr cs:I2a_Vec
IFDEF POWERALONE
Pwr_i28_next dw Pwr_i28_lab
dw Bios_Data
Pwr_i28_lab:
pop ds
jmp dword ptr cs:i28_Vec
ENDIF
Pwr_i16_next dw Pwr_i16_lab
dw Bios_Data
Pwr_i16_lab:
pop ds
jmp dword ptr cs:I16_Vec
Pwr_call_i16 dw Pwr_calli16_lab
dw Bios_Data
Pwr_calli16_ret dw Calli16ret
dw 0
Pwr_calli16_lab:
pop ds
pop Kyc_Ret
pop Kyc_Ret+2
call dword ptr I16_Vec
pushf
push Kyc_Ret+2 ; don't clear before
push Kyc_Ret ; return values on stack
push ds
jmp dword ptr Pwr_calli16_ret
kb_call_i16 dw kb_calli16_lab
dw Bios_Data
kb_calli16_ret dw kbChkRet
dw 0
kb_calli16_lab:
pushf
call dword ptr I16_Vec
jmp dword ptr kb_calli16_ret
Pwr_i1c_next dw Pwr_i1c_lab
dw Bios_Data
Pwr_i1c_lab:
pop ds
jmp dword ptr cs:I1c_Vec
Pwr_i9_next dw Pwr_i9_lab
dw Bios_Data
Pwr_i9_lab:
pop ds
jmp dword ptr cs:I9_Vec
Pwr_i10_next dw Pwr_i10_lab
dw Bios_Data
Pwr_i10_lab:
pop ds
jmp dword ptr cs:I10_Vec
Pwr_i13_next dw Pwr_i13_lab
dw Bios_Data
Pwr_i13_lab:
pop ds
jmp dword ptr cs:I13_Vec
Pwr_i14_next dw Pwr_i14_lab
dw Bios_Data
Pwr_i14_lab:
pop ds
jmp dword ptr cs:I14_Vec
Pwr_i17_next dw Pwr_i17_lab
dw Bios_Data
Pwr_i17_lab:
pop ds
jmp dword ptr cs:I17_Vec
Pwr_i21_next dw Pwr_i21_lab
dw Bios_Data
Pwr_i21_lab:
pop ds
jmp dword ptr cs:I21_Vec
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -