Category : Communication (modem) tools and utilities
Archive   : LITES.ZIP
Filename : LITES.ASM

 
Output of file : LITES.ASM contained in archive : LITES.ZIP
;=============================================================================
; LITES displays the realtime status of the UART's DTR, RTS, CTS, DSR, DCD,
; and RI lines as well as its Baud rate and data format settings. Syntax is:
; LITES [comport] [U]
; where comport is a number indicating which COM port is to be monitored,
; and U uninstalls the program from memory.
;=============================================================================
CODE SEGMENT PARA PUBLIC 'CODE'
ASSUME CS:CODE
ORG 100H
BEGIN: JMP INITIALIZE

PROGRAM DB "LITES 1.0 (c) 1989 Ziff Communications Co.",13,10
AUTHOR DB "PC Magazine ",254," Jeff Prosise",13,10
HOTKEY DB "Hotkey is Alt-L",32,32,32,13,10,"$"

;-----------------------------------------------------------------------------
; Patch points to modify the program's operation.
;-----------------------------------------------------------------------------
KEYCODE DB 26H ;scan code for "L" key
VIDEO_ATTR DB 70H ;status line video attribute
ROWNUM DB 0 ;row number of status line
COL_OFFSET DB 0 ;offset from right margin
TICKS DB 2 ;ticks between refreshes
COMPORT DW 0 ;COM port designator (COM1)

;-----------------------------------------------------------------------------
; Other program variables.
;-----------------------------------------------------------------------------
INT09H DD ? ;interrupt 9h vector
INT08H DD ? ;interrupt 8h vector
COUNTER DB 0FFH ;refresh counter

PINS DB ? ;bit 0 = DTR, 1 = RTS
; 2 = CTS, 3 = DSR
; 4 = RI, 5 = DCD

BAUDRATE DW ? ;Baud rate
PARITY DB ? ;parity setting
DATABITS DB ? ;number of data bits
STOPBITS DB ? ;number of stop bits

VIDEOSEG DW ? ;video segment address
VIDEOADDR DW ? ;video offset address
SYNCFLAG DB ? ;0 = no video sync, 1 = sync

PINTEXT DB "DTRRTSCTSDSRRI",32,"DCD"

;=============================================================================
; KBINT intercepts and handles the keyboard interrupt 9h.
;=============================================================================
KBINT PROC FAR

PUSHF ;save flags
PUSH AX ;save AX

