⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 power.asm

📁 DOS 源码 系列之 BIOS ,上传与大家分享
💻 ASM
📖 第 1 页 / 共 5 页
字号:
	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 + -