Obsah / Ovladače / CMOS / Globální funkce ovladače paměti CMOS
Zdrojový kód:
DRIVERS\SYSTEM\CMOS.ASM
Globální
funkce ovladače paměti CMOS
Globální funkce
ovladače paměti CMOS se provádějí s implicitním ovladačem
paměti CMOS, jehož popisovač je uchován v proměnné
CMOSDevice.
; -----------------------------------------------------------------------------
; CMOS global function: Read byte from CMOS memory
; -----------------------------------------------------------------------------
; INPUT: EDX = index of byte (0 to 127)
; OUTPUT: EAX = read byte (0 to 255, 0 on error)
; CY = invalid index (EAX = 0)
; NOTES: It locks fast spin-lock of device interface.
; NOTES: It takes aprox. 4 us.
; -----------------------------------------------------------------------------
CMOSGetByte: push ebx ; push EBX
mov ebx,[CMOSDevice] ; EBX <- current CMOS device
DEVFNCLOCKC DEVCMOS_GetByte ; read byte
pop ebx ; pop EBX
ret
|
Funkce CMOSGetByte
načte bajt z paměti CMOS. Na vstupu funkce obsahuje registr EDX
index bajtu v rozsahu 0 až 127. Na výstupu funkce je v registru
EAX navrácen načtený bajt v rozsahu 0 až 255. V případě
chyby (zadán neplatný index bajtu) je navrácen příznak CY a
obsah registru EAX je nulový. Funkce trvá přibližně 4
mikrosekundy. Funkce zajistí uzamknutí ovladače pomocí
rychlého zámku.
; -----------------------------------------------------------------------------
; CMOS global function: Write byte to CMOS memory
; -----------------------------------------------------------------------------
; INPUT: AL = data
; EDX = index of data (0 to 127)
; OUTPUT: CY = invalid index
; -----------------------------------------------------------------------------
CMOSSetByte: push ebx ; push EBX
mov ebx,[CMOSDevice] ; EBX <- current CMOS device
DEVFNCLOCKC DEVCMOS_SetByte ; write byte
pop ebx ; pop EBX
ret
|
Funkce CMOSSetByte
uloží bajt do paměti CMOS. Na vstupu funkce obsahuje registr
AL bajt k zápisu a registr EDX index bajtu v rozsahu 0 až 127.
V případě chyby (zadán neplatný index bajtu) je navrácen
příznak CY. Funkce trvá přibližně 4 mikrosekundy. Funkce
zajistí uzamknutí ovladače pomocí rychlého zámku.
; -----------------------------------------------------------------------------
; CMOS global function: Read data from CMOS memory
; -----------------------------------------------------------------------------
; INPUT: EAX = data buffer
; ECX = number of bytes (0 to 128)
; EDX = start index (0 to 127)
; OUTPUT: CY = invalid parameters (no data read)
; -----------------------------------------------------------------------------
CMOSGetData: push ebx ; push EBX
mov ebx,[CMOSDevice] ; EBX <- current CMOS device
DEVFNCLOCKC DEVCMOS_GetData ; read data
pop ebx ; pop EBX
ret
|
Funkce CMOSGetData
načte data z paměti CMOS. Na vstupu funkce obsahuje registr EAX
ukazatel na datový buffer (do kterého se data mají načíst),
ECX počet bajtů k načtení v rozsahu 0 až 128 a EDX
počáteční index dat v rozsahu 0 až 127. V případě chyby
(zadán neplatný index nebo neplatný počet bajtů) je
navrácen příznak CY a obsah bufferu zůstane nezměněn.
Funkce zajistí uzamknutí ovladače pomocí rychlého zámku.
; -----------------------------------------------------------------------------
; CMOS global function: Write data to CMOS memory
; -----------------------------------------------------------------------------
; INPUT: EAX = data buffer
; ECX = number of bytes (0 to 128)
; EDX = start index (0 to 127)
; OUTPUT: CY = invalid parameters (no data writen)
; -----------------------------------------------------------------------------
CMOSSetData: push ebx ; push EBX
mov ebx,[CMOSDevice] ; EBX <- current CMOS device
DEVFNCLOCKC DEVCMOS_SetData ; write data
pop ebx ; pop EBX
ret
|
Funkce CMOSSetData
uloží data do paměti CMOS. Na vstupu funkce obsahuje registr
EAX ukazatel na datový buffer (ze kterého se data mají
uložit), ECX počet bajtů k uložení v rozsahu 0 až 128 a EDX
počáteční index dat v rozsahu 0 až 127. V případě chyby
(zadán neplatný index nebo neplatný počet bajtů) je
navrácen příznak CY a žádná data nejsou zapsána. Funkce
zajistí uzamknutí ovladače pomocí rychlého zámku.
; -----------------------------------------------------------------------------
; CMOS global function: Read date and time from CMOS memory
; -----------------------------------------------------------------------------
; INPUT: EDX = pointer to DATETIME buffer
; OUTPUT: CY = time update is in progress (try again later) or DATETIME
; entries are not in valid range
; NOTES: Time update flag can be set up to 2 ms.
; Values are loaded into buffer even on error state.
; It takes aprox. 40 us.
; On some PC's day of week may be invalid (-> Sunday).
; -----------------------------------------------------------------------------
CMOSGetTime: push ebx ; push EBX
mov ebx,[CMOSDevice] ; EBX <- current CMOS device
DEVFNCLOCKC DEVCMOS_GetTime ; read date and time
pop ebx ; pop EBX
ret
|
Funkce CMOSGetTime
načte datum a čas z paměti CMOS. Na vstupu funkce obsahuje
registr EDX ukazatel na buffer DATETIME, do kterého se má datum
a čas načíst. Jsou-li údaje v CMOS neplatné nebo pokud
probíhá update cyklus času je navrácen příznak chyby CY. I
v případě navrácené chyby jsou údaje z paměti CMOS
načteny. Update cyklus znamená, že probíhá inkrementace
času hodin a je potřeba čekat na jeho dokončení. Doba
čekání se může pohybovat až do 2 milisekund. Položka dne v
týdnu může být u některých PC neplatná a proto je sice
načítána, ale není kontrolována na platnost. Je-li potřeba
časový údaj načíst přesně, je třeba opakovaným čtením
synchronizovat okamžik, kdy se zvýší údaj sekund. Funkce
trvá typicky zhruba 40 mikrosekund. Funkce zajistí uzamknutí
ovladače pomocí rychlého zámku.
; -----------------------------------------------------------------------------
; CMOS global function: Write date and time to CMOS memory
; -----------------------------------------------------------------------------
; INPUT: EDX = pointer to DATETIME buffer
; OUTPUT: CY = error (currently not used, allways NC)
; NOTES: It takes aprox. 50 us.
; Next time increment begins 0.5 sec later.
; -----------------------------------------------------------------------------
CMOSSetTime: push ebx ; push EBX
mov ebx,[CMOSDevice] ; EBX <- current CMOS device
DEVFNCLOCKC DEVCMOS_SetTime ; write date and time
pop ebx ; pop EBX
ret
|
Funkce CMOSSetTime
je funkce pro zápis aktuálního data a času do paměti CMOS.
Na vstupu funkce obsahuje registr EDX ukazatel na buffer
DATETIME, obsahující aktuální datum a čas (včetně dne v
týdnu). V případě chyby funkce navrací příznak CY. První
inkrementace času nastane 0,5 sekundy po zápisu času - při
přesné synchronizaci času je proto potřeba čas nastavit v
době za 0,5 sekundy po uběhnutí požadovaného času. Funkce
trvá typicky zhruba 50 mikrosekund. Funkce zajistí uzamknutí
ovladače pomocí rychlého zámku.
; -----------------------------------------------------------------------------
; CMOS global function: Read alarm from CMOS memory
; -----------------------------------------------------------------------------
; INPUT: EDX = pointer to DATETIME buffer
; OUTPUT: EAX = flags (ALARM_ENABLED, ...)
; CY = error
; NOTES: It takes aprox. 20 us.
; Unused entries (or on error) are initialized to 0:00:00 1/1/1
; -----------------------------------------------------------------------------
CMOSGetAlarm: push ebx ; push EBX
mov ebx,[CMOSDevice] ; EBX <- current CMOS device
DEVFNCLOCKC DEVCMOS_GetAlrm ; read alarm
pop ebx ; pop EBX
ret
|
Funkce CMOSGetAlarm
je funkce pro načtení času alarmu z paměti CMOS. Na vstupu
funkce obsahuje registr EDX ukazatel na buffer DATETIME, do
kterého bude čas alarmu načten. Na výstupu funkce jsou v
registru EAX navráceny příznaky (ALARM_ENABLED, ...). V
případě chyby funkce vrací příznak CY. Nepoužité položky
struktury jsou inicializovány na údaj 0:00:00 1/1/1. Funkce
trvá typicky 20 mikrosekund. Funkce zajistí uzamknutí
ovladače pomocí rychlého zámku.
; -----------------------------------------------------------------------------
; CMOS global function: Write alarm to CMOS memory
; -----------------------------------------------------------------------------
; INPUT: EAX = flags (ALARM_ENABLED, ...)
; EDX = pointer to DATETIME buffer
; OUTPUT: CY = error
; NOTES: It takes aprox. 20 us.
; -----------------------------------------------------------------------------
CMOSSetAlarm: push ebx ; push EBX
mov ebx,[CMOSDevice] ; EBX <- current CMOS device
DEVFNCLOCKC DEVCMOS_SetAlrm ; write alarm
pop ebx ; pop EBX
ret
|
Funkce CMOSSetAlarm
je funkce pro zápis času alarmu do paměti CMOS. Na vstupu
funkce obsahuje registr EAX příznaky (ALARM_ENABLED,...) a
registr EDX ukazatel na buffer DATETIME, obsahující čas
alarmu. V případě chyby funkce navrací příznak CY. Funkce
trvá typicky zhruba 20 mikrosekund. Funkce zajistí uzamknutí
ovladače pomocí rychlého zámku.
; -----------------------------------------------------------------------------
; CMOS global function: Get periodic interrupt rate (IRQ 8)
; -----------------------------------------------------------------------------
; OUTPUT: CY = error
; EAX = periodic interrupt rate (CMOS_RATE_NONE,...)
; NOTES: It takes aprox. 8 us.
; -----------------------------------------------------------------------------
CMOSGetRate: push ebx ; push EBX
mov ebx,[CMOSDevice] ; EBX <- current CMOS device
DEVFNCLOCKC DEVCMOS_GetRate ; get interrupt rate
pop ebx ; pop EBX
ret
|
Funkce CMOSGetRate
je funkce pro zjištění rychlosti periodického přerušení.
Na výstupu funkce navrací v registru EAX rychlost přerušení
- hodnotu CMOS_RATE_NONE, CMOS_RATE_8K atd. V případě chyby
funkce navrací příznak CY. Funkce trvá typicky zhruba 8
mikrosekund.
; -----------------------------------------------------------------------------
; CMOS global function: Set periodic interrupt rate (IRQ 8)
; -----------------------------------------------------------------------------
; INPUT: EAX = periodic interrupt rate (CMOS_RATE_NONE,...)
; OUTPUT: CY = error, invalid rate selection
; NOTES: It takes aprox. 12 us.
; -----------------------------------------------------------------------------
CMOSSetRate: push ebx ; push EBX
mov ebx,[CMOSDevice] ; EBX <- current CMOS device
DEVFNCLOCKC DEVCMOS_SetRate ; set interrupt rate
pop ebx ; pop EBX
ret
|
Funkce CMOSSetRate
je funkce pro nastavení rychlosti periodického přerušení. Na
vstupu funkce obsahuje registr EAX rychlost přerušení (hodnota
CMOS_RATE_NONE, CMOS_RATE_8K atd.). V případě chybného
argumentu navrací funkce příznak chyby CY. CMOS_RATE_NONE
přerušení zakáže, ostatní hodnoty přerušení povolí.
Funkce trvá typicky zhruba 12 mikrosekund.
; -----------------------------------------------------------------------------
; CMOS global function: Acknowledge interrupt
; -----------------------------------------------------------------------------
; OUTPUT: CY = error (currently not used, allways NC)
; NOTES: It takes aprox. 4 us.
; It reads status register C.
; -----------------------------------------------------------------------------
CMOSAckInt: push ebx ; push EBX
mov ebx,[CMOSDevice] ; EBX <- current CMOS device
DEVFNCLOCKC DEVCMOS_AckInt ; acknowledge interrupt
pop ebx ; pop EBX
ret
|
Funkce CMOSAckInt
je funkce pro potvrzení periodického přerušení. Funkce je
volána z obsluhy periodického přerušení. Informuje řadič
hodin reálného času o zpracování přerušení, čímž
umožní aktivaci příštího přerušení. Potvrzení
přerušení se provádí čtením stavového registru C hodin
reálného času. Funkce trvá typicky zhruba 4 mikrosekundy.
; -----------------------------------------------------------------------------
; CMOS global function: Reassert NMI
; -----------------------------------------------------------------------------
CMOSNextNMI: push ebx ; push EBX
mov ebx,[CMOSDevice] ; EBX <- current CMOS device
DEVFNCLOCKC DEVCMOS_NextNMI ; get IRQ channel info
pop ebx ; pop EBX
ret
|
Funkce CMOSNextNMI
je funkce k reaktivaci dalšího nemaskovatelného přerušení
po obsloužení nemaskovatelného přerušení. Funkce zajistí
uzamknutí ovladače pomocí rychlého zámku.
; -----------------------------------------------------------------------------
; CMOS global function: Read CMOS time
; -----------------------------------------------------------------------------
; OUTPUT: EDX:EAX = absolute time (100-nanoseconds from 1/1/1 CE 0:00)
; CY = error (EDX:EAX = 0)
; NOTES: Function takes normaly 40 us but it can take up to 10 ms.
; -----------------------------------------------------------------------------
; ------------- Push registers
GetCMOSTime: push ebx ; push EBX
push ecx ; push ECX
push esi ; push ESI
push ebp ; push EBP
mov ebp,esp ; EBP <- local variables
sub esp,DATETIME_size ; buffer for date-time structure
; ------------- Read date and time from CMOS (wait 256 * 40 = 10240 us)
xor ecx,ecx ; ECX <- 0
mov ch,1 ; ECX <- 256, max. attempts (= 10 ms)
xor esi,esi ; ESI <- 0, old value - time
xor ebx,ebx ; EBX <- 0, old value - date
GetCMOSTime2: mov edx,esp ; EDX <- DATETIME buffer in stack
call CMOSGetTime ; read date and time
jc GetCMOSTime6 ; error
; ------------- Check old value if it has been changed
cmp esi,[ebp-DATETIME_size+DATETIME_Time] ; check time
jne GetCMOSTime4 ; change, try again
cmp ebx,[ebp-DATETIME_size+DATETIME_Date] ; check date
jne GetCMOSTime4 ; change, try again
; ------------- Convert system time to absolute time
mov ebx,esp ; EBX <- DATETIME buffer in stack
call DateTimeToAbs ; convert date-time to absolute time
clc ; clear error flag
jmp short GetCMOSTime8
; ------------- Next attempt
GetCMOSTime4: mov esi,[ebp-DATETIME_size+DATETIME_Time] ; ESI <- get time
mov ebx,[ebp-DATETIME_size+DATETIME_Date] ; EBX <- get date
GetCMOSTime6: loop GetCMOSTime2 ; next attempt
; ------------- Error
xor eax,eax ; EAX <- 0
xor edx,edx ; EDX <- 0
stc ; set error flag
; ------------- Pop registers
GetCMOSTime8: mov esp,ebp ; EPS <- return stack
pop ebp ; pop EBP
pop esi ; pop ESI
pop ecx ; pop ECX
pop ebx ; pop EBX
ret
|
Funkce GetCMOSTime
je funkce k načtení aktuálního času z paměti CMOS.
Navrátí v registrech EDX:EAX aktuální čas v absolutním
formátu (tj. počet 100-nsec od 0:00:00 1.1.1). V případě
chyby (položky data a času jsou v paměti CMOS v neplatném
tvaru) je navrácen příznak CY a obsah registrů EDX:EAX je
nulový. Funkce zajistí čekání na ukončení aktualizace
hodin a může trvat od 40 mikrosekund do 10 milisekund. Jsou
používány funkce ovladače paměti CMOS, které si samy
zajistí uzamknutí zámku ovladače. Proto může být funkce
volána s povoleným přerušením, má-li být povolena obsluha
přerušení během průběhu funkce.
Funkce opakovaně
načítá čas pomocí funkce CMOSGetTime, dokud není načten
bez chyby nebo není proveden dostatečný počet pokusů (=256)
odpovídající zhruba 10 ms. V případě úspěšného
načtení času (tj. položky v CMOS jsou platné a neprobíhá
aktualizace času) je čas porovnán z předešlou hodnotou. Čas
je považován za platný pouze v případě, že je 2x načten
stejný údaj. V tom případě se zkonvertuje na absolutní
formát.
; -----------------------------------------------------------------------------
; CMOS global function: Write CMOS time
; -----------------------------------------------------------------------------
; INPUT: EDX:EAX = absolute time (100-nanoseconds from 1/1/1 CE 0:00)
; OUTPUT: CY = error
; NOTES: Function takes aprox. 50 us.
; Next time increment begins 0.5 sec later.
; -----------------------------------------------------------------------------
; ------------- Push registers
SetCMOSTime: push ebx ; push EBX
push edx ; push EDX
push ebp ; push EBP
mov ebp,esp ; EBP <- local variables
sub esp,DATETIME_size ; buffer for date-time structure
; ------------- Convert absolute time to DATETIME
mov ebx,esp ; EBX <- DATETIME buffer in stack
call AbsToDateTime ; convert absolute time to date-time
; ------------- Write date and time to CMOS memory
mov edx,esp ; EDX <- DATETIME buffer in stack
call CMOSSetTime ; write date and time to CMOS memory
; ------------- Pop registers
mov esp,ebp ; EPS <- return stack
pop ebp ; pop EBP
pop edx ; pop EDX
pop ebx ; pop EBX
ret
|
Funkce SetCMOSTime
je funkce k zápisu aktuálního času do paměti CMOS. Na vstupu
obsahují registry EDX:EAX aktuální čas v absolutním formátu
(tj. počet 100-nsec od 0:00:00 1.1.1). V případě chyby je
navrácen příznak CY. Funkce trvá přibližně 50 mikrosekund.
První inkrementace času nastane 0,5 sekundy po zápisu času -
při přesné synchronizaci času je proto potřeba čas nastavit
v době za 0,5 sekundy po uběhnutí požadovaného času.
; -----------------------------------------------------------------------------
; CMOS global function: Read CMOS alarm
; -----------------------------------------------------------------------------
; OUTPUT: EDX:EAX = absolute time (100-nanoseconds from 1/1/1 CE 0:00)
; ECX = flags (ALARM_ENABLED, ...)
; CY = error (EDX:EAX = 0)
; NOTES: It takes aprox. 20 us.
; -----------------------------------------------------------------------------
; ------------- Push registers
GetCMOSAlarm: push ebx ; push EBX
push ebp ; push EBP
mov ebp,esp ; EBP <- local variables
sub esp,DATETIME_size ; buffer for date-time structure
; ------------- Read alarm from CMOS
mov edx,esp ; EDX <- DATETIME buffer in stack
call CMOSGetAlarm ; read alarm
xchg eax,ecx ; ECX <- flags
; ------------- Convert system time to absolute time
mov ebx,esp ; EBX <- DATETIME buffer in stack
pushf ; push flags (CY = error)
call DateTimeToAbs ; convert date-time to absolute time
popf ; pop flags (CY = error)
; ------------- Pop registers
mov esp,ebp ; EPS <- return stack
pop ebp ; pop EBP
pop ebx ; pop EBX
ret
|
Funkce GetCMOSAlarm
je funkce k načtení alarmu z paměti CMOS. Navrátí v
registrech EDX:EAX čas alarmu v absolutním formátu (tj. počet
100-nsec od 0:00:00 1.1.1). V registru ECX jsou navráceny
příznaky (ALARM_ENABLED, ...). V případě chyby funkce vrací
příznak CY a čas EDX:EAX = 0. Funkce trvá přibližně 20
mikrosekund.
; -----------------------------------------------------------------------------
; CMOS global function: Write CMOS alarm
; -----------------------------------------------------------------------------
; INPUT: EDX:EAX = absolute time (100-nanoseconds from 1/1/1 CE 0:00)
; ECX = flags (ALARM_ENABLED, ...)
; OUTPUT: CY = error
; NOTES: Function takes aprox. 20 us.
; -----------------------------------------------------------------------------
; ------------- Push registers
SetCMOSAlarm: push ebx ; push EBX
push edx ; push EDX
push ebp ; push EBP
mov ebp,esp ; EBP <- local variables
sub esp,DATETIME_size ; buffer for date-time structure
; ------------- Convert absolute time to DATETIME
mov ebx,esp ; EBX <- DATETIME buffer in stack
call AbsToDateTime ; convert absolute time to date-time
; ------------- Write alarm to CMOS memory
xchg eax,ecx ; EAX <- flags, ECX <- time LOW
mov edx,esp ; EDX <- DATETIME buffer in stack
call CMOSSetAlarm ; write alarm to CMOS memory
xchg eax,ecx ; return EAX and ECX
; ------------- Pop registers
mov esp,ebp ; EPS <- return stack
pop ebp ; pop EBP
pop edx ; pop EDX
pop ebx ; pop EBX
ret
|
Funkce SetCMOSAlarm
je funkce k zápisu alarmu do paměti CMOS. Na vstupu obsahují
registry EDX:EAX čas alarmu v absolutním formátu (tj. počet
100-nsec od 0:00:00 1.1.1). Registr ECX obsahuje příznaky
(ALARM_ENABLED,...). V případě chyby je navrácen příznak
CY. Funkce trvá přibližně 20 mikrosekund.
Obsah / Ovladače / CMOS / Globální funkce ovladače paměti CMOS