STI ;interrupts on
IN AL,60H ;get scan code from keyboard
CMP AL,CS:[KEYCODE] ;exit to BIOS if it's not
JNE NOT_HOT ; the hotkey
MOV AH,2 ;get keyboard shift state
INT 16H
AND AL,0FH ;mask off the upper 4 bits
CMP AL,8 ;exit if Alt isn't held down
JNE NOT_HOT
MOV AH,0FH ;get current video mode
INT 10H
CMP AL,7 ;abort if not in text mode
JE RESET
CMP AL,4
JB RESET
NOT_HOT: POP AX ;exit to BIOS int 9 handler
POPF
JMP CS:INT09H
;
;Reset the keyboard controller and interrupt controller.
;
RESET: CLI ;interrupts off
IN AL,61H ;reset the keyboard controller
MOV AH,AL
OR AL,80H
OUT 61H,AL
XCHG AH,AL
MOV AL,20H ;signal EOI to interrupt
OUT 20H,AL ; controller
STI ;interrupts back on
PUSH BX ;save registers
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH DS
PUSH ES
PUSH BP
;
;Deactivate the status line if it is currently displayed.
;
CMP CS:[COUNTER],0FFH ;branch if status line is
JE SETVIDEO ; dormant
MOV CS:[COUNTER],0FFH ;disable counter
MOV AX,CS ;point DS:SI to buffer
MOV DS,AX
MOV SI,OFFSET INITIALIZE
MOV ES,CS:[VIDEOSEG] ;point ES:DI to video memory
MOV DI,CS:[VIDEOADDR]
MOV CX,32
CALL VIDEO_XFER ;erase the status line
JMP SHORT KB_EXIT
;
;Initialize video parameters.
;
SETVIDEO: MOV CS:[VIDEOSEG],0B800H ;set default video parms
MOV CS:[SYNCFLAG],0
MOV AX,40H ;point ES to BIOS data
MOV ES,AX ; area
TEST BYTE PTR ES:[63H],20H ;set video segment value
JZ COLOR ; (monochrome or color)
MOV CS:[VIDEOSEG],0B000H
JMP SHORT NOSYNC
COLOR: MOV AH,12H ;if a color adapter is
MOV BL,10H ; detected, determine
INT 10H ; whether or not it's
CMP BL,10H ; a CGA and set SYNCFLAG
JNE NOSYNC ; if it is
MOV CS:[SYNCFLAG],1
NOSYNC: MOV AX,ES:[4AH] ;calculate offset address
SHL AX,1 ; within video segment
MOV BL,CS:[ROWNUM] ;multiply number of columns
MUL BL ; by row number
MOV BX,ES:[4AH] ;add column offset
SUB BL,32
SUB BL,CS:[COL_OFFSET]
SHL BL,1
ADD AX,BX
ADD AX,ES:[4EH] ;add page address
MOV CS:[VIDEOADDR],AX ;store it
;
;Save the portion of the screen that will be overwritten by the status line.
;
MOV DS,CS:[VIDEOSEG] ;point DS:SI to video memory
MOV SI,CS:[VIDEOADDR]
MOV AX,CS ;point ES:DI to save buffer
MOV ES,AX
MOV DI,OFFSET INITIALIZE
MOV CX,32
CALL VIDEO_XFER ;block move
;
;Activate the status line, restore registers, and exit.
;
MOV AL,CS:[TICKS] ;enable counter
MOV CS:[COUNTER],AL
KB_EXIT: POP BP ;restore registers
POP ES
POP DS
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX ;restore AX and flags
POPF
IRET
KBINT ENDP

;=============================================================================
; TIMERINT intercepts and handles the timer tick interrupt 8h.
;=============================================================================
TIMERINT PROC FAR
PUSHF ;push flags for int call
CALL CS:INT08H ;call old interrupt handler
CMP CS:[COUNTER],0FFH ;exit if status line is
JE TIMER_EXIT ; dormant
DEC CS:[COUNTER] ;decrement timer
JNZ TIMER_EXIT ;exit if nonzero
PUSH AX
MOV AL,CS:[TICKS] ;reset counter
MOV CS:[COUNTER],AL
PUSH BX ;save remaining registers
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH DS
PUSH ES
STI ;enable interrupts
CALL SETPARMS ;set output variables
CALL REFRESH ;refresh the status display
POP ES ;restore registers and exit
POP DS
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
TIMER_EXIT: IRET ;exit
TIMERINT ENDP

;-----------------------------------------------------------------------------
; SETPARMS is called by TIMERINT to set UART parameter values.
;-----------------------------------------------------------------------------
PSETTINGS DB "NONE"
DLAB_REG DB ?

