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: releng/11.0/sys/boot/i386/boot2/sio.S 242804 2012-11-08 23:21:02Z dim $ 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 27241301Savg/* 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 43242804Sdim # Fallthrough 44125932Sru 45241301Savg/* int sio_flush(void) */ 46125932Sru 47242804Sdimsio_flush: xorl %ecx,%ecx # Timeout 48241301Savg movb $0x80,%ch # counter 49241301Savgsio_flush.1: call sio_ischar # Check for character 50241301Savg jz sio_flush.2 # Till none 51241301Savg loop sio_flush.1 # or counter is zero 52241301Savg movb $1, %al # Exhausted all tries 53241301Savgsio_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