📄 gpmlib.inc
字号:
ide_wait_for_interrupt_12:
mov si,wfiloop ; wait for interrupt timeout (16 secs)
ide_wait_for_interrupt_02:
xor cx, cx ; 1 sec loop count
ide_wait_for_interrupt_03:
IF IRQ_HANDLING_SUPPORT
call check_irq_pm ; IRQ based power management ?
jnz short ide_wait_for_interrupt_10 ; yes...
ENDIF
call read_8259_irr_reg ; interrupt came ?
ide_wait_for_interrupt_11:
jnz short ide_wait_for_interrupt_04 ; yes....
push cx ;
mov cx, 2 ; give 15 microsec delay
call pm_fixed_delay ; PM_FIXED_DELAY ROUTINE MAY NOT BE ABLE TO GIVE 15 MICROSEC DELAY
pop cx ;
loop short ide_wait_for_interrupt_03 ;
dec si ; does not disturb (CF)
jnz short ide_wait_for_interrupt_02 ;
ide_wait_for_interrupt_04:
pop si ;
ret
IF IRQ_HANDLING_SUPPORT
ide_wait_for_interrupt_10:
in al,dx ; (al) = current status
not al ;
test al,ide_cntlr_busy_bit ; controller busy ?
jmp short ide_wait_for_interrupt_11 ;
ENDIF
ide_wait_for_interrupt endp
;---------------------------------------------------------------;
ide_power_down_ends label byte
ENDIF
;---------------------------------------------------------------;
;*****************************************************************;
;*****************************************************************;
;** **;
;** (C)Copyright 1985-1996, American Megatrends Inc. **;
;** **;
;** All Rights Reserved. **;
;** **;
;** 6145-F, Northbelt Parkway, Norcross, **;
;** **;
;** Georgia - 30071, USA. Phone-(770)-246-8600. **;
;** **;
;*****************************************************************;
;*****************************************************************;
;---------------------------------------------------------------;
; CODE TO UPDATE DOS DATE/TIME ;
; CODE TO UPDATE DOS DATE/TIME ;
; CODE TO UPDATE DOS DATE/TIME ;
; CODE TO UPDATE DOS DATE/TIME ;
;---------------------------------------------------------------;
; All the code from here labelled as 'DOS_DATE_TIME_RESTORE' to ;
; the label 'DOS_DATE_TIME_RESTORE_ENDS' should be made active if
; dos date/time needs to be updated during sleep & suspend. The ;
; chipset should update date/time if chipset porting stops cpu ;
; clock for more than one timer ticks. The following routines ;
; can update dos date/time only....... ;
; Please take the comment out in between the above mentioned ;
; labels if you want to use this routines. ;
; In this scenario where system date/time needs to be updated, you
; should setup proper apm events (if apm is enabled) depending on
; apm V1.0 & v1.1, so that dos/windows automatically updates the;
; system date/time. ;
; Following two routines needs to be called... ;
; SAVE_SUSPEND_DATE_TIME ;
; RES_SUSPEND_DATE_TIME ;
; CALL 'save_suspend_date_time' while going to SLEEP/SUSPEND
; CALL 'res_suspend_date_time' while coming out of ;
; SLEEP/SUSDPEND ;
;---------------------------------------------------------------;
IF DATE_TIME_UPDATION_SUPPORT
dos_date_time_restore label byte
;---------------------------------------------------------------;
; SAVE_SUSPEND_DATE_TIME ;
;---------------------------------------------------------------;
; Input : NONE ;
; Output: (CY) 00 for no error ;
; (CY) 01 for err..RTC inoperational ;
; Register destroyed : NONE ;
; NOTE : Saves date on suspend in local SUSPEND_DATE structure ;
;---------------------------------------------------------------;
save_suspend_date_time proc near
IF IRQ_HANDLING_SUPPORT
call check_irq_apm ; IRQ based APM 16/32 bit function currently being executed ?
jnz short save_suspend_date_time_20 ; yes...
ENDIF
pushad ;
call get_rtc_date ; Read RTC Date
; returns (ch) = century, (cl) = year
; (dh) = month, (dl) = date
call date_to_binary ; (eax) = century/year/month/day in BINARY
mov ds:suspend_date,eax ; save in local data area
clc ; (cy) = 00 for no error
popad ;
save_suspend_date_time_20:
ret
save_suspend_date_time endp
;---------------------------------------------------------------;
; RES_SUSPEND_DATE_TIME ;
;---------------------------------------------------------------;
; Input : NONE ;
; Output: (CY) 00 for no error ;
; (CY) 01 for err..RTC inoperational ;
; Register destroyed : NONE ;
;---------------------------------------------------------------;
res_suspend_date_time proc near
IF IRQ_HANDLING_SUPPORT
call check_irq_apm ; IRQ based APM 16/32 bit function currently being executed ?
jnz short res_suspend_date_time_20 ; yes...
ENDIF
call set_dos_time ;
call set_dos_date ;
res_suspend_date_time_20:
ret
res_suspend_date_time endp
;---------------------------------------------------------------;
; SET_DOS_TIME ;
;---------------------------------------------------------------;
; Input : NONE ;
; Output: (CY) 00 for no error ;
; (CY) 01 for err..RTC inoperational ;
; Register destroyed : NONE ;
; NOTE : Sets DOS TIME in BIOS global based on current RTC time;
;---------------------------------------------------------------;
set_dos_time proc near
pushad ;
call get_rtc_time ; Read RTC time
; returns (ch) = hour, (cl) = minute
; (dh) = seconds
call hr_min_sec_to_sec ; (eax) = total seconds in BINARY
call seconds_to_timer_ticks ; (eax) = total timer ticks
push ds ; save on entry (ds)
push bios_data_seg ; BIOS standard data segment
pop ds ;
mov dword ptr timer_low_count,eax ; set DOS time
pop ds ; restore on entry (ds)
clc ; set (cy) = 00 for no error
popad ;
ret
set_dos_time endp
;---------------------------------------------------------------;
; SET_DOS_DATE ;
;---------------------------------------------------------------;
; Input : NONE ;
; Output: (CY) 00 for no error ;
; (CY) 01 for err..RTC inoperational ;
; Register destroyed : NONE ;
; NOTE : Update the BIOS global data area based on # of days ;
; passed in suspend ;
;---------------------------------------------------------------;
set_dos_date proc near
pushad ;
call get_rtc_date ; Read RTC Date
; returns (ch) = century, (cl) = year
; (dh) = month, (dl) = date
call date_to_binary ; (eax) = century/year/month/day in BINARY
push eax ;
pop dx ; (dh) = month in BINARY, (dl) = day in BINARY
pop cx ; (ch) = century in BINARY, (cl) = year in BINARY
mov eax,ds:suspend_date ;
mov bx,ax ; (bl) = old DAY in BINARY, (bh) = old MONTH in BINARY
shr eax,16 ; (al) = old YEAR in BINARY, (ah) = old CENTURY in BINARY
call days_in_suspend ; (ax) = # of full days in suspend
push ds ; save on entry (ds)
push bios_data_seg ; BIOS standard data segment
pop ds ;
mov timer_count_rolled,al ;
pop ds ; restore on entry (ds)
clc ; set (cy) = 00 for no error
popad ;
ret
set_dos_date endp
;---------------------------------------------------------------;
; SECONDS_TO_TIMER_TICKS ;
;---------------------------------------------------------------;
; Input : (EAX) seconds in BINARY ;
; Output: (EAX) timer ticks ;
; Register destroyed : (EAX),(EBX),(EDX) ;
; NOTE : Input frequency is 1.19318 MHz & the divisor is 65536 ;
; which means 18.20648 interrupts every second. ;
; We will compute total ticks as : ;
; <01> 18*total seconds + ;
; <02> .20648*65536*total seconds & ;
; ignore the lower word ;
;---------------------------------------------------------------;
seconds_to_timer_ticks proc near
mov ebx,eax ; (eax) = (ebx) = total seconds
mov edx,18 ;
mul edx ; (eax) = total seconds * 18
xchg eax,ebx ; (eax) = total seconds
; (ebx) = total seconds * 18
mov edx,13532 ; 0.20648*65536
mul edx ; (eax) = 0.20648*65536*total seconds
shr eax,16 ; (eax) = 0.20648*65536*total seconds/65536
add eax,ebx ; (eax) = total timer ticks
ret
seconds_to_timer_ticks endp
;---------------------------------------------------------------;
; DAYS_IN_SUSPEND ;
;---------------------------------------------------------------;
; Input : (CH) current century in BINARY ;
; (CL) current year in BINARY ;
; (DH) current month in BINARY ;
; (DL) current day in BINARY ;
; (AH) old century in BINARY ;
; (AL) old year in BINARY ;
; (BH) old month in BINARY ;
; (BL) old day in BINARY ;
; Output: (AX) # of days in suspend ;
; Register destroyed : (AX),(BX),(CX),(DX),(SI),(DI) ;
; NOTE : <01> Assumption of maximum 99 years in suspend. ;
; <02> Century updation support from 20th century ;
; to 29th century ;
; <03> Maximum 255 days updation ;
;---------------------------------------------------------------;
days_in_suspend proc near
cmp cl,al ; current year = old year ?
jz short days_in_suspend_10 ; yes...
ja short days_in_suspend_30 ; current year > old year
cmp ch,ah ; current century = old century ?
jnz short days_in_suspend_01 ; no...century already updated
inc ch ; increment century
push ax ;
mov al,ch ; (al) = century in BINARY
call binary_to_bcd ; (al) = century in BCD
mov ah,al ; (ah) = century in BCD
mov al,cmos_century or 10000000b ; NMI off
call smi_cmos_data_out ; write to CMOS
pop ax ;
;-----------------------------------------------;
days_in_suspend_01:
cmp cl,00h ; current year 00 ?
jz short days_in_suspend_40 ; yes...
days_in_suspend_31:
mov ax,255 ; maximum 255 days updation possible
; because of byte
ret
;-----------------------------------------------;
days_in_suspend_10:
cmp dh,bh ; current month = old month ?
jz short days_in_suspend_11 ; yes...
mov di,(offset cgroup:month_table - offset cgroup:smi_code_begin + orgbase)
test al,00000011b ; old year leap year ?
jnz short days_in_suspend_12 ; no...
mov di,(offset cgroup:month_table_leap_year - offset cgroup:smi_code_begin + orgbase)
days_in_suspend_12:
mov ah,bl ; (ah) = old day
mov bl,bh ; (bl) = old month
xor bh,bh ; (bx) = old month
mov al,cgroup:[di+bx-1] ; (al) = # of days in old month
sub al,ah ; (al) = # of days in suspend in old month
xor ah,ah ; (ax) = # of days in suspend calculated so far
sub dh,bl ; (dh) = current month - old month
dec dh ; (dh) = # of full months in suspend
jz short days_in_suspend_13 ; no full month in suspend
days_in_suspend_14:
movzx cx,byte ptr cgroup:[di+bx] ; (cx) = # of days for this month
add ax,cx ; (ax) = # of days in suspend calculated so far
inc bx ;
dec dh ;
jnz short days_in_suspend_14 ;
days_in_suspend_13:
add ax,dx ; (ax) = total days in suspend
days_in_suspend_16:
cmp ax,255 ; more than 255 days ?
jbe short days_in_suspend_15 ; no...
mov ax,255 ; maximum 255 days supported
days_in_suspend_15:
ret
days_in_suspend_11:
sub dl,bl ; current day - old day
movzx ax,dl ; (ax) = # of days in suspend
ret
;-----------------------------------------------;
days_in_suspend_30:
mov ch,cl ; (ch) = (cl) = current year
sub ch,al ; current year - old year
cmp ch,1 ; suspend time more than a year ?
ja short days_in_suspend_31 ; yes...
;-----------------------------------------------;
days_in_suspend_40:
mov di,(offset cgroup:month_table - offset cgroup:smi_code_begin + orgbase)
test al,00000011b ; old year leap year ?
jnz short days_in_suspend_41 ; no...
mov di,(offset cgroup:month_table_leap_year - offset cgroup:smi_code_begin + orgbase)
days_in_suspend_41:
mov ah,bl ; (ah) = old day
mov bl,bh ; (bl) = old month
xor bh,bh ; (bx) = old monmth
mov al,cgroup:[di+bx-1] ; (al) = # of days in old month
sub al,ah ; (al) = # of days in suspend in old month
xor ah,ah ; (ax) = # of days in suspend calculated so far
push dx ;
mov dh,12 ; 12 months in a year
sub dh,bl ; (dh) = # of full months in old year in suspend
jz short days_in_suspend_42 ; no full month in old year in suspend
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -