1128707Sru/*
2128707Sru * Copyright (c) 1998 Robert Nordier
3128707Sru * All rights reserved.
4128707Sru *
5128707Sru * Redistribution and use in source and binary forms are freely
6128707Sru * permitted provided that the above copyright notice and this
7128707Sru * paragraph and the following disclaimer are duplicated in all
8128707Sru * such forms.
9128707Sru *
10128707Sru * This software is provided "AS IS" and without any express or
11128707Sru * implied warranties, including, without limitation, the implied
12128707Sru * warranties of merchantability and fitness for a particular
13128707Sru * purpose.
14128707Sru *
15128707Sru * $FreeBSD$
16128707Sru */
17125932Sru
18129240Sru		.set SIO_PRT,SIOPRT		# Base port
19129240Sru		.set SIO_FMT,SIOFMT		# 8N1
20125932Sru
21125932Sru		.globl sio_init
22125932Sru		.globl sio_flush
23125932Sru		.globl sio_putc
24125932Sru		.globl sio_getc
25125932Sru		.globl sio_ischar
26125932Sru
27242562Savg/* int sio_init(int div) */
28125932Sru
29220337Srdivackysio_init:	pushl %eax
30220337Srdivacky		movw $SIO_PRT+0x3,%dx		# Data format reg
31129240Sru		movb $SIO_FMT|0x80,%al		# Set format
32129240Sru		outb %al,(%dx)			#  and DLAB
33129240Sru		subb $0x3,%dl			# Divisor latch reg
34220337Srdivacky		popl %eax
35129240Sru		outw %ax,(%dx)			#  BPS
36220337Srdivacky		movw $SIO_PRT+0x3,%dx		# Data format reg
37129240Sru		movb $SIO_FMT,%al		# Clear
38129240Sru		outb %al,(%dx)			#  DLAB
39129240Sru		incl %edx			# Modem control reg
40129240Sru		movb $0x3,%al			# Set RTS,
41129240Sru		outb %al,(%dx)			#  DTR
42129240Sru		incl %edx			# Line status reg
43242907Sdim		# Fallthrough
44125932Sru
45242562Savg/* int sio_flush(void) */
46125932Sru
47242907Sdimsio_flush:	xorl %ecx,%ecx			# Timeout
48242562Savg		movb $0x80,%ch			#  counter
49242562Savgsio_flush.1:	call sio_ischar 		# Check for character
50242562Savg		jz sio_flush.2			# Till none
51242562Savg		loop sio_flush.1		#  or counter is zero
52242562Savg		movb $1, %al			# Exhausted all tries
53242562Savgsio_flush.2:	ret				# To caller
54125932Sru
55128707Sru/* void sio_putc(int c) */
56125932Sru
57220337Srdivackysio_putc:	pushl %eax
58220337Srdivacky		movw $SIO_PRT+0x5,%dx		# Line status reg
59129240Sru		xor %ecx,%ecx			# Timeout
60129240Sru		movb $0x40,%ch			#  counter
61129240Srusio_putc.1:	inb (%dx),%al			# Transmitter
62129240Sru		testb $0x20,%al 		#  buffer empty?
63129240Sru		loopz sio_putc.1		# No
64129240Sru		jz sio_putc.2			# If timeout
65220337Srdivacky		popl %eax                       # Get the character
66129240Sru		subb $0x5,%dl			# Transmitter hold reg
67129240Sru		outb %al,(%dx)			# Write character
68220337Srdivackysio_putc.2:	ret				# To caller
69125932Sru
70128707Sru/* int sio_getc(void) */
71125932Sru
72129240Srusio_getc:	call sio_ischar 		# Character available?
73129240Sru		jz sio_getc			# No
74129240Srusio_getc.1:	subb $0x5,%dl			# Receiver buffer reg
75129240Sru		inb (%dx),%al			# Read character
76129240Sru		ret				# To caller
77125932Sru
78128707Sru/* int sio_ischar(void) */
79125932Sru
80129240Srusio_ischar:	movw $SIO_PRT+0x5,%dx		# Line status register
81129240Sru		xorl %eax,%eax			# Zero
82129240Sru		inb (%dx),%al			# Received data
83129240Sru		andb $0x1,%al			#  ready?
84129240Sru		ret				# To caller
85