Category : Tutorials + Patches
Archive   : NAT_UART.ZIP
Filename : ASCTEST.ASM
;FILE NAME :ASCTEST.ASM *
;VERSION :1.0 *
;DATE :JAN. 22, 1989 *
;PURPOSE :THIS PROGRAM IS TO PERFORM THE FULL DUPLEX COMMUNICATION *
; ON 16550 SERIES UART PRODUCTS IN FIFO POLLING MODE BETWEEN *
; TWO PCS. *
;INPUT :UNDER EACH PROMPT, USER HAS THE OPTION TO SPECIFY THE REQUIRED *
; COM PORT, BAUD RATE, DATA BITS, PARITY BIT, AND STOP BITS. *
; A
;OUTPUT :NO OUTPUT GENERATED *
;USAGE :1.SET UP SERIAL CABLE BETWEEN TWO PCS. *
; 2.RUN THE PROGRAM ON BOTH MACHINES. *
; 3.WHILE THE PROGRAM IS RUNNING, A MESSAGE "PROGRAM RUNNING " *
; WILL BE DISPLAYED ALONG WITH '0' AND '1' INDICATIONS. *
;***************************************************************************
DISPMSG MACRO MSGNO ;MACRO TO DISPLAY MESSAGE
MOV DX,OFFSET MSGNO
MOV AX,SEG MSGNO
MOV DS,AX
MOV AH,9
INT 21H
ENDM
;
KEYIP MACRO ;MACRO TO GET KEYBOARD INPUT
MOV AH,01
INT 21H
ENDM
;
STAK SEGMENT
DW 64 DUP (?)
STAK ENDS
;
DATASEG SEGMENT
NSCMSG DB 0AH,0DH,' National Semiconductor Corporation'
DB 0AH,0DH,0AH,0DH
DB ' -----------------------------------------------'
DB 0AH,0DH,' FULL DUPLEX ASYNC. COMM. PROGRAM',0AH
DB 0DH
DB ' -----------------------------------------------'
DB 0AH,0DH,' ARGUMENT DEFAULT MIN.VALUE MAX.VALUE'
DB 0AH,0DH
DB 0AH,0DH,' COM 1 1 2 '
DB 0AH,0DH,' BAUD 9600 50 56000 '
DB 0AH,0DH,' DATA 8 5 8 '
DB 0AH,0DH,' PARITY O Odd,Even,None,Space,'
DB 'Mark'
DB 0AH,0DH,' STOP 2 1, 1.5, 2',0AH,0DH
DB ' -----------------------------------------------'
DB 0AH,0DH,0AH,0DH,'$'
BASE DW ?
COMMSG DB 0AH,0DH,0AH,0DH,'Enter COM number (1,2) :$'
COMERR DB 0AH,0DH,0AH,0DH,'*** COM number not valid ***','$'
BAUDMSG DB 0AH,0DH,0AH,0DH,'Enter BAUD RATE (50-56000) :$'
BAUDERR DB 0AH,0DH,0AH,0DH,'*** BAUD RATE not valid ***','$'
BAUD DB 2 DUP (?)
DATAMSG DB 0AH,0DH,0AH,0DH,'Enter DATA BITS (5-8) :$'
DATAERR DB 0AH,0DH,0AH,0DH,'*** DATA BITS not valid ***','$'
PTYMSG DB 0AH,0DH,0AH,0DH,'Enter PARITY BIT (O,E,N,S,M) :$'
PTYERR DB 0AH,0DH,0AH,0DH,'*** PARITY BITS not valid ***','$'
PARITY DB ?
STOPMSG DB 0AH,0DH,0AH,0DH,'Enter STOP BITS : 1) 1 BIT. 2) 1.5 BIT.'
DB '3) 2 BIT. :$'
STOPERR DB 0AH,0DH,0AH,0DH,'*** STOP BITS not valid ***','$'
BADSTP DB 0AH,0DH,0AH,0DH,'*** SELECT 1 OR 2 STOP BIT(S) '
DB 'ONLY ***','$'
CTS_OUT DB 0AH,0DH,0AH,0DH,'CTS TIMEOUT--CTS IS NOT ACTIVE, CHECK '
DB 'COMMUNICATION LINK$',0AH,0DH
BUFFER DB 5 DUP (?)
CLENTH DB ?
FORMAT DB 0H
HBAUD DB ?
LBAUD DB ?
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,'$'
NOCOM DB 0AH,0DH,'COM PORT DOES NOT EXIST',0AH,0DH,'$'
RUNMSG DB 0AH,0DH,0AH,0DH,'PROGRAM RUNNING ... $'
DATASEG ENDS
;
PROG SEGMENT 'CODE'
ASSUME CS:PROG,DS:DATASEG,SS:STAK
;
SDLAB EQU 80H
HIMAX EQU 0001H
LOMAX EQU 0C201H
COUNT EQU 50
;
START:
PUSH DS ;INITIALIZATION
SUB AX,AX
PUSH AX
MOV AX,DATASEG
MOV DS,AX
;
;
DISPMSG NSCMSG ;DISPLAY ARGUMENT RANGE
;
COMIP: DISPMSG COMMSG ;PROMPT FOR COM ENTRY
;
KEYIP ;GET INPUT
;
CMP AL,0DH
JNE NODEFT
MOV WORD PTR[BASE],3F8H
JMP SHORT DECIP
NODEFT: CMP AL,'1' ;CHECK IF COM=1
JNE NOT1
MOV WORD PTR[BASE],3F8H
JMP SHORT DECIP
NOT1: CMP AL,'2' ;CHECK IF COM=2
JE COM2
DISPMSG COMERR ;IF NOT,DISPLAY ERROR MSG AND WAIT FOR
JMP SHORT COMIP ;COM INPUT
COM2: MOV WORD PTR[BASE],2F8H
;
DECIP: DISPMSG BAUDMSG
MOV BX,OFFSET BUFFER ;SET UP BUFFER FOR BAUD RATE ENTRY
MOV AH,0AH
MOV BYTE PTR[BX],6
MOV DX,BX
INT 21H
;
INC BX ;CHECK IF 1 DIGIT
CMP BYTE PTR[BX],0
JNE NOTDEF
MOV BYTE PTR[HBAUD],00H
MOV BYTE PTR[LBAUD],0CH
JMP DATAIP
NOTDEF: CMP BYTE PTR[BX],1 ;IF 1 DIGIT, DISPLAY ERROR MSG AND WAIT
JA GT1 ;FOR BAUD RATE INPUT
DISPMSG BAUDERR
JMP SHORT DECIP
;
GT1: CMP BYTE PTR[BX],2 ;IF 2 DIGITS, MOVE AND PATCH
JNE GT2
CMP BYTE PTR[BX+1],'4'
JA DIG1OK
DISPMSG BAUDERR
JMP SHORT DECIP
DIG1OK: MOV AL,[BX+2]
MOV [BX+5],AL
MOV AL,[BX+1]
MOV [BX+4],AL
MOV WORD PTR[BX+1],3030H
MOV BYTE PTR[BX+3],30H
JMP SHORT CHECK
;
GT2: CMP BYTE PTR[BX],3 ;IF 3 DIGITS, MOVE AND PATCH
JNE GT3
MOV AL,[BX+3]
MOV [BX+5],AL
MOV AL,[BX+2]
MOV [BX+4],AL
MOV AL,[BX+1]
MOV [BX+3],AL
MOV WORD PTR[BX+1],3030H
JMP SHORT CHECK
;
GT3: CMP BYTE PTR[BX],4 ;IF 4 DIGITS, MOVE AND PATCH
JNE GT4
MOV AL,[BX+4]
MOV [BX+5],AL
MOV AL,[BX+3]
MOV [BX+4],AL
MOV AL,[BX+2]
MOV [BX+3],AL
MOV AL,[BX+1]
MOV [BX+2],AL
MOV BYTE PTR[BX+1],30H
JMP SHORT CHECK
;
GT4: CMP BYTE PTR[BX+1],'1' ;IF 5 DIGITS, CHECK IF '134.5'
JNE CHECK ;IS ENTERED
CMP BYTE PTR[BX+2],'3'
JNE CHECK
CMP BYTE PTR[BX+3],'4'
JNE CHECK
CMP BYTE PTR[BX+4],'.'
JNE CHECK
CMP BYTE PTR[BX+5],'5'
JNE CHECK
MOV BYTE PTR[HBAUD],03H ;IF YES, STORE DEFAULT DIVISOR
MOV BYTE PTR[LBAUD],59H
MOV AL,0
JMP SHORT CONVOK
CHECK: MOV SI,5 ;IF NOT, CHECK IF 5 DIGITS ARE VALID
NXTDG: CMP BYTE PTR[BX+SI],'9'
JA GT9
CMP BYTE PTR[BX+SI],'0'
JB LT0
DEC SI
JNZ NXTDG
JMP SHORT CONVT
;
GT9: DISPMSG BAUDERR ;IF DIGIT IS GRATER THAN '9'
JMP DECIP
;
LT0: DISPMSG BAUDERR ;IF DIGIT IS LESS THAN '0'
JMP DECIP
;
CONVT: CALL IPCHK ;IF VALID DIGITS, CHECK THE
CONVOK: CMP AL,0 ;CORRESPONDING DECIMAL VALUE
JE DATAIP ;IF CONVERSION IS OK,PROMPT DATA INPUT
DISPMSG BAUDERR ;IF CONVERSION IS NOT GOOD, DISPLAY ERROR
JMP DECIP ;MESSAGE AND GET INPUT AGAIN
;
DATAIP: DISPMSG DATAMSG ;PROMPT FOR DATA BITS INPUT
;
KEYIP ;GET INPUT
CMP AL,0DH ;IF
JNE DTAIN ;IF YES, STORE DEFAULT AND PROMPT
MOV BYTE PTR[CLENTH],'8' ;FOR PARITY INPUT
OR [FORMAT],00000011B
JMP PTYIP
DTAIN: CMP AL,'5' ;IF NOT DEFAULT, CHECK IF 5 DATA BITS
JNE NEXT1
OR BYTE PTR[FORMAT],00000000B
MOV [CLENTH],AL
JMP SHORT PTYIP
NEXT1: CMP AL,'6' ;CHECK IF 6 DATA BITS
JNE NEXT2
OR BYTE PTR[FORMAT],00000001B
MOV [CLENTH],AL
JMP SHORT PTYIP
NEXT2: CMP AL,'7' ;CHECK IF 7 DATA BITS
JNE NEXT3
OR BYTE PTR[FORMAT],00000010B
MOV [CLENTH],AL
JMP SHORT PTYIP
NEXT3: CMP AL,'8' ;CHECK IF 8 DATA BITS
JE DTAOK
DISPMSG DATAERR
JMP SHORT DATAIP
DTAOK: OR BYTE PTR[FORMAT],00000011B
MOV [CLENTH],AL
;
PTYIP: DISPMSG PTYMSG ;PROMPT FOR PARITY BIT INPUT
;
KEYIP
CMP AL,0DH ;CHECK IF
JNE PTYIN
OR [FORMAT],00001000B
JMP STOPIP
PTYIN: CMP AL,'E' ;CHECK IF EVEN PARITY IS SELECTED
JE EVE
CMP AL,'e'
JNE PTY1
EVE: OR [FORMAT],00011000B
JMP STOPIP
PTY1: CMP AL,'O' ;CHECK IF ODD PARITY IS SELECTED
JE ODD
CMP AL,'o'
JNE PTY2
ODD: OR [FORMAT],00001000B
JMP STOPIP
PTY2: CMP AL,'N' ;CHECK IF NONE PARITY IS SELECTED
JE NONE
CMP AL,'n'
JNE PTY3
NONE: OR [FORMAT],00000000B
JMP STOPIP
PTY3: CMP AL,'S' ;CHECK IF SPACE PARITY IS SELECTED
JE SPACE
CMP AL,'s'
JNE PTY4
SPACE: OR [FORMAT],00101000B
JMP STOPIP
PTY4: CMP AL,'M' ;CHECK IF MARK PARITY IS SELECTED
JE MARK
CMP AL,'m'
JE MARK
DISPMSG PTYERR
JMP SHORT PTYIP
MARK: OR [FORMAT],00111000B
;
STOPIP: DISPMSG STOPMSG ;PROMPT FOR STOP BIT INPUT
;
KEYIP
CMP AL,0DH ;CHECK IF
JNE STOPIN
OR [FORMAT],00000100B
JMP SHORT BEGIN
STOPIN: CMP AL,'1' ;CHECK IF 1 STOP BIT IS SELECTED
JNE STOP1
OR [FORMAT],00000000B
JMP BEGIN
STOP1: CMP AL,'2' ;CHECK IF 1.5 STOP BIT IS SELECTED
JNE STOP2 ;IF YES, CHECK IF 5 DATA BITS IS SELECTED
CMP [CLENTH],'5' ;IF YES, STORE STOP BIT FORMAT
JE STOP15
DISPMSG BADSTP ;IF NOT, DISPLAY ERROR MESSAGE AND
JMP STOPIP ;PROMPT FOR STOP BIT INPUT
STOP15: OR [FORMAT],00000100B
JMP SHORT BEGIN
STOP2: CMP AL,'3' ;CHECK IF 2 STOP BITS IS SELECTED
JE STOP3
DISPMSG STOPERR
JMP SHORT STOPIP
STOP3: OR [FORMAT],00000100B
MOV AL,'2'
;
BEGIN:
;
COMOK: DISPMSG RUNMSG
MOV SI,COUNT
MOV DI,0
MOV CL,0
;
CLI
MOV DX,[BASE] ;WRITE TO LCR, DLAB=1
ADD DX,3
MOV AL,SDLAB
OUT DX,AL
;
MOV DX,[BASE] ;WRITE TO DIVISOR LATCH, LB
MOV AL,[LBAUD]
OUT DX,AL
;
MOV DX,[BASE] ;WRITE TO DIVISOR LATCH, HB
INC DX
MOV AL,[HBAUD]
OUT DX,AL
;
MOV DX,[BASE] ;LOAD LCR WITH DATA FORMAT
ADD DX,3
MOV AL,[FORMAT]
OUT DX,AL
;
MOV DX,[BASE] ;DISABLE /OUT2
ADD DX,4
MOV AL,00000000B
OUT DX,AL
;
MOV DX,[BASE] ;DISABLE ALL INTERRUPT BUT RDA INTERRUPT
INC DX
MOV AL,01H
OUT DX,AL
;
MOV DX,[BASE] ;ENABLE AND CLEAR FIFOS
ADD DX,2
MOV AL,00000001B
OUT DX,AL
MOV AL,0
OUT DX,AL
MOV AL,1
OUT DX,AL
;
MOV DX,[BASE] ;SET TRIGGER LEVEL OF 1
ADD DX,2
MOV AL,00000001
OUT DX,AL
STI
;
MOV DX,[BASE] ;READ LSR TO CLEAR ALL ERRORS
ADD DX,5
IN AL,DX
;
MOV DX,[BASE] ;CLEAR RECEIVER BUFFER REGISTER
IN AL,DX
IN AL,DX
;
;
MOV DX,[BASE] ;SEND RTS, BY WRITING TO MCR
ADD DX,4
IN AL,DX
OR AL,00000010B
OUT DX,AL
;
MOV DX,[BASE] ;CHECK CTS
ADD DX,6
MOV CX,0FFFFH
NOCTS: IN AL,DX
AND AL,00010000B
CMP AL,0
JNZ NEXT
DEC CX
JNZ NOCTS
DISPMSG CTS_OUT ;IF CTS IS NOT ACTIVE FOR 65536
JMP DONE ;COUNTS, TIMEOUT
;
NEXT: MOV DX,[BASE] ;TEST IF DATA IS IN
ADD DX,2
IN AL,DX
AND AL,00000111B
CMP AL,04H
JE GOON
;
MOV DX,[BASE] ;CHECK CTS
ADD DX,6
IN AL,DX
AND AL,00010000B
CMP AL,0
JZ NEXT
JMP NODATA
;
GOON: MOV DX,[BASE]
ADD DX,5
IN AL,DX
MOV [STATUS],AL ;SAVE LSR READING
;
MOV DX,[BASE] ;READ DATA
IN AL,DX
MOV [ERRDATA],AL ;SAVE DATA
;
CMP AL,[DATA] ;CHECK DATA
JE SAME
JMP ERROR1
;
SAME: MOV AL,[STATUS] ;TEST IF ERROR OCCURS
AND AL,10000000B
CMP AL,0
JZ TEM
ERROR2:
MOV DX,[BASE] ;TURN ON DTR
ADD DX,4
MOV AL,01
OUT DX,AL
;
DISPMSG MSG3 ;'ERROR THE STATUS IS : '
;
MOV AL,[STATUS] ;DISPLAY STATUS, MSB
CALL ASCODE
MOV DL,[MSBYTE]
MOV AH,2
INT 21H
;
MOV DL,[LSBYTE] ;DISPLAY STATUS, LSB
INT 21H
;
DISPMSG MSG4 ;'THE DATA IS :'
;
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 DX,[BASE] ;DEACTIVATE /RTS
ADD DX,4
MOV AL,00H
OUT DX,AL
;
MOV AH,4CH
INT 21H
;
TEM: JMP DATAOK
;
ERROR1:
MOV DX,[BASE] ;TURN ON DTR
ADD DX,4
MOV AL,01
OUT DX,AL
;
DISPMSG MSG0 ;'THE EXPECTED DATA IS:'
;
MOV AL,[DATA] ;EXPECTED DATA, MSB
CALL ASCODE
MOV DL,[MSBYTE]
MOV AH,2
INT 21H
;
MOV DL,[LSBYTE] ;EXPECTED DATA, LSB
INT 21H
;
DISPMSG MSG1 ;'THE MISMATCHED DATA IS :'
;
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
;
DISPMSG MSG2 ;'THE STATUS IS :'
;
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 DX,[BASE] ;DEACTIVATE /RTS
ADD DX,4
MOV AL,00H
OUT DX,AL
;
DONE: MOV AH,4CH
INT 21H
;
TEMP: JMP NEXT
DATAOK: MOV DX,[BASE] ;ACTIVATE /RTS
ADD DX,4
IN AL,DX
OR AL,00000010B
OUT DX,AL
;
INC BYTE PTR[DATA] ;INCREMENT EXPECTED DATA
DEC CL ;CHECK IF COUNTER IS 0 AND RESET DATA
JNZ TEMP
MOV CL,0
DEC SI ;CHECK IF 100 CHARS. ARE SENT
JNZ TEMP
;
MOV SI,COUNT ;RESET SI
;
CMP DI,0 ;CHECK FLAG
JNZ DIIS1
;
MOV AH,9 ;DISPLAY 0 IF DI=0
MOV AL,'0'
MOV BH,0
MOV BL,112
MOV CX,1
INT 10H
;
MOV DI,1
JMP NEXT
;
DIIS1: MOV AH,9 ;DISPLAY 1 IF DI=1
MOV AL,'1'
MOV BH,0
MOV BL,112
MOV CX,1
INT 10H
;
MOV DI,0
JMP NEXT
;
NODATA: MOV DX,[BASE] ;CHECK IF THRE IS ACTIVE
ADD DX,5
CHKAGN: IN AL,DX
AND AL,00100000B
CMP AL,0
JZ CHKAGN
;
MOV AL,[CHAR] ;LOAD DATA AND OUTPUT
MOV DX,[BASE]
OUT DX,AL
;
MOV DX,[BASE] ;DEACTIVATE RTS
ADD DX,4
IN AL,DX
AND AL,11111101B
OUT DX,AL
;
INC BYTE PTR[CHAR]
JMP NEXT
;************************
;CHECK BAUD INPUT
;************************
IPCHK PROC NEAR
CMP BYTE PTR[BX+1],35H
JBE DIGI4
MOV AL,1
JMP DIGERR
DIGI4: CMP BYTE PTR[BX+1],35H
JNE DIGIOK
CMP BYTE PTR[BX+2],36H
JBE DIGIT3
MOV AL,1
JMP DIGERR
DIGIT3: CMP BYTE PTR[BX+2],36H
JNE DIGIOK
DIGI3: CMP BYTE PTR[BX+3],30H
JE DIGIT2
MOV AL,1
JMP DIGERR
DIGIT2: CMP BYTE PTR[BX+4],30H
JE DIGIT1
MOV AL,1
JMP DIGERR
DIGIT1: CMP BYTE PTR[BX+5],30H
JE DIGIOK
MOV AL,1
JMP DIGERR
DIGIOK: MOV SI,1
NXT: SUB BYTE PTR[BX+SI],30H ;CONVERT ASCII TO HEX
INC SI
CMP SI,6
JNE NXT
;
MOV CX,10 ;PUT DIGIT 1 IN RESULT
MOV AL,[BX+4] ;DIGIT 2 X 10
MUL CL
ADD AL,[BX+5] ;ADD WITH DIGIT 1
MOV AH,0
MOV SI,AX
MOV AL,[BX+3] ;DIGIT 3 X 100
MUL CX
MUL CX
ADD AX,SI ;DIGIT 4 X 1000
MOV SI,AX
MOV AL,[BX+2]
MOV AH,0
MUL CX
MUL CX
MUL CX
ADD AX,SI ;DIGIT 5 X 10000
MOV SI,AX
MOV AL,[BX+1]
MOV AH,0
MUL CX
MUL CX
MUL CX
MUL CX
ADD AX,SI
MOV SI,AX
MOV DI,SI
SAR DI,1
MOV DX,HIMAX ;LOAD 115200 IN HEX
MOV AX,LOMAX
DIV SI
CMP DX,DI
JNA LTHN4
INC AX
LTHN4: MOV [HBAUD],AH
MOV [LBAUD],AL
MOV AL,0
DIGERR: RET
IPCHK ENDP
;
;*************************
; 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/