ASM System Time
ASM System Time
Hey, it's my first time back here in a long time, but hopefully I'll be on more often. Anyways, is there an easy to get the time from the bios using intel assembly? Thanks in advance.
NULL
-
- Member
- Posts: 190
- Joined: Tue Sep 26, 2006 1:40 pm
- Libera.chat IRC: Nokurn
- Location: Ontario, CA, USA
- Contact:
Read these indexes from the CMOS:
Convert them from binary-coded decimal to binary and store them in variables.
Reading the CMOS:
The BCD is now in AL.
Converting from BCD to binary: Sorry, you'll just have to translate this C macro, I'm in a hurry right now.
p.s. Some of this code might be incorrect, as stated above, I'm in a rush.
Code: Select all
Second = 0x00
Minute = 0x02
Hour = 0x04
Day = 0x07
Month = 0x08
Year = 0x09
Century = 0x32
Reading the CMOS:
Code: Select all
mov dx, 0x70
mov al, IDX
out dx, al
mov dx, 0x71
in al, dx
Converting from BCD to binary: Sorry, you'll just have to translate this C macro, I'm in a hurry right now.
Code: Select all
#define BCD2BIN(val) (((val) & 0x0F) + ((val) >> 4) * 10)
So, I tried this code:
Which should return the hour, right? but nothing happened.
Code: Select all
_get_time:
mov dx, 0x70
mov al, 0x04
out dx, al
mov dx, 0x71
in al, dx
int 0x021
ret
NULL
Hi,
Some more notes:
Cheers,
Brendan
What is the int 0x21 there for?Bobalandi wrote:Which should return the hour, right? but nothing happened.Code: Select all
_get_time: mov dx, 0x70 mov al, 0x04 out dx, al mov dx, 0x71 in al, dx int 0x021 ret
Some more notes:
- - It's theoretically possible for the RTC to be set to "binary" mode or "BCD mode", and also theoretically possible for the RTC to be set to "12-hour mode" or "24-hour mode". This means that at 11:00 in the afternoon the hour value may be 0x91 (BCD, 12-hour), 0x8B *binary, 12-hour), 0x23 (BCD, 24-hour) or 0x17 (Binary, 24-hour). Check CMOS register 0x0B to find out which mode the RTC is in.
- You should have some sort of re-entrancy lock around this code, so that other code can't change the CMOS index before you read from the CMOS data.
- All good OSs expect the RTC to be set to UTC. Unfortunately, badly designed OSs (Windows) expect the RTC to be set to Standard Time. This means you won't know which time the RTC is set to, and if the RTC is set to Standard Time you won't know if another OS has adjusted it for daylight savings or not (which is one of the reasons why good OSs use UTC).
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
This will give you the time in realmode
The above code is coded with nasm.
Here is some code from DexOS, that has the full time/date functions written in fasm, but you will need to add your own print char function etc.
Code: Select all
org 100h
segment .text
mov ah,01h ; from here to
mov cx,2000h ; ,,,,,,,,,,,,,
int 10h ; here, hide's cursor(bios int's)
m0:
mov ah,2 ; get's the (bios int's)
int 1ah ; time in BCD , dl=0
push cx
push dx
pop eax
m1:
mov al,163
sub dl,160 ; gives c,c,nc,c,c,nc,c,nc+z
ja $+3 ; h h : m m : s s
rol eax,4 ; if jump is taken, we're in the middle of this.
push ax
mov ah,0eh
int 10h
pop ax
jne m1
mov al,13 ; CR to re-position cursor - looks crappy.
mov ah,0eh
int 10h
; mov ah,1 ; until key is pressed
; int 16h
; jz m0
mov ah,01h ; here to
mov cx,0d0eh ; ,,,,,,,,
int 10h ; here show cursor (bios int's)
ret
Here is some code from DexOS, that has the full time/date functions written in fasm, but you will need to add your own print char function etc.
Code: Select all
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Project : DexOS ;;
;; Ver : 00.01 ;;
;; Author : Dex ;;
;; Website : www.dex4u.com ;;
;; Forum : http://jas2o.forthworks.com/dexforum/ ;;
;; wiki : http://tonymac.asmhackers.net/Wiki/pmwiki.php ;;
;; Date : October 31, 2006 ;;
;; Filename : TimeDate.inc ;;
;; Assembler Command: ********** ;;
;; Copy Right Owners: Team DexOS (c)2002-2007 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Team DexOS : 0x4e71, bubach, crc, Dex, hidnplayr, jas2o, Solidus ;;
;; : smiddy, tony(mac), roboman, viki. ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Disclaimer : ;;
;; This software is provided "AS IS" without warranty of any kind, either ;;
;; expressed or implied, including, but not limited to, the implied ;;
;; warranties of merchantability and fitness for a particular purpose. The ;;
;; entire risk as to the quality and performance of this software is with ;;
;; you. ;;
;; In no event will the author's, distributor or any other party be liable to ;;
;; you for damages, including any general, special, incidental or ;;
;; consequential damages arising out of the use, misuse or inability to use ;;
;; this software (including but not limited to loss of data or losses ;;
;; sustained by you or third parties or a failure of this software to operate ;;
;; with any other software), even if such party has been advised of the ;;
;; possibility of such damages. ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;----------------------------------------------------;
; date ; fills vals with bcd date ;
;----------------------------------------------------;
; ;
; Input: ;
; none. ;
; Output: ;
; Puts bcd date in vals: ;
; century, year, month, day. ;
; (100%) ;
;....................................................;
date:
push ds es
pusha
cli
mov al,32h ; RTC 32h
out 70h,al
in al,71h ; read century
mov [century],al
mov al,9 ; RTC 09h
out 70h,al
in al,71h ; read year
mov [year],al
mov al,8 ; RTC 08h
out 70h,al
in al,71h ; read month
mov [month],al
mov al,7 ; RTC 07h
out 70h,al
in al,71h ; read day
mov [day],al
sti
popa
pop es ds
ret
;====================================================;
; FloppyDate. ;
;====================================================;
FloppyDate:
pushad
push es
push ds
mov ax,18h
mov ds,ax
mov es,ax
call date
xor bx,bx
mov dx,bx
mov ax,bx
mov al,[year]
call Bcd2Bin
add al,20
mov dx,ax
shl dx,4
mov al,[month]
call Bcd2Bin
and al,00001111b
add dl,al
shl dx,5
mov al,[day]
call Bcd2Bin
and ax,0000000000011111b
add dx,ax
mov [FddDate],dx
pop ds
pop es
popad
ret
;====================================================;
; FloppyTime. ;
;====================================================;
FloppyTime:
pushad
push es
push ds
mov ax,18h
mov ds,ax
mov es,ax
call time
xor bx,bx
mov dx,bx
mov ax,bx
mov al,[hour]
call Bcd2Bin
mov dx,ax
shl dx,6
mov al,[minute]
call Bcd2Bin
and al,00111111b
add dl,al
shl dx,5
mov al,[second]
shr al,1
call Bcd2Bin
and ax,0000000000011111b
add dx,ax
mov [FddTime],dx
pop ds
pop es
popad
ret
;----------------------------------------------------;
; prints date ; prints the date in text mode ;
;----------------------------------------------------;
; ;
; Input: ;
; none. ;
; Output: ;
; prints the date in text mode. ;
; (100%) ;
;....................................................;
print_date:
push es
pusha
mov esi,date_lable
call print_string
call date
mov al,[day]
call bcd_to_ASCII
mov bx,[val]
mov al,bl
call print_char
mov al,bh
call print_char
mov al,":"
call print_char
mov al,[month]
call bcd_to_ASCII
mov bx,[val]
mov al,bl
call print_char
mov al,bh
call print_char
mov al,":"
call print_char
mov al,[century]
call bcd_to_ASCII
mov bx,[val]
mov al,bl
call print_char
mov al,bh
call print_char
mov al,[year]
call bcd_to_ASCII
mov bx,[val]
mov al,bl
call print_char
mov al,bh
call print_char
popa
pop es
ret
;----------------------------------------------------;
; time ; fills vals with bcd time ;
;----------------------------------------------------;
; ;
; Input: ;
; none. ;
; Output: ;
; Puts bcd time in vals: ;
; hour, minute, second. ;
; (100%) ;
;....................................................;
time:
push ds es
pusha
cli
mov al,4 ; RTC 04h
out 70h,al
in al,71h ; read hour
mov [hour],al
mov al,2 ; RTC 02h
out 70h,al
in al,71h ; read minute
mov [minute],al
xor al,al ; RTC 00h
out 70h,al
in al,71h ; read second
mov [second],al
sti
popa
pop es ds
ret
;----------------------------------------------------;
; prints time ; prints the time in text mode ;
;----------------------------------------------------;
; ;
; Input: ;
; none. ;
; Output: ;
; prints the time in text mode. ;
; (100%) ;
;....................................................;
print_time:
push es
pusha
mov esi,time_lable
call print_string
call time
mov al,[hour]
call bcd_to_ASCII
mov bx,[val]
mov al,bl
call print_char
mov al,bh
call print_char
mov al,":"
call print_char
mov al,[minute]
call bcd_to_ASCII
mov bx,[val]
mov al,bl
call print_char
mov al,bh
call print_char
mov al,":"
call print_char
mov al,[second]
call bcd_to_ASCII
mov bx,[val]
mov al,bl
call print_char
mov al,bh
call print_char
popa
pop es
ret
;----------------------------------------------------;
; set time ; set's time from vals ;
;----------------------------------------------------;
; ;
; Input: ;
; Bcd time in vals. ;
; Output: ;
; Prints ERROR msg on error. ;
; (70%) ;
;....................................................;
set_time:
push ds es
pusha
cli
mov bl,59h
mov al,[second]
call check_bcd_time ; check second number
mov al,[minute]
call check_bcd_time ; check minute number
mov bl,23h
mov al,[hour]
call check_bcd_time ; check hour number
xor al,al ; RTC 00h
out 70h,al
mov al,[second]
out 71h,al ; write second
mov al,2 ; RTC 02h
out 70h,al
mov al,[minute]
out 71h,al ; write minute
mov al,4 ; RTC 04h
out 70h,al
mov al,[hour]
out 71h,al ; write hour
jmp leave1
time_error:
mov esi,time_error_msg
call print_string
leave1:
sti
popa
pop es ds
ret
;----------------------------------------------------;
; set date ; set's date from vals ;
;----------------------------------------------------;
; ;
; Input: ;
; Bcd date in vals. ;
; Output: ;
; Prints ERROR msg on error. ;
; (70%) ;
;....................................................;
set_date:
push ds es
pusha
cli
mov al,[day]
mov bl,31h
or al,al ; day cannot be 0
jz date_error
call check_bcd_date ; check day number
mov bl,12h
mov al,[month]
or al,al ; month cannot be 0
jz date_error
call check_bcd_date ; check month number
mov bl,99h
mov al,[year]
call check_bcd_date ; check year number
mov al,[century]
call check_bcd_date ; check century number
mov al,7 ; RTC 07h
out 70h,al
mov al,[day]
out 71h,al ; write day
mov al,8 ; RTC 08h
out 70h,al
mov al,[month]
out 71h,al ; write month
mov al,9 ; RTC 09h
out 70h,al
mov al,[year]
out 71h,al ; write year
mov al,32h ; RTC 32h
out 70h,al
mov al,[century]
out 71h,al ; write century
jmp leave2
date_error:
mov esi,date_error_msg
call print_string
leave2:
sti
popa
pop es ds
ret
;----------------------------------------------------;
; bcd_to_ASCII ;converts bcd number to ASCII ;
;----------------------------------------------------;
; ;
; Input: ;
; Bcd number in al. ;
; Output: ;
; ASCII number in val. ;
; (100%) ;
;....................................................;
bcd_to_ASCII:
pusha ;start of convert
mov ah,al ;copy AL to AH
and ax,0f00fh ;mask bits
mov cl,4 ;CL=04 for shift
shr ah,cl ;shift right AH to get unpacked BCD
or ax, 3030h ;combine with 30 to get ASCII
xchg ah,al ;swap for ASCII storage convention
mov [val],ax ;store the ASCII value in VAL
popa
ret
;----------------------------------------------------;
; checks it a bcd number date ;
;----------------------------------------------------;
check_bcd_date:
cmp al,bl
ja date_error
and al,0Fh
cmp al,9
ja date_error
ret
;----------------------------------------------------;
; checks it a bcd number time ;
;----------------------------------------------------;
check_bcd_time:
cmp al,bl
ja time_error
and al,0Fh
cmp al,9
ja time_error
ret
;====================================================;
; Bcd2Bin. ;
;====================================================;
Bcd2Bin:
push bx
mov bl,0x0a
mov bh,al
shr al,4
mul bl
and bh,0x0f
add al,bh
pop bx
ret
;----------------------------------------------------;
; Data. ;
;----------------------------------------------------;
time_lable: db " Time ",0
date_lable: db " Date ",0
val: dw 0,0
hour: db 0
minute: db 0
second: db 0
century: db 0
year: db 0
month: db 0
day: db 0
FddDate dw 0
FddTime dw 0