SETPARMS PROC NEAR
MOV DX,CS:[COMPORT] ;get UART base address
ADD DX,3 ;point DX to Data Format
PUSH DX
IN AL,DX ;read Data Format byte
MOV CS:[DLAB_REG],AL ;save it
OR AL,80H ;set DLAB
OUT DX,AL
SUB DX,3 ;read divisor LSB
IN AL,DX
MOV BL,AL
INC DX
IN AL,DX ;read divisor MSB
MOV BH,AL
OR BX,BX ;don't divide if BX = 0
JNZ SP1
MOV WORD PTR CS:[BAUDRATE],0
JMP SHORT SP2
SP1: MOV AX,0C200H ;calculate Baud rate from
MOV DX,1 ; clock and divisor
DIV BX
MOV CS:[BAUDRATE],AX ;save it
SP2: POP DX ;restore Data Format register
MOV AL,CS:[DLAB_REG]
OUT DX,AL
;
;Determine what the parity, data bits, and stop bits settings are.
;
MOV AL,CS:[DLAB_REG] ;data bits in bits 0 and 1
AND AL,3
ADD AL,5
MOV CS:[DATABITS],AL
MOV AL,CS:[DLAB_REG] ;stop bits in bit 2
SHR AL,1
SHR AL,1
AND AL,1
ADD AL,1
MOV CS:[STOPBITS],AL
MOV BL,CS:[DLAB_REG] ;parity in bits 3 and 4
MOV CL,3
SHR BL,CL
AND BL,3
XOR BH,BH
MOV AL,BYTE PTR CS:[PSETTINGS][BX]
MOV CS:[PARITY],AL
;
;Determine the states of the CTS, DSR, DCD, and RI input pins.
;
MOV DX,CS:[COMPORT] ;point DX to Modem Status
ADD DX,6
IN AL,DX ;read register
AND AL,0F0H ;mask off the lower 4 bits
SHR AL,1 ;then save them
SHR AL,1
MOV CS:[PINS],AL
;
;Determine the states of the RTS and DTR output pins.
;
SUB DX,2 ;point DX to Modem Control
IN AL,DX ;read register
AND AL,3 ;strip the upper 6 bits
OR CS:[PINS],AL ;store in PINS byte
RET
SETPARMS ENDP

;-----------------------------------------------------------------------------
; REFRESH is called by TIMERINT to display the status line.
;-----------------------------------------------------------------------------
REFRESH PROC NEAR
MOV AX,CS ;copy the underlying line
MOV DS,AX ; into the status buffer
MOV ES,AX
MOV SI,OFFSET INITIALIZE
MOV DI,OFFSET INITIALIZE + 64
MOV CX,32
CLD
REP MOVSW
;
;Construct the portion of the string pertaining to the 6 pins.
;
MOV SI,OFFSET PINTEXT ;point SI to text
MOV DI,OFFSET INITIALIZE + 64 ;point DI to buffer
MOV BL,1
MOV AH,CS:[VIDEO_ATTR]
MOV CX,6 ;6 pins to test
RLOOP1: PUSH CX
PUSH SI
PUSH DI
TEST CS:[PINS],BL ;copy pin name to buffer if
JZ PINLOW ; corresponding bit is set
MOV CX,3
RLOOP2: LODSB
STOSW
LOOP RLOOP2
PINLOW: POP DI
POP SI
SHL BL,1
ADD SI,3
ADD DI,8
POP CX
LOOP RLOOP1 ;loop unitl all 6 are done
;
;Add Baud rate, parity, data bits, and stop bits indicators to the string.
;
MOV AX,CS:[BAUDRATE] ;Baud rate
CALL BIN2ASC
MOV DI,OFFSET INITIALIZE + 64 + 58
MOV AL,CS:[PARITY] ;parity
MOV AH,CS:[VIDEO_ATTR]
STOSW
MOV AL,CS:[DATABITS] ;data bits
ADD AL,30H
STOSW
MOV AL,CS:[STOPBITS] ;stop bits
ADD AL,30H
STOSW
;
;Display the status string.
;
MOV SI,OFFSET INITIALIZE + 64
MOV ES,CS:[VIDEOSEG]
MOV DI,CS:[VIDEOADDR]
MOV CX,32
CALL VIDEO_XFER
RET
REFRESH ENDP

