Category : BBS Programs+Doors
Archive   : PHONEV4.ZIP
Filename : PHONEV4.ASM

 
Output of file : PHONEV4.ASM contained in archive : PHONEV4.ZIP
; Phone monitor - CFHSoftware
;
;
; To Assemble:
;
; MASM PHONE;
; LINK PHONE;
; EXE2BIN PHONE.EXE PHONE.COM
;
;
; THIS PROGRAM >MUST< BE RUN AS A .COM FILE
;
;
MS_DOS EQU 21H
MOD_STA EQU 6 ; Offset to 8250 modem-status port
RI EQU 01000000B ; Ring indicator
RLSD EQU 10000000B ; Received line signal det

BOOT_BLIND MACRO
MOV AX,0FFFFH ; Segment of boot code
PUSH AX ; Push on the stack
INC AX ; Make ax=0 (offset of boot code)
PUSH AX ; Push on the stack
RETF ; Far 'return' to boot code
ENDM

PSEG SEGMENT PARA PUBLIC 'CODE'
BEGIN EQU $
ASSUME CS:PSEG, DS:PSEG, ES:PSEG, SS:NOTHING
ORG 100H
MAIN PROC NEAR
START EQU $

STK_TOP LABEL WORD ; Where to start local stack
JMP INIT1
MAIN ENDP
;
signature db "CFH"
OLD_INT LABEL DWORD ; Old int 8
OLD_OFF DW ? ; Int 8 offset
OLD_SEG DW ? ; Int 8 segment

old_49 label dword
old_49_off dw ?
old_49_seg dw ?

RINGS DB 0
TRIGGER DB 9
LASTRNG DB ?
LASTCAR DB ?
tone dw 10010

CHK_PRT DW 0
SS_SAV DW ?
SP_SAV DW ?
BUSY DB 0
SOUND db 0
PSP dw 0

CHANGE_TRIGGER PROC FAR
PUSH DS

PUSH CS
POP DS

cmp ax, 69h
jnz nope
cmp cx, 69h
jnz nope

MOV BYTE PTR [RINGS], 0
MOV BYTE PTR [TRIGGER], BL
MOV AX, 1
MOV BX, 2
MOV CX, 3
MOV DX, 4
POP DS
IRET
nope:
cmp ax, "UN"
jne not_mine
cmp bx, "IN"
jne not_mine
cmp cx, "ST"
jne not_mine
cmp dx, "AL"
jne not_mine
mov bx, psp
mov cx, cs

MOV AX,2508H ; Patch INT 8
MOV DX, cs:old_off ; DS:DX = new vector
MOV DS, cs:old_seg
INT MS_DOS

MOV AX, 2549h
MOV DX, cs:old_49_off
MOV DS, cs:old_49_seg
INT MS_DOS

pop ds
IRET
not_mine:
cmp ax, "SO"
jne nope2
cmp bx, "UN"
jne nope2
cmp cx, "D!"
jne nope2
xor ah,ah
mov al, byte ptr sound
xor al,1
mov byte ptr sound, al
POP DS
IRET
nope2:
pop ds
jmp dword ptr cs:[old_49]
CHANGE_TRIGGER ENDP

;
; Check the modem status.
;
CHK_MOD PROC NEAR
PUSH DX ; Save register used
MOV DX,WORD PTR [CHK_PRT] ; Pick up modem-status port
ADD DX,MOD_STA
IN AL,DX ; Get modem status
AND AL,RI ; Check the bit
CMP BYTE PTR [LASTRNG],AL ; Same last time?
MOV BYTE PTR [LASTRNG],AL ; Set new status
JZ NODETR ; Yes, ignore.
CMP BYTE PTR [LASTRNG],0 ; Not ringing?
JNZ @f
in al, 61h
and al, 11111100b
out 61h, al
jmp nodetr


