Category : Tutorials + Patches
Archive   : NAT_UART.ZIP
Filename : TOG1.ASM
;FILE NAME :TOG1.ASM
;VERSION :2.0
;DATE :JAN. 17, 1989
;PURPOSE :THIS PROGRAM IS TO PERFORM THE FULL DUPLEX COMMUNICATION
; BETWEEN TWO IBM-PC COMPATIBLE MACHINES. THE PROGRAM TESTS
; 8250, 8250A, 16450 AND 16550 COMPATIBLE UARTS OPERATING IN
; SINGLE CHARACTER MODE.
;SUMMARY :THE PROGRAM POLLS LINE STATUS AND MODEM STATUS REGISTERS
; TO CONTROL DATA FLOW. UPON RECEIVING A DATA READY (DR BIT)
; INDICATION, THE RECEIVER BUFFER IS READ. DATA TRANSMITTED
; IS A SEQUENCE FROM 00-FFH. THE DATA RECEIVED IS COMPARED
; TO A COUNTER VARIABLE TO INSURE DATA WAS TRANSMITTED AND
; RECEIVED CORRECTLY. THE LSR IS ALSO CHECKED FOR LINE STATUS
; ERRORS. BAD CHARACTERS OR LINE STATUS ERRORS WILL CAUSE
; ERROR MESSAGES TO BE PRINTED AND THE PROGRAM TERMINATED.
; AFTER RECEIVING A CHARACTER, THE PROGRAM TOGGLES THE
; REQUEST TO SEND (RTS) BIT.
; THE MODEM STATUS REGISTER IS POLLED FOR A DCTS - CHANGE IN
; CTS - INDICATION. THIS SIGNIFIES THAT THE OTHER MACHINE HAS
; RECEIVED A CHARACTER AND HAS TOGGLED RTS AND THUS A NEW
; CHARACTER IS TRANSMITTED.
; THE PROGRAM ALSO OUTPUTS ALTERNATING 1'S AND 0'S EVERY 16
; CHARACTERS TO VERIFY PROGRAM OPERATION.
;USAGE :SET UP SERIAL CABLE BETWEEN TWO PCS WITH NULL MODEM CONNECTION.
; IN ADDITION, THE CONSTANT base IN THIS PROGRAM MUST BE THE
; PROPER BASE ADDRESS FOR THE COM PORT BEING USED.
; ADDRESS BASE FOR TOG1.ASM = 3F8H = ADDRESS FOR COM1.
;*******************************************************************
STAK SEGMENT
DW 64 DUP (?)
STAK ENDS
;
DATASEG SEGMENT
CHAR DB 0
STATUS DB ?
ERRDATA DB ?
DATA DB 0
LSBYTE DB ?
MSBYTE DB ?
SAVE DB ?
MSG0 DB 0AH,0DH,'THE EXPECTED DATA IS :',0AH,0DH,'$'
MSG1 DB 0AH,0DH,'THE MISMATCHED DATA IS :',0AH,0DH,'$'
MSG2 DB 0AH,0DH,'THE STATUS IS :',0AH,0DH,'$'
MSG3 DB 0AH,0DH,'THE ERROR STATUS IS :',0AH,0DH,'$'
MSG4 DB 0AH,0DH,'THE DATA IS :',0AH,0DH,'$'
MSG6 DB 0AH,0DH,0AH,0DH,'FLOW CONTROL ERROR: UART FAILED TO RECOGNIZE A CHANGE IN CLEAR TO SEND (DCTS)',0AH,0DH,0AH,0DH,'$'
MSG8 DB 0AH,0DH,'FULL DUPLEX, ASYNCHRONOUS COMMUNICATIONS PROGRAM FAILED.',0AH,0DH,'$'
MSG7 DB 0AH,0DH,'START BOTH PROGRAMS THEN HIT A KEY ON BOTH KEYBOARDS TO START COMMUNICATION',0AH,0DH,'$'
DATASEG ENDS
;
PROG SEGMENT 'CODE'
ASSUME CS:PROG,DS:DATASEG,SS:STAK
;
SDLAB EQU 80H
BASE EQU 3F8H ;COM1 ADDRESS BASE
LCR EQU BASE+3
DLL EQU BASE
DLM EQU BASE+1
BAUD1 EQU 0CH
BAUD2 EQU 00H
MCR EQU BASE+4
FCR EQU BASE+2
LSR EQU BASE+5
MSR EQU BASE+6
RBR EQU BASE
TX EQU BASE
IIR EQU BASE+2
IER EQU BASE+1
;
START:
PUSH DS ;INITIALIZATION
SUB AX,AX
PUSH AX
MOV AX,SEG DATASEG
MOV DS,AX
;
MOV DI,0
MOV CL,10H
MOV CH,0
CLI
MOV DX,LCR ;WRITE TO LCR, DLAB=1
MOV AL,SDLAB
OUT DX,AL
;
MOV DX,DLL ;WRITE TO DIVISOR LATCH, LB
MOV AL,BAUD1
OUT DX,AL
;
MOV DX,DLM ;WRITE TO DIVISOR LATCH, HB
MOV AL,BAUD2
OUT DX,AL
;
MOV DX,LCR ;8 BITS, 1 STOP, ODD
MOV AL,00001011B
OUT DX,AL
;
MOV DX,MCR ;CLEAR MCR
MOV AL,00000000B
OUT DX,AL
;
MOV DX,IER ;DISABLE ALL INTERRUPTS
MOV AL,00H
OUT DX,AL
;
STI
;
MOV DX,LSR ;READ LSR TO CLEAR ALL ERRORS
IN AL,DX
;
MOV DX,RBR ;CLEAR RECEIVER BUFFER REGISTER
IN AL,DX
IN AL,DX
;*********************** WAIT FOR KEYBOARD STRIKE ********************
MOV DX,OFFSET MSG7 ;'HIT A KEY...'
MOV AX,SEG MSG7
MOV DS,AX
MOV AH,9
INT 21H
MOV AL,0
MOV AH,0 ;KEYBOARD BIOS CODE
INT 16H ;CALL KEYBOARD BIOS (CHAR RET IN AL)
;
MOV DX,MCR ;TOGGLE RTS
IN AL,DX
XOR AL,00000010B
OUT DX,AL
;********************* POLLING LOOP ***************************
NEXT: MOV DX,LSR ;TEST IF DATA IS IN
IN AL,DX
AND AL,00000001B
CMP AL,01H
JE GOON ;DR INDICATION FOUND SO READ NEW CHAR
;
MOV DX,MSR ;CHECK DCTS
IN AL,DX
AND AL,00000001B
CMP AL,0
JZ NEXT
JMP XMIT ;DCTS FOUND SO TRANSMIT NEXT CHAR
;*************************** READ NEW DATA ***********************
GOON: MOV DX,LSR
IN AL,DX
MOV [STATUS],AL ;SAVE LSR READING
;
MOV DX,RBR ;READ DATA
IN AL,DX
MOV [ERRDATA],AL ;SAVE DATA
;
CMP AL,[DATA] ;CHECK DATA
JNE ERROR1
;
MOV AL,[STATUS] ;TEST IF ERROR OCCURS
AND AL,10000000B
CMP AL,0
JNZ ERROR2 ;JUMP IF STATUS ERROR
JMP DATAOK
ERROR2: MOV DX,OFFSET MSG3 ;'ERROR THE STATUS IS : '
MOV AX,SEG MSG3
MOV DS,AX
MOV AH,9
INT 21H
;
MOV AL,[STATUS] ;DISPLAY STATUS, MSB
CALL ASCODE
MOV DL,[MSBYTE]
MOV AH,2
INT 21H
;
MOV DL,[LSBYTE] ;DISPLAY STATUS, LSB
INT 21H
MOV DX,OFFSET MSG4 ;'THE DATA IS :'
MOV AX,SEG MSG4
MOV DS,AX
MOV AH,9
INT 21H
;
MOV AL,[ERRDATA] ;DISPLAY DATA, MSB
CALL ASCODE
MOV DL,[MSBYTE]
MOV AH,2
INT 21H
;
MOV DL,[LSBYTE] ;DISPLAY DATA LSB
INT 21H
;
MOV DL,0AH ;DISPLAY LF
MOV AH,2
INT 21H
;
MOV DL,0DH ;DISPLAY CR
INT 21H
;
MOV AL,CL ;DISPLAY COUNTER, MSB
CALL ASCODE
MOV DL,[MSBYTE]
MOV AH,2
INT 21H
;
MOV DL,[LSBYTE] ;DISPLAY COUNTER, LSB
INT 21H
;
MOV AH,4CH
INT 21H
;
ERROR1: MOV DX,OFFSET MSG0 ;'THE EXPECTED DATA IS:'
MOV AX,SEG MSG0
MOV DS,AX
MOV AH,9
INT 21H
;
MOV AL,[DATA] ;EXPECTED DATA, MSB
CALL ASCODE
MOV DL,[MSBYTE]
MOV AH,2
INT 21H
;
MOV DL,[LSBYTE] ;EXPECTED DATA, LSB
INT 21H
;
MOV DX,OFFSET MSG1 ;'THE MISMATCHED DATA IS :'
MOV AX,SEG MSG1
MOV DS,AX
MOV AH,9
INT 21H
;
MOV AL,[ERRDATA] ;DISPLAY ERROR DATA, MSB
CALL ASCODE
MOV DL,[MSBYTE]
MOV AH,2
INT 21H
MOV DL,[LSBYTE] ;DISPLAY ERROR DATA, LSB
INT 21H
;
MOV DX,OFFSET MSG2 ;'THE STATUS IS :'
MOV AX,SEG MSG2
MOV DS,AX
MOV AH,9
INT 21H
;
MOV AL,[STATUS] ;DISPLAY STATUS, MSB
CALL ASCODE
MOV DL,[MSBYTE]
MOV AH,2
INT 21H
;
MOV DL,[LSBYTE] ;DISPLAY STATUS, LSB
INT 21H
;
MOV DL,0AH ;DISPLAY LF
INT 21H
;
MOV DL,0DH ;DISPLAY CR
INT 21H
;
MOV AL,CL ;DISPLAY COUNTER, MSB
CALL ASCODE
MOV DL,[MSBYTE]
MOV AH,2
INT 21H
;
MOV DL,[LSBYTE] ;DISPLAY COUNTER, LSB
INT 21H
;
MOV AH,4CH
INT 21H
;
DATAOK: INC BYTE PTR[DATA] ;INCREMENT EXPECTED DATA
INC CH ;INC TIMEOUT VARIABLE
CMP CH,5
JZ ERROR3 ;5 CHARS RECEIVED W/OUT TRANSMITTING ONE
DEC CL ;CHECK IF COUNTER IS 0 AND RESET DATA
JNZ TEMP
MOV CL,10H
;
CMP DI,0 ;CHECK FLAG
JNZ DIIS1
;
MOV DL,'0' ;DISPLAY 0 IF DI=0
MOV AH,02H
INT 21H
;
MOV DI,1
JMP TEMP
;
DIIS1: MOV DL,'1' ;DISPLAY 1 IF DI=1
MOV AH,02H
INT 21H
;
MOV DI,0
TEMP: MOV DX,MCR ;TOGGLE /RTS
IN AL,DX
XOR AL,00000010B
OUT DX,AL
JMP NEXT ;RESUME POLLING
;
XMIT: MOV DX,LSR ;CHECK IF THRE IS ACTIVE
CHKAGN: IN AL,DX
AND AL,00100000B
CMP AL,0
JZ CHKAGN
;
MOV AL,[CHAR] ;LOAD DATA AND OUTPUT
MOV DX,TX
OUT DX,AL
;
INC BYTE PTR[CHAR]
MOV CH,0 ;CLEAR TRANSMITTER TIMEOUT COUNTER
JMP NEXT ;RESUME POLLING
;
;******************* ERROR 3: TRANSMITTER TIMEOUT ERROR ***************
ERROR3: MOV DX,OFFSET MSG6 ;OUTPUT TRANSMITTER ERROR MSG 1
MOV AX,SEG MSG6
MOV DS,AX
MOV AH,9
INT 21H
MOV DX,OFFSET MSG8 ;OUTPUT TRANSMITTER ERROR MSG 2
MOV AX,SEG MSG8
MOV DS,AX
MOV AH,9
INT 21H
MOV AH,4CH ;END PROGRAM
INT 21H
;*************************
; HEX TO ASCII CONVERSION
;*************************
ASCODE PROC NEAR
PUSH CX ;SAVE COUNTER
MOV CL,4 ;LOAD SHIFT COUNT
MOV [SAVE],AL ;SAVE INPUT DATA
AND AL,0F0H ;MASK OFF LSB
SHR AL,CL ;RIGHT SHIFT
POP CX ;RESTORE COUNTER
CMP AL,9 ;CHECK IF DATA IS BETWEEN 0-9
JA ATOFH
ADD AL,30H ;IF YES, CONVERT TO 30H-39H
MOV [MSBYTE],AL ;SAVE THE RESULT
LSB: MOV AL,[SAVE] ;LOAD ORIGINAL DATA
AND AL,0FH ;MASK OFF MSB
CMP AL,9 ;CHECK IF DATA IS BETWEEN 0-9
JA ATOFL
ADD AL,30H ;IF YES, CONVERT TO 30H-39H
MOV [LSBYTE],AL ;SAVE THE RESULT
RET
ATOFH: ADD AL,37H ;IF DATA IS BETWEEN A-F, CONVERT TO 41H-46H
MOV [MSBYTE],AL ;SAVE THE RESULT
JMP SHORT LSB
ATOFL: ADD AL,37H ;IF DATA IS BETWEEN A-F, CONVERT TO 41H-46H
MOV [LSBYTE],AL
RET
ASCODE ENDP
PROG ENDS
END START
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
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/