kernel/src/serial.asm

89 lines
1.3 KiB
NASM

SERIAL_PORT equ 0x3f8
serialinitialized db 0
serialinit:
push ax
;Disable ints
mov dx, SERIAL_PORT+1
mov al, 0x00
out dx, al
;Enable DLAB baud divisor and set 3 (38400 baud)
mov al, 0x80
mov dx, SERIAL_PORT+3
out dx, al
;Baud divisor lo byte
mov al, 0x03
mov dx, SERIAL_PORT
out dx, al
;Baud divisor hi byte
mov al, 0x00
mov dx, SERIAL_PORT+1
out dx, al
;8bits, no parity, one stop bit
mov al, 0x03
mov dx, SERIAL_PORT+3
out dx, al
;Enable+clear FIFO, 14-byte threshold
mov al, 0xc7
mov dx, SERIAL_PORT+2
out dx, al
;IRQs enabled, RTS/DSR set
mov al, 0x0b
mov dx, SERIAL_PORT+4
out dx, al
;Set loopback for test purposes
mov al, 0x1e
out dx, al
;; Check if serial is workie
mov al, 0xae
mov dx, SERIAL_PORT
out dx, al
in al, dx
cmp al, 0xae
jne .end
;; Set serial to normal operation
mov dx, SERIAL_PORT+4
mov al, 0x0f
out dx, al
mov [serialinitialized], 1
.end:
pop ax
ret
.errormsg db "Serial init failed", 0
serialwrite:
cmp [serialinitialized], 0
je .notinitialized
push ebp
mov ebp, esp
push esi
push ax
cld
mov esi, [ebp+8]
.loop:
mov dx, SERIAL_PORT+5
.wait:
in al, dx
and al, 0x20
jz .wait
lodsb
or al, al
jz .done
mov dx, SERIAL_PORT
out dx, al
jmp .loop
.done:
pop ax
pop esi
pop ebp
ret
.notinitialized:
ret