@@: INC BYTE PTR [RINGS] ; Number of rings
cmp sound, 1 ;is noise allowed?
jne nodetr ;if not, skip this stuff
mov al, 182
out 43h, al
mov ax, tone ; ringer tone
sub ax, 1000
mov tone, ax
out 42h, al
mov al, ah
out 42h, al
in al, 61h
or al, 3
out 61h, al
;
NODETR:
CMP BYTE PTR [LASTRNG],0 ; Not ringing?
MOV DX,WORD PTR [CHK_PRT] ; Pick up modem-status port
ADD DX,MOD_STA
IN AL,DX ; Get modem status
AND AL,RLSD ; Check the bit
MOV BYTE PTR [LASTCAR],AL ; Set new status
CMP BYTE PTR [LASTCAR],0 ; See if the carrier is off
JZ CAROFF ; Yes it is.
MOV BYTE PTR [RINGS],0 ; Carrier's on, zero the ring-count
mov word ptr [tone], 9010 ; and the tone
CAROFF: POP DX ; Restore registers used
RET
CHK_MOD ENDP
;
; Main Interrupt routine. This is patched to the clock interrupt at
; INT 08. After checking, it continues to main DOS routines.
;
INTER PROC FAR
CMP BYTE PTR CS:[TRIGGER],0 ;see if we are disabled
JZ @F
CMP BYTE PTR CS:[BUSY],0 ; See if we are re-entering
JZ NOBUSY ; No.
@@: JMP DWORD PTR CS:[OLD_int] ; Continue to old vector
;
NOBUSY: MOV BYTE PTR CS:[BUSY],0FFH ; Set busy flag
CLI
MOV WORD PTR CS:[SS_SAV],SS ; Save stack-segment
MOV WORD PTR CS:[SP_SAV],SP ; Save stack-pointer
PUSH CS
POP SS ; SS = CS
MOV SP,OFFSET STK_TOP ; Set up local stack
STI ; Allow interrupts
;
PUSH AX ; Free up a working register
PUSH DS ; Save data-segment

PUSH CS ; Establish addressability
POP DS ; DS = CS

CALL CHK_MOD
MOV AL, BYTE PTR [TRIGGER]
CMP BYTE PTR CS:[RINGS], AL ; modem rings > AL ? <<<<<<<<<<<<<<
JG CRASH ; Yes, crash the system.
POP DS
POP AX

CLI ; No interrupts
MOV SS,WORD PTR CS:[SS_SAV] ; Restore user stack
MOV SP,WORD PTR CS:[SP_SAV]
MOV BYTE PTR CS:[BUSY],0 ; Free up busy-flag
STI ; Allow interrupts
JMP DWORD PTR CS:[OLD_INT] ; Continue to old vector
CRASH:
BOOT_BLIND
INTER ENDP

TOP EQU $
;
; Iniitialization code. This space is used only once then given up.
;

; get_args
; gets the command line information from the psp
;ENTRY:
; di points to a 127 byte buffer into which you want the command line
; info copied.
;EXIT:
; cx contains the number of characters on the command line
; di points to the "buffer" area into which the info was copied
; all other registers' previous values ARE preserved (i.e. not destroyed)
get_args proc
push ax
push bx
push di
push si
push ds
mov ah, 62h
int 21h
push bx
mov cs:psp, bx
pop ds
mov si, 80h
lodsb
xor ch, ch
mov cl, al
push cx
rep movsb
pop cx
pop ds
pop si
pop di
pop bx
pop ax
ret
get_args endp

;Extract_args
;
;Searches for a '/' delimiter in arguments string followed by whatever
;character is sent in al, returns with di pointing to the first character
;following the character specified
;
;Entry: di - point to beginning of argument string
; al - contains character which follows the '/' delimiter
;
;Exit: CF set - not found
; CF clear - found
; di points to first char in arg string following
; /char
extract_args proc
mov cx, 127
topside:
jcxz notfound
push ax
mov ax, "/"
repne scasb
pop ax
jnz topside
got_slash:
scasb
jnz topside
found_it:
clc
ret
notfound:
stc
ret
extract_args endp

convert_to_binary_number proc
xor bx, bx
@@:
xor ax, ax
lodsb
cmp al, 57
jg non_numeric
sub ax, 48
jl non_numeric
push ax
mov ax, bx
mul ten
mov bx, ax
pop ax
add bx, ax
space: loop @b
non_numeric:
ret
convert_to_binary_number endp

uninstall proc near
mov ax, "UN"
mov bx, "IN"
mov cx, "ST"
mov dx, "AL"
int 49h

mov es, bx
mov es, es:[02ch]
mov ah, 49h
int ms_dos

mov es, cx
mov ah, 49h
int ms_dos

in al, 61h
and al, 11111100b
out 61h, al


mov dx, offset uninstallmsg
mov ah, 09h
int MS_DOS
mov ax, 4c00h
INT MS_DOS
uninstall endp

toggle_sound proc near
mov ax,"SO"
mov bx,"UN"
mov cx,"D!"
int 49h
cmp ax, 0
jz @f
mov dx, offset sound_on
mov ah, 09h
int MS_DOS
ret
@@: mov dx, offset sound_off
mov ah, 09h
int MS_DOS
ret
toggle_sound endp

INIT1 PROC NEAR
;
mov ax, cs
mov ds, ax
mov es, ax

mov di, offset args
call get_args
inc di
mov al, "u"
call extract_args
jc @f
push es
MOV AX,3549H ; Get INT49h vector
INT MS_DOS
MOV WORD PTR [OLD_49_off],BX
MOV WORD PTR [OLD_49_seg],ES

