summaryrefslogtreecommitdiff
path: root/usr/src/boot/i386/gptzfsboot/sio.S
blob: 27c25006b241d023859d04eaea1e31e7313e43c0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/*
 * Copyright (c) 1998 Robert Nordier
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are freely
 * permitted provided that the above copyright notice and this
 * paragraph and the following disclaimer are duplicated in all
 * such forms.
 *
 * This software is provided "AS IS" and without any express or
 * implied warranties, including, without limitation, the implied
 * warranties of merchantability and fitness for a particular
 * purpose.
 */

		.set SIO_FMT,SIOFMT		# 8N1

/* int sio_port */
sio_port:	.long SIOPRT			# Base port

		.globl sio_port
		.globl sio_init
		.globl sio_flush
		.globl sio_putc
		.globl sio_getc
		.globl sio_ischar

/* int sio_init(int div) */

sio_init:	pushl %eax
		movl (sio_port),%edx
		addl $0x3,%edx			# Data format reg
		movb $SIO_FMT|0x80,%al		# Set format
		outb %al,(%dx)			#  and DLAB
		subb $0x3,%dl			# Divisor latch reg
		popl %eax
		outw %ax,(%dx)			#  BPS
		movl (sio_port),%edx
		addl $0x3,%edx			# Data format reg
		movb $SIO_FMT,%al		# Clear
		outb %al,(%dx)			#  DLAB
		incl %edx			# Modem control reg
		movb $0x3,%al			# Set RTS,
		outb %al,(%dx)			#  DTR
		incl %edx			# Line status reg
		# Fallthrough

/* int sio_flush(void) */

sio_flush:	xorl %ecx,%ecx			# Timeout
		movb $0x80,%ch			#  counter
sio_flush.1:	call sio_ischar 		# Check for character
		jz sio_flush.2			# Till none
		loop sio_flush.1		#  or counter is zero
		movb $1, %al			# Exhausted all tries
sio_flush.2:	ret				# To caller

/* void sio_putc(int c) */

sio_putc:	pushl %eax
		movl (sio_port),%edx
		addl $0x5,%edx			# Line status reg
		xor %ecx,%ecx			# Timeout
		movb $0x40,%ch			#  counter
sio_putc.1:	inb (%dx),%al			# Transmitter
		testb $0x20,%al 		#  buffer empty?
		loopz sio_putc.1		# No
		jz sio_putc.2			# If timeout
		popl %eax                       # Get the character
		subb $0x5,%dl			# Transmitter hold reg
		outb %al,(%dx)			# Write character
sio_putc.2:	ret				# To caller

/* int sio_getc(void) */

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				# To caller

/* int sio_ischar(void) */

sio_ischar:	movl (sio_port),%edx
		addl $0x5,%edx			# Line status register
		xorl %eax,%eax			# Zero
		inb (%dx),%al			# Received data
		andb $0x1,%al			#  ready?
		ret				# To caller