Category : Assembly Language Source Code
Archive   : TASMSWAN.ZIP
Filename : ASYNCH.ASM

 
Output of file : ASYNCH.ASM contained in archive : TASMSWAN.ZIP
%TITLE "Asynchronous Serial Communications Module"

IDEAL
DOSSEG
MODEL small

PUBLIC ComPort

ComPort = 0

IF ComPort EQ 0
Port EQU 03F8h
VectorNum EQU 0Ch
EnableIRQ EQU 0EFh
DisableIRQ EQU 10h
ELSEIF ComPort EQ 1
Port EQU 02F8h
VectorNum EQU 0Bh
EnableIRQ EQU 0F7h
DisableIRQ EQU 08h
ELSE
%DISPLAY "ComPort must be 0 or 1"
ERR
ENDIF

TxRegister = Port + 0
RxRegister = Port + 0
IntEnable = Port + 1
IntIdent = Port + 2
LineControl = Port + 3
ModemControl = Port + 4
LineStatus = Port + 5
ModemStatus = Port + 6

Ctrl8259_0 EQU 020h
Ctrl8259_1 EQU 021h
EOI EQU 020h
BufSize EQU 2048


DATASEG

vectorSeg dw ?
vectorOfs dw ?
bufHead dw ?
bufTail dw ?
buffer db BufSize DUP (?)

CODESEG

PUBLIC AsynchInit, AsynchStop, AsynchStat
PUBLIC AsynchOut, AsynchIn, AsynchInStat

%NEWPAGE
;------------------------------------------------------------------------
; EmptyBuffer - empty the input buffer
;------------------------------------------------------------------------
; NOTE: private to module
; Input: none
; Output: none
; Registers: none
;------------------------------------------------------------------------
PROC EmptyBuffer
cli
push ax
mov ax, offset buffer
mov [bufHead], ax
mov [bufTail], ax
pop ax
sti
ret
ENDP EmptyBuffer

%NEWPAGE
;------------------------------------------------------------------------
; AsynchInit - initialize serial port and install ISR
;------------------------------------------------------------------------
; Input: none
; Output: none
; NOTE: precede (usually) with call to int 14h
; to set baud rate
; NOTE: interrupt-driven input begins immediately
; upon exit from this routine
; WARNING: you MUST call AsynchStop before your program ends
; to avoid a !!! SYSTEM CRASH !!!
; Registers: ax,bx,dx
;------------------------------------------------------------------------
PROC AsynchInit
call EmptyBuffer
push ds
push es
mov ax, 3500h + VectorNum
int 21h
mov [vectorSeg], es
mov [vectorOfs], bx
push cs
pop ds
mov ds, offset AsynchISR
mov ax, 2500h + VectorNum
int 21h
pop es
pop ds
in al, Ctrl8259_1
and al, EnableIRQ
out Ctrl8259_1,al
mov dx,LineControl
in al,dx
and al,07Fh
out dx,al
mov dx,IntEnable
mov al,1
out dx,al
@@10:
mov dx,RxRegister
in al,dx
mov dx,LineStatus
in al,dx
mov dx,ModemStatus
in al,dx
mov dx,IntIdent
in al,dx
test al,1
jz @@10
mov dx,ModemControl
in al,dx
or al,08h
out dx,al
call EmptyBuffer
ret
ENDP AsynchInit

%NEWPAGE
;------------------------------------------------------------------------
; AsynchStop - uninstall asynch ISR
;------------------------------------------------------------------------
; Input: none
; Output: none
; WARNING: you MUST call AsynchStop before your program ends
; to avoid a !!! SYSTEM CRASH !!!
; Registers: al,dx
;------------------------------------------------------------------------
PROC AsynchStop
in al, Ctrl8259_1
or al, DisableIRQ
out Ctrl8259_1,al
mov dx,LineControl
in al,dx
and al,07Fh
out dx,al
mov dx, IntEnable
xor al,al
out dx,al
mov dx,ModemControl
in al,dx
and al, 0F7h
out dx,al
push ds
mov ax, 2500h + VectorNum
mov dx, [vectorOfs]
mov ds,[vectorSeg]
int 21h
pop ds
ret
ENDP AsynchStop

%NEWPAGE
;------------------------------------------------------------------------
; AsynchStat - get status for output
;------------------------------------------------------------------------
; Input: none
; Output: ah = line status, al = modem status
; Registers: ax,dx
;------------------------------------------------------------------------
PROC AsynchStat
mov ah,3
mov dx, ComPort
int 14h
ret
ENDP AsynchStat

%NEWPAGE
;------------------------------------------------------------------------
; AsynchOut - output a byte (to the output port)
;------------------------------------------------------------------------
; Input: al = character (or byte) to output
; Output: none
; Registers: none
;------------------------------------------------------------------------
PROC AsynchOut
push dx
push ax
@@10:
mov dx, LineStatus
in al,dx
and al,020h
jz @@10
pop ax
mov dx, TxRegister
out dx,al
pop dx
ret
ENDP AsynchOut

%NEWPAGE
;------------------------------------------------------------------------
; AsynchIn - input a byte (from buffer)
;------------------------------------------------------------------------
; Input: none
; Output: al = char from buffer
; NOTE: if buffer is empty, al will be 0, with
; no indication that this is not an input value.
; Precede with call to AsynchInStat to avoid reads
; from an empty buffer.
; Registers: al,bx
;------------------------------------------------------------------------
PROC AsynchIn
xor al,al
mov bx,[bufTail]
cmp bx,[bufHead]
je @@99
mov al,[byte ptr bx]
inc [bufTail]
cmp [word ptr bufTail], offset buffer + BufSize
jb @@99
mov [bufTail], offset buffer
@@99:
ret
ENDP AsynchIn

%NEWPAGE
;------------------------------------------------------------------------
; AsynchInStat - get status of input buffer
;------------------------------------------------------------------------
; Input: none
; Output: dx = number of bytes (or chars) in buffer
; Registers: dx
;------------------------------------------------------------------------
PROC AsynchInStat
mov dx,[bufHead]
sub dx,[bufTail]
jge @@99
add dx,BufSize
@@99:
ret
ENDP AsynchInStat

%NEWPAGE
;------------------------------------------------------------------------
; AsynchISR - asynchronous input Interrupt Service Routine (ISR)
;------------------------------------------------------------------------
; Input: none
; Output: none (char read and deposited in buffer)
; NOTE: this version ignores buffer overflows
; Registers: none
;------------------------------------------------------------------------
PROC AsynchISR
push ax
push bx
push ds
push dx
mov ax,@data
mov ds,ax
mov dx,RxRegister
in al,dx
mov bx,[bufHead]
mov [byte ptr bx], al
inc bx
cmp bx,offset buffer + BufSize
jb @@10
mov bx, offset buffer
@@10:
cmp bx,[bufTail]
jne @@20
mov bx,[bufHead]
@@20:
mov [bufHead],bx
mov al,EOI
out Ctrl8259_0,al
pop dx
pop ds
pop bx
pop ax
iret
ENDP AsynchISR

END


  3 Responses to “Category : Assembly Language Source Code
Archive   : TASMSWAN.ZIP
Filename : ASYNCH.ASM

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/