162 lines
2.1 KiB
NASM
162 lines
2.1 KiB
NASM
bits 64
|
|
|
|
section .rodata
|
|
|
|
section .text
|
|
|
|
read_cmos_byte:
|
|
;dil in = register number
|
|
;al out = value
|
|
;rdx and rcx are not touched
|
|
|
|
mov al, dil
|
|
out 0x70, al
|
|
in al, 0x71
|
|
ret
|
|
|
|
global enable_rtc_interrupts
|
|
enable_rtc_interrupts:
|
|
|
|
;secondary status register
|
|
mov dil, 11
|
|
call read_cmos_byte
|
|
|
|
;enable interrupts
|
|
or al, 0x40
|
|
mov cl, al
|
|
|
|
;do cmos write
|
|
mov al, 11
|
|
out 0x70, al
|
|
mov al, cl
|
|
out 0x71, al
|
|
|
|
ret
|
|
|
|
global acknowledge_rtc_interrupt
|
|
acknowledge_rtc_interrupt:
|
|
mov dil, 12
|
|
jmp read_cmos_byte
|
|
|
|
convert_bcd:
|
|
;al in = byte (possibly bcd)
|
|
;al out = byte (not bcd)
|
|
;sil 0x02 = bcd
|
|
;does not touch rdx, rcx, sil
|
|
test sil, 0x02
|
|
jz .no_convert
|
|
|
|
mov dil, al
|
|
and dil, 0xf0
|
|
and al, 0x0f
|
|
shr dil, 3
|
|
add al, dil
|
|
shl dil, 2
|
|
add al, dil
|
|
|
|
.no_convert:
|
|
ret
|
|
|
|
convert_hours:
|
|
;al in = byte (possibly bcd and 12 hour)
|
|
;al out = byte (not bcd or 12 hour)
|
|
;sil 0x02 = bcd, sil 0x01 = 12 hour
|
|
;does not touch rdx, rcx, sil
|
|
test sil, 0x01
|
|
jz convert_bcd
|
|
|
|
test al, 0x80
|
|
jz .am
|
|
|
|
and al, 0x7f
|
|
call convert_bcd
|
|
cmp al, 12
|
|
je .noon
|
|
|
|
add al, 12
|
|
ret
|
|
|
|
.noon:
|
|
ret
|
|
|
|
.am:
|
|
call convert_bcd
|
|
cmp al, 12
|
|
je .midnight
|
|
|
|
ret
|
|
|
|
.midnight:
|
|
xor al, al
|
|
ret
|
|
|
|
global get_time_from_rtc
|
|
get_time_from_rtc:
|
|
;rax out = time (see timer.cpp for encoding)
|
|
;we assume the year is 20xx (sorry)
|
|
|
|
mov dil, 11
|
|
call read_cmos_byte
|
|
|
|
shr al, 1
|
|
not al
|
|
and al, 3
|
|
mov sil, al
|
|
|
|
xor rdx, rdx
|
|
|
|
.outer_loop:
|
|
mov rcx, rdx
|
|
|
|
.wait_for_update_loop:
|
|
;status register - 0x80 is update in progress
|
|
mov dil, 10
|
|
call read_cmos_byte
|
|
test al, 0x80
|
|
jnz .wait_for_update_loop
|
|
|
|
;years
|
|
mov dil, 9
|
|
call read_cmos_byte
|
|
call convert_bcd
|
|
mov dh, al
|
|
|
|
;months
|
|
mov dil, 8
|
|
call read_cmos_byte
|
|
call convert_bcd
|
|
mov dl, al
|
|
|
|
shl edx, 16
|
|
|
|
;days
|
|
mov dil, 7
|
|
call read_cmos_byte
|
|
call convert_bcd
|
|
mov dh, al
|
|
|
|
;hours
|
|
mov dil, 4
|
|
call read_cmos_byte
|
|
call convert_hours
|
|
mov dl, al
|
|
|
|
shl rdx, 16
|
|
|
|
;minutes
|
|
mov dil, 2
|
|
call read_cmos_byte
|
|
call convert_bcd
|
|
mov dh, al
|
|
|
|
;seconds
|
|
xor dil, dil
|
|
call read_cmos_byte
|
|
call convert_bcd
|
|
mov dl, al
|
|
|
|
cmp rdx, rcx
|
|
jne .outer_loop
|
|
|
|
mov rax, rdx
|
|
ret
|