.set SIO_PRT,SIOPRT # Base port
.set SIO_FMT,SIOFMT # 8N1
.set SIO_DIV,(115200/SIOSPD) # 115200 / SPD
.globl sio_init
.globl sio_flush
.globl sio_putc
.globl sio_getc
.globl sio_ischar
sio_init: movw $SIO_PRT+0x3,%dx # Data format reg
movb $SIO_FMT|0x80,%al # Set format and DLAB
outb %al,(%dx) # BASE+3
subb $0x3,%dl
movw $SIO_DIV,%ax # divisor
outw %ax,(%dx) # BASE+0 (divisor w/ DLAB set)
movw $SIO_PRT+0x2,%dx
movb $0x01,%al # Enable FIFO
# BASE+2
incl %edx
movb $SIO_FMT,%al # Clear DLAB
outb %al,(%dx) # BASE+3
incl %edx
movb $0x3,%al # RTS+DTR
outb %al,(%dx) # BASE+4
incl %edx # BASE+5 Line status reg
sio_flush: movb $1,%ch # let %cl be garbage
1: call sio_getc.1
call sio_ischar
loopnz 1b
ret
sio_putc: movw $SIO_PRT+0x5,%dx # Line status reg
movb $0x40,%ch # Timeout counter. Allow %cl
sio_putc.1: inb (%dx),%al # Transmitter buffer empty?
testb $0x20,%al
loopz sio_putc.1 # No
jz sio_putc.2 # If timeout
movb 0x4(%esp,1),%al # Get character
subb $0x5,%dl # Transmitter hold reg
outb %al,(%dx) # Write character
sio_putc.2: ret
sio_getc: call sio_ischar # Character available?
jz sio_getc # No
sio_getc.1: subb $0x5,%dl # Receiver buffer reg
inb (%dx),%al # Read character
ret
sio_ischar: movw $SIO_PRT+0x5,%dx # Line status register
xorl %eax,%eax # Zero
inb (%dx),%al # Received data ready?
andb $0x1,%al
ret
.globl inbser
inbser: movw $SIO_PRT+5,%dx
inb (%dx),%al
ret