diff options
Diffstat (limited to 'kernel/source/timer.asm')
-rw-r--r-- | kernel/source/timer.asm | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/kernel/source/timer.asm b/kernel/source/timer.asm new file mode 100644 index 0000000..d5f6f73 --- /dev/null +++ b/kernel/source/timer.asm @@ -0,0 +1,162 @@ +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 |