;-----------------------------------------------------------------------------
; VIDEO_XFER transfers a block of data to or from the video buffer.
; Entry: DS:SI - source
; ES:DI - destination
; CX - number of words
;-----------------------------------------------------------------------------
VIDEO_XFER PROC NEAR
CLD ;clear DF
TEST CS:[SYNCFLAG],1 ;don't wait if this isn't
JZ NOWAIT ; a CGA
MOV DX,3DAH ;wait if it is
MWAIT1: IN AL,DX ;wait for non-retrace period
TEST AL,8
JNZ MWAIT1
MWAIT2: IN AL,DX ;wait for the next vertical
TEST AL,8 ; retrace
JZ MWAIT2
NOWAIT: CLI ;interrupts off
REP MOVSW ;block move
STI ;interrupts back on
RET
VIDEO_XFER ENDP

;-----------------------------------------------------------------------------
; BIN2ASC converts a single binary word value into its ASCII decimal
; equivalent and writes it to the designated output buffer.
; Entry: AX - binary value
; ES:DI - destination
;-----------------------------------------------------------------------------
BASE DW 10 ;base 10 divisor

BIN2ASC PROC NEAR
XOR CX,CX ;zero digit counter
BALOOP1: INC CX ;increment counter
XOR DX,DX
DIV CS:[BASE] ;divide by base
PUSH DX ;save remainder on stack
OR AX,AX ;loop until quotient is zero
JNZ BALOOP1
BALOOP2: POP AX ;pull digits back off the
ADD AL,30H ; stack and output them
MOV AH,CS:[VIDEO_ATTR]
STOSW
LOOP BALOOP2
RET
BIN2ASC ENDP

;=============================================================================
; INITIALIZE installs or uninstalls the program.
;=============================================================================
ERRMSG1 DB "Usage: LITES [comport] [U]$"
ERRMSG2 DB "Not Installed$"
ERRMSG3 DB "Cannot Uninstall$"
ERRMSG4 DB "Already Installed$"
ERRMSG5 DB "Invalid COM Port$"
OUTTEXT DB "Uninstalled$"
INSTALLED DB 0

