Article View: comp.os.msdos.programmer
Article #6443H E L P!!! Serial Communications Blues... (UART).
From: gardner
Date: Thu, 19 Nov 1992 19:33
Date: Thu, 19 Nov 1992 19:33
301 lines
8282 bytes
8282 bytes
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Hello,
;
;I was torn about whether to ZOO and UUENCODE the following little program,
;but I really need help and didn't want to proclude anyone from assisting by
;requiring special software tools. So, to those of you who are upset by my
;loading a 5K file with this message, I apologize.
;
;Now, for the question...
;
; I am teaching myself about the 8250 UART and am having problems doing
; somthing that "appears" to be very easy... All I want to do is create
; a TSR (no problem) that is kicked every time a byte arrives in COM2.
; The interrupt service routine that is invoked by the 0BH (COM2) vector
; will retrieve the byte from the RECEIVER REGISTER and display it directly
; to video memory (I've implemented the video code but haven't tested it).
;
; The program that follows is my attempt at doing this. When I loaded this
; TSR and ran a separate program to send a byte to COM2. It appears that
; the UART knows a byte has arrived and raises the RECEIVED DATA INTERRUPT.
; However, the PIC never generates an interrupt to my COM2 isr...
;
; W H Y ?!?!?!?!?!?!?!?!?!?!
;
; The separate program that sends data to COM2 simply OUT's the byte to
; the COM2 transmit register (2F8H) and waits 10 seconds and then sends
; another.
;
; I've compared what I am doing with several programs that are published
; in books... I must be missing something very simple... Any ideas?
;
; I'd appreciate any help that you may offer... Frankly, this has been
; driving me nuts!
;
; Thanks,
;
; Mike Gardner
;
; P.S. I wrote this using Turbo Assembler.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
title COM2 TSR Program
%PAGESIZE 60,132
ideal
;*****************************************************************************
; AUTHOR: Mike Gardner
; CREATED: 19-NOV-1992
;*****************************************************************************
; Various boolean values...
FALSE equ 0
OFF equ 0
ON equ 1
TRUE equ 1
; The COM port address
COM = 2F8H
TXR = COM+0
RXR = COM+0
DLL = COM+0
DLH = COM+1
IER = COM+1
IIR = COM+2
LCR = COM+3
MCR = COM+4
LSR = COM+5
MSR = COM+6
; The PIC port address
PIC_CONTROL equ 20H
PIC_MASK equ 21H
END_OF_INTERRUPT equ 20H
; The COM communication parameters
C9600BAUD_MSB equ 0CH
C9600BAUD_LSB equ 00H
C8_1_NO equ 03H
C7_1_NO equ 02H
; The various UART int sources
MODEM_STATUS equ 0
TX_REG_EMPTY equ 2
RX_DATA_READY equ 4
RLINE_STATUS equ 6
macro IO_DELAY n
rept n
local IO_DELAY_TARGET
jmp short IO_DELAY_TARGET
IO_DELAY_TARGET:
endm
endm
macro OUTCH ch
ASSUME ES:VIDEO_SEGMENT
push es
push ax
mov ax, VIDEO_SEGMENT
mov es, ax
pop ax
mov [cmd], ch
mov [attr], 7H
ASSUME ES:VECTORS_SEGMENT
pop es
endm
; The video segment... It assumes VGA/CGA.
SEGMENT VIDEO_SEGMENT AT 0H
ORG 0B800H
cmd db ?
attr db ?
ENDS
; A segment to access the interrupt table vector entry
SEGMENT VECTORS_SEGMENT AT 0H
ORG 0BH * 4 ; COM2 communications interrupt vector
int0BOff dw ?
int0BSeg dw ?
ENDS
SEGMENT CODE_SEGMENT
ASSUME CS:CODE_SEGMENT, DS:CODE_SEGMENT, ES:VECTORS_SEGMENT
ORG 100H
START:
; Initialize and launch the tsr...
jmp LAUNCH
; Original COM2 interrupt vector.
label oldint0B dword
oldint0BOff dw 0
oldint0BSeg dw 0
; The received byte
theChar db 0
; The COM2 isr...
proc int0Bisr near
push ax
push bx
push cx
push dx
push si
push di
push bp
push ds
push es
; Set up my data segment.
push cs
pop ds
; See if there are any interrupts pending in the IIR.
; I am only really interested (and have only enabled)
; the received data interrupt.
@@ANY_INTS_PENDING:
mov dx, IIR
in al, dx ; See if any interrupts have arrived in IIR
mov cl, al
test al, 1
jnz @@EXIT_SERIAL_INT
; Read and place the character into the buffer
IO_DELAY 2
mov dx, RXR
in al, dx
mov ah, 0
; The real version will do buffering... For now
; just store the byte...
mov [theChar], al
; And display it.
OUTCH al
jmp @@ANY_INTS_PENDING
@@EXIT_SERIAL_INT:
; Inform the PIC that we are done with the COM interrupt
mov dx, 20H
mov al, 20H
out dx, al
pop es
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
iret
endp
;*****************************************************************************
LAUNCH:
jmp START_LAUNCH
; Disposable data
; Our startup message
label ABMsg byte
db 13, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 7, 7, 7, 7, 7
db 10, 13, " *******************************************"
db 10, 13, " * A TEST OF A COM2 TSR *"
db 10, 13, " * Version 1.00 *"
db 10, 13, " *******************************************"
db 10, 13, 10, 10, 10, 10, 10, 10, '$'
START_LAUNCH:
push cs
pop ds
mov ax, VECTORS_SEGMENT
mov es, ax
; lets say hello
lea dx,[ABMsg]
mov ah,9
int 21h
OUTCH 'Z'
cli
; Get the original COM2 vector
mov ax,[int0BOff]
mov [oldint0BOff],ax
mov ax,[int0BSeg]
mov [oldint0BSeg],ax
; lets set our new COM2 vector
lea ax,[int0Bisr]
mov [int0BOff],ax
mov [int0BSeg],cs
; Initialize the COM port
mov al, 80H
mov dx, LCR
out dx,al ; Turn on DLAB to set the baud rate
IO_DELAY 3
mov dx, DLL
mov al, C9600BAUD_MSB
out dx,al
IO_DELAY 3
mov dx, DLH
mov al, C9600BAUD_LSB
out dx,al ; Set the baud rate to 9600
IO_DELAY 3
mov dx, LCR
mov al, C8_1_NO
out dx, al ; Set the port to 8 bits, 1 stop, no parity
IO_DELAY 3
in al, dx
and al, 7FH
IO_DELAY 3
out dx, al ; Turn off the DLAB ... Done setting baud rate.
; Enable receiver interrupts from the COM port, DTR, RTS
IO_DELAY 3
mov dx, MCR
mov al, 0BH
out dx, al ; Turn on OUT2, DTR, RTS to enable communication interrupts
IO_DELAY 3
mov dx, IER
mov al, 01H
out dx, al ; Turn on the received data interrupt
; Read the receiver register to make sure any garbage is removed.
IO_DELAY 3
mov dx, RXR
in al, dx
; Enable the PIC to generate COM interrupt
IO_DELAY 3
mov dx, PIC_MASK
in al, dx
and al, 0F7H
IO_DELAY 3
out dx, al ; Permit the generation of COM interrupt
sti
; Go tsr... Jettison everything from the LAUNCH label to the end...
mov dx, offset LAUNCH
int 27H
ENDS
END START
Technical Details
Message-ID:
<1992Nov19.143345.9313@iccgcc.decnet.ab.com>Path:
arc1-ca.pugleaf.net!sparky!uunet!icd.ab.com!iccgcc.decnet.ab.com!gardnerShow Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!sparky!uunet!icd.ab.com!iccgcc.decnet.ab.com!gardner From: gardner@iccgcc.decnet.ab.com Newsgroups: comp.os.msdos.programmer,comp.sys.ibm.pc.programmer Subject: H E L P!!! Serial Communications Blues... (UART). Message-ID: <1992Nov19.143345.9313@iccgcc.decnet.ab.com> Date: 19 Nov 92 14:33:45 EST Lines: 301