//------------------------------------------------------------------ // uartecho.s // // This program is for testing a "null-modem" cable-connection // between a pair of adjacent PCs in our classroom. First you // start this program running on one PC, and then you launch a // modified version of our 'testuart.s' application on a PC at // the other end of the cable. The modification just consists // of putting a zero-value into the MODEM_CONTROL register, to // disable the UART's 'loopback' mode. You can terminate this // program by typing -C. // // to assemble: $ as uartecho.s -o uartecho.o // and to link: $ ld uartecho.o -o uartecho // // (NOTE: Remember to execute the 'iopl3' command beforehand!) // // programmer: ALLAN CRUSE // written on: 04 APR 2007 //------------------------------------------------------------------ # manifest constants .equ sys_WRITE, 4 .equ STDOUT, 1 .equ UART, 0x03F8 .equ LINE_CONTROL, UART+3 .equ DIVISOR_LATCH, UART+0 .equ MODEM_CONTROL, UART+4 .equ LINE_STATUS, UART+5 .equ TX_DATA, UART+0 .equ RX_DATA, UART+0 .section .data msg: .ascii "\nHit -C to termine this program\n\n" len: .int . - msg inch: .byte 0 .section .text _start: # configure the UART's operational parameters mov $LINE_CONTROL, %dx mov $0x80, %al # access Divisor-Latch out %al, %dx mov $DIVISOR_LATCH, %dx mov $0x0001, %ax # set baudrate: 115200 out %ax, %dx mov $LINE_CONTROL, %dx mov $0x03, %al # set data-format: 8-N-1 out %al, %dx mov $MODEM_CONTROL, %dx mov $0x00, %al # disable 'loopback' mode out %al, %dx # tell the user how to terminate this application mov $sys_WRITE, %eax mov $STDOUT, %ebx lea msg, %ecx mov len, %edx int $0x80 # an infinite loop that sends back every byte it receives again: # wait until the UART's has received a new byte of data mov $LINE_STATUS, %dx spin2: in %dx, %al test $0x01, %al jz spin2 # read the new character from the UART's RX_DATA register mov $RX_DATA, %dx in %dx, %al mov %al, inch # show the received character on the screen mov $sys_WRITE, %eax mov $STDOUT, %ebx lea inch, %ecx mov $1, %edx int $0x80 # wait until the UART's Transmit Holding Register is empty mov $LINE_STATUS, %dx spin1: in %dx, %al test $0x20, %al jz spin1 # transmit the received character back to the sender mov inch, %al mov $TX_DATA, %dx out %al, %dx jmp again .global _start .end