home *** CD-ROM | disk | FTP | other *** search
- Xref: sparky comp.os.msdos.programmer:10776 comp.sys.ibm.pc.programmer:595
- Path: 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
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;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
-