INITIALIZE PROC NEAR
ASSUME CS:CODE, DS:CODE
;
;See if a copy of LITES is already resident in memory.
;
CLD ;clear DF for string ops
MOV WORD PTR [BEGIN],0 ;initialize fingerprint
XOR BX,BX ;zero BX for start
MOV AX,CS ;keep CS value in AX
INIT1: INC BX ;increment search segment value
MOV ES,BX
CMP AX,BX ;not installed if current
JE PARSE1 ; segment is reached
MOV SI,OFFSET BEGIN ;search this segment for ASCII
MOV DI,SI ; fingerprint
MOV CX,16
REPE CMPSB
JNE INIT1 ;loop back if not found
MOV INSTALLED,1 ;set installed flag
;
;Parse the command line for entries.
;
PARSE1: MOV SI,81H ;point SI to command line
PARSE2: LODSB ;get a character
CMP AL,20H ;skip it if it's a space
JE PARSE2
CMP AL,0DH ;exit loop when a carriage
JE INSTALL ; return is encountered
CMP AL,"0" ;branch if numeral is found
JB ERROR1
CMP AL,"9"
JBE CHECK_COM
AND AL,0DFH ;capitalize the character
CMP AL,"U" ;branch to uninstall code if
JE UNINSTALL ; character is a "U"
;
;An error was encountered in parsing. Display error message and exit.
;
ERROR1: MOV DX,OFFSET ERRMSG1 ;load message address
ERROR2: MOV AH,9 ;display error message
INT 21H
MOV AX,4C01H ;exit with ERRORLEVEL = 1
INT 21H
;
;Make sure the COM port entered on the command line exists.
;
CHECK_COM: SUB AL,"1" ;normalize the entry
MOV BL,AL ;save it
INT 11H ;determine number of COM
SHR AH,1 ; ports installed
AND AH,07H
MOV DX,OFFSET ERRMSG5
CMP AH,BL ;exit on error if COM port
JNA ERROR2 ; number is invalid
MOV BYTE PTR COMPORT,BL ;save port designator
JMP SHORT INSTALL ;go to install routine
;
;Uninstall the program.
;
UNINSTALL: MOV DX,OFFSET ERRMSG2 ;error if program isn't
CMP INSTALLED,0 ; installed
JE ERROR2
CALL REMOVE ;call uninstall routine
MOV DX,OFFSET ERRMSG3 ;error if uninstall failed
JC ERROR2
MOV DX,OFFSET OUTTEXT ;display "Uninstalled"
MOV AH,9 ; message
INT 21H
MOV AX,4C00H ;exit with ERRORLEVEL = 0
INT 21H
;
;Make sure LITES isn't already installed, then get the UART base address.
;
INSTALL: MOV DX,OFFSET ERRMSG4 ;exit on error if program
CMP INSTALLED,0 ; is already installed
JNE ERROR2
MOV AX,40H ;get UART address from BIOS
MOV ES,AX ; data area using the port
XOR DI,DI ; number as an index into
MOV BX,COMPORT ; the table
SHL BX,1
MOV AX,WORD PTR ES:[DI][BX]
MOV COMPORT,AX
;
;Hook into interrupts 9h and 8h and deallocate the environment block.
;
MOV AX,3509H ;save old interrupt 9h vector
INT 21H
MOV WORD PTR INT09H,BX
MOV WORD PTR INT09H[2],ES
MOV AX,2509H ;then set the new 9h vector
MOV DX,OFFSET KBINT
INT 21H
MOV AX,3508H ;save old interrupt 8h vector
INT 21H
MOV WORD PTR INT08H,BX
MOV WORD PTR INT08H[2],ES
MOV AX,2508H ;then set the new 8h vector
MOV DX,OFFSET TIMERINT
INT 21H
MOV AX,DS:[2CH] ;deallocate the program's
MOV ES,AX ; environment block
MOV AH,49H
INT 21H
;
;Display copyright notice, then terminate and remain resident in memory.
;
MOV AH,9 ;display copyright and hotkey
MOV DX,OFFSET PROGRAM ; information
INT 21H
MOV AX,3100H
MOV DX,(OFFSET INITIALIZE - OFFSET CODE + 15 + 128) SHR 4
INT 21H
INITIALIZE ENDP

;-----------------------------------------------------------------------------
; REMOVE deallocates the memory block addressed by ES and restores the
; interrupt vectors displaced on installation.
; Entry: ES - segment to release
; Exit: CF clear - program uninstalled
; CF set - can't uninstall
;-----------------------------------------------------------------------------
REMOVE PROC NEAR
MOV CX,ES ;abort if either interrupt
MOV AX,3509H ; vector has been altered
INT 21H ; since installation
MOV AX,ES
CMP AX,CX
JNE REMOVE_ERROR
MOV AX,3508H
INT 21H
MOV AX,ES
CMP AX,CX
JNE REMOVE_ERROR
;
;Free memory given to the original program block.
;
MOV ES,CX ;Ask DOS to free it
MOV AH,49H
INT 21H
JC REMOVE_ERROR ;exit if call failed
;
;Restore the interrupt 9h and 8h vectors to their installation values.
;
PUSH DS
ASSUME DS:NOTHING
MOV AX,2509H ;restore interrupt 9h vector
LDS DX,ES:[INT09H]
INT 21H
MOV AX,2508H ;restore interrupt 8h vector
LDS DX,ES:[INT08H]
INT 21H
POP DS
ASSUME DS:CODE
NOT WORD PTR ES:[BEGIN] ;destroy ASCII fingerprint
CLC ;clear CF for exit
RET
REMOVE_ERROR: STC ;set CF to indicate program
RET ; couldn't be uninstalled
REMOVE ENDP

CODE ENDS
END BEGIN


  3 Responses to “Category : Communication (modem) tools and utilities
Archive   : LITES.ZIP
Filename : LITES.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/