mov di, 103h
mov si, offset signature
mov cx, 3
repe cmpsb
pop es
jnz no_way
jmp already_installed

no_way: mov dx, offset not_installed
jmp show_msg_and_terminate

@@: mov di, offset args
inc di
mov al, "p"
call extract_args
jnc @f
jmp not_good
@@: mov al, byte ptr [di]
cmp al, "4"
jne @f
mov word ptr chk_prt, 02e8h ;COM4
jmp got_port
@@: cmp al, "2"
jne @f
mov word ptr chk_prt, 02f8h ;COM2
jmp got_port
@@: cmp al, "3"
jne @f
mov word ptr chk_prt, 03e8h ;COM3
jmp got_port
@@: cmp al, "1"
je default
jmp not_good
default:
mov word ptr chk_prt, 03f8h ;COM1...Default


got_port:
mov byte ptr [comnum], al
mov di, offset args
inc di
mov al, "r"
call extract_args
jnc @f
jmp not_good
@@: mov ax, word ptr [di]
mov word ptr [nums], ax
mov cx, 2
mov si, di
call convert_to_binary_number
cmp bx, 0
jz not_good
ring_default:
mov byte ptr [trigger], bl

MOV BYTE PTR CS:[BUSY],0 ; Free up busy-flag

push es

MOV AX,3508H ; Get clock vector
INT MS_DOS
MOV WORD PTR [OLD_OFF],BX
MOV WORD PTR [OLD_SEG],ES

MOV AX,3549H ; Get INT49h vector
INT MS_DOS
MOV WORD PTR [OLD_49_off],BX
MOV WORD PTR [OLD_49_seg],ES

mov di, 103h
mov si, offset signature
mov cx, 3
repe cmpsb
jz already_installed

MOV AX,2508H ; Patch INT 8
MOV DX,OFFSET INTER ; DS:DX = new vector
INT MS_DOS

MOV AX, 2549h
MOV DX, OFFSET CHANGE_TRIGGER
INT MS_DOS

MOV DX, OFFSET CFH
MOV AH, 09h
INT MS_DOS

pop es

mov di, offset args
inc di
mov al, "s"
mov sound,0
mov dx, offset sound_off
call extract_args
jc @f
mov sound, 1 ;found "/s", sound is allowed
mov dx, offset sound_on
@@: mov ah, 09h
int MS_DOS

;
; Terminate and stay-resident. Initialization-code is thrown away.
;
MOV DX,OFFSET TOP ; Last code to save
SHR DX,1 ; Div/2
SHR DX,1 ; Div/4
SHR DX,1 ; Div/8
SHR DX,1 ; Div/16
INC DX ; Round up
MOV AX,3100H
INT MS_DOS

not_good:
mov dx, offset bad_msg

show_msg_and_terminate:
mov ah, 09h
int 21h
terminate:
mov ax, 4c01h
int 21h

already_installed:
mov di, offset args
call get_args
inc di
mov al, "u"
call extract_args
jc @f
call uninstall
jmp terminate
@@: mov di, offset args
inc di
mov al, "s"
call extract_args
jc @f
call toggle_sound
jmp terminate
@@:
mov dx, offset twice
jmp show_msg_and_terminate

INIT1 ENDP
PRG_END EQU $
args db 127 dup(0)
ten dw 10
uninstallmsg db "Uninstallation complete",13,10,13,10,"$"
BAD_MSG DB 13,10,"Invalid command line ",13,10,13,10
DB "USAGE: PHONEV4 /p /r [/s] [/u]",13,10,13,10
DB " portnumber = 1-4",13,10
DB " ringcount = 1-99",13,10,13,10
DB " /s to enable/disable sound",13,10,13,10
DB " /u to Uninstall",13,10
DB 13,10,13,10,"$"
twice DB 13,10,"CFHSoftware's Phone monitor is already installed!",13,10,"$"
CFH DB 13,10,13,10,"PHONE v4 - BBS Crash monitor by "
DB "CFHSoftware",13,10,13,10
DB "Monitoring COM"
comnum db " and will reboot the system on ring number "
nums DB " ",13,10,13,10,"$"
sound_on db 13,10,"Sound is enabled",13,10,"$"
sound_off db 13,10,"Sound is disabled",13,10,"$"
not_installed db 13,10,"CFHSoftware's PHONE monitor not installed!!!!!",13,10,"$"
;
;
PSEG ENDS
END MAIN


  3 Responses to “Category : BBS Programs+Doors
Archive   : PHONEV4.ZIP
Filename : PHONEV4.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/