home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Black Box 4
/
BlackBox.cdr
/
lan
/
lanutsrc.arj
/
MESSAGE.ASM
< prev
next >
Wrap
Assembly Source File
|
1991-03-13
|
11KB
|
420 lines
INCLUDE \ASM\INCLUDE\BIOS.INC
INCLUDE DEFS.INC
SAVELEN EQU 160 ; Number of words to save from scn.
BIOS_SEG EQU 0040H
msv SEGMENT
ASSUME CS:msv
ASSUME DS:msv
ASSUME ES:msv
ASSUME SS:NOTHING
ORG 0
SEG_ORG EQU $
ORG 100h
main PROC FAR
start: jmp init ; Do initialization section
;*******************************************************************
; LANOS VECTOR TSR portion of Message handler --
; The LANOS portion simply increments a message received flag and
; exits, leaving the actual processing of the message to an
; interrupt.
;*******************************************************************
MSV_entry: jmp first ; skip data area
; LANOS MSR handler variables
tsr_name db '■SM'
color db 70h
msg_flag db 0
msg_time dd ?
old_msr dd ?
; Pop up Message Service variables
from db 'From: ',0
time db 'Time: ',0
busy db 0 ; TSR status flag
c_pos dw ? ; old cursor location
old_vector2 dd ? ; address of previous kbd ISR
buffer message_buffer <> ; local message buffer
screen_data dw SAVELEN dup (?) ; storage for old screen data
old_stk_seg dw ? ; Calling program's stack info
old_b_ptr dw ?
old_stk_ptr dw ?
new_stk_seg dw ?
new_stk_ptr dw OFFSET TOS
dw 80 dup (?) ; local stack data area
TOS equ $
;************************************************************************
; Start of actual LANOS message handler
;************************************************************************
first:
; Save current clock count
cli ; forbid additional interrupts
push ax ; save needed registers
push ds
push si
mov ax,BIOS_SEG
mov ds,ax ; Point ds to BIOS data area
mov si,006Ch ; Offset of master clock dw.
mov ax,[si] ; get the first word
mov word ptr cs:msg_time, ax
inc si ; get the second word
inc si
mov ax,[si]
mov word ptr cs:msg_time + 2,ax
pop si
pop ds
pop ax
inc cs:msg_flag ; set the message received flag
call_old_msr:
sti ; allow interrupts
jmp cs:old_msr
;*****************************************************************************
; Interrupt E0 handler --- this is apparently something that LANtastic uses
; internally to indicate when DOS is safe.
;*****************************************************************************
DOSFREE:
PUSHF
CALL CS:old_vector2 ; give everyone else a chance...
cmp cs:msg_flag,0 ; have our services been requested?
jz Done_E0 ; If not, skip this stuff
CMP CS:busy,0 ; Are we already busy?
JNZ Done_E0 ; If so, skip this stuff
; Activate the pop up routine
inc cs:busy ; set busy flag
call pop_up
mov cs:msg_flag,0 ; reset received flag
dec cs:busy ; reset busy flag
Done_E0:
IRET
;***********************************************************************
; Pop-up message handler
; When we're popped up, an Esc keypress will take us back to normal
; processing
;***********************************************************************
pop_up PROC near
@NewStack ; replace stack
; Set all segment regs to CS for convenience
set_seg:
push cs ; point all segregs to CS
push cs
pop ds
pop es
; Save the bottom line of the screen and highlight the message area
save_cur:
mov ah,03 ; get old cursor info
xor bx,bx
int 10h ; do it;
mov cs:c_pos,dx ; save old cursor location
mov di,OFFSET screen_data
mov dx,1700h ; point to line 23
mov cx,2 ; number of lines to move
save_row:
push cx ; save current row count
mov cx,80 ; number of columns to move
save_col:
call CURSOR ; move cursor to proper spot
push cx ; save char count
push dx
@GetChAtr 0 ; get the current character
stosw ; save current char/attr
@PutChAtr 32,color,0,1 ; highlight current char position
pop dx
inc dl ; increment cursor position
pop cx ; restore char count
loop save_col ; go back for next char
xor dl,dl ; set cursor to start of next row
inc dh
pop cx ; restore row count
loop save_row ; go back for next row
; Get the address of the last unsolicited message
mov di,OFFSET buffer
mov ax,5F99H
int 21h
; Display the message text
mov dx,1700h ; point to line 23
call CURSOR
mov di,OFFSET buffer.MB_text
call PRT_STR ; Display the message text
mov dx,1807h ; row 24, column 7
call CURSOR
mov di,OFFSET buffer.MB_originator
call PRT_STR ; Display sender's name
; display text prompts
push cs ; point ES to current seg
pop es
mov dx,1800h ; line 24, column 0
call CURSOR
mov di,OFFSET from ; print from prompt
call PRT_STR
mov dx,1818h ;line 24, column 24
call CURSOR
mov di,OFFSET time ; print time prompt
call PRT_STR
; Display the time
; load the clock count for use by DIV
mov ax,word ptr msg_time
mov dx,word ptr msg_time + 2
push ax ; save count for easy access
push dx
; calculate number of minutes since midnight
mov cx,1080
div cx
; calculate error in clock ticks
mov cx,12
mul cx
mov bx,dx ; save high word in bx
mov cx,ax ; save low word in cx
; subtract the error from the original clock tick number
pop dx ; High order word
pop ax ; low order word
sub ax,cx ; subtract low order word
sbb dx,bx ; subtract high order word
; calculate the new, improved number of minutes since midnight
mov cx,1080
div cx
; calculate hours since midnight
; leaves hours in AL and minutes in AH
mov cl,60
div cl
push ax ; Save result
mov dx,181Eh ; row 24, column 30
call CURSOR
mov bl,al ; Display hour
call PRT_TIME
mov al,':' ; display delimiter
call PUT_CHAR
pop ax
mov bl,ah ; Display minute
call PRT_TIME
; Wait for the user to press escape
K_WAIT:
xor ax,ax ; Read keyboard char fn.
int 16h
cmp al,27 ; is it an escape?
jne K_WAIT ; If not, try again
; Restore the bottom line of the screen
rest_cur:
mov si,OFFSET screen_data
mov dx,1700h ; point to line 23
mov cx,2 ; number of lines to move
rest_row:
push cx ; save current row count
mov cx,80 ; number of columns to move
rest_col:
call CURSOR ; move cursor to proper spot
lodsw ; get the word to save
push cx ; save char count
@PutChAtr al,ah,0,1 ; write character/attribute
inc dl ; increment cursor position
pop cx ; restore char count
loop rest_col ; go back for next char
xor dl,dl ; set cursor to start of next row
inc dh
pop cx ; restore row count
loop rest_row ; go back for next row
mov dx,c_pos ; restore old cursor position
call CURSOR
; Restore calling program's stack setup
BYPASS:
@OldStack ; restore caller's stack
ret ; return to caller
pop_up ENDP
;*********************************************************************
; Subroutines
;********************************************************************
; Move cursor -- row in dh, col in dl
CURSOR PROC NEAR
push ax
push bx
push cx
@SetCurPos dl,dh,0
pop cx
pop bx
pop ax
ret
CURSOR ENDP
PRT_STR PROC NEAR
;
; Write ASCIIZ string pointed to by ES:DI at current cursor position
;
L3:
mov al,es:[di] ; get the character
or al,al ; See if it's a zero
jz short L4 ; Yes- we're done
call PUT_CHAR ; display the character
inc di ; get the next char
jmp short L3
L4:
ret
PRT_STR ENDP
;
; Displays a number between 0 and 99 on the screen, at the location
; pointed to by es:di. Note that the number must be between 0 and 100.
; The number to be displayed must be in bx.
;
PRT_TIME PROC NEAR
mov ax,bx ; extract the 10's digit
xor ah,ah ; clear MSB so that we limit range
mov dl,10
div dl
mov dx,ax ; save result
add al,30H ; convert quotient to ASCII
call PUT_CHAR ; print the digit
mov al,dh ; get remainder (1's digit)
add al,30H ; convert to ASCII
call PUT_CHAR ; print the digit
ret
PRT_TIME ENDP
;Print a character (the one in AL, hopefully) and advance the cursor
PUT_CHAR PROC NEAR
push dx
push di
mov ah,0Eh ; write char in tty mode
mov bx,7 ; video page 0, gfx foreground 7
int 10h ; display the character
pop di
pop dx
ret
PUT_CHAR ENDP
LAST_BYTE EQU $
;
; Initialization -- thrown away after load
;
title1 db "SoftMagic Resident Message Handler V1.61 for LANtastic",13,10,0
title2 db "Copyright 1989 by SoftMagic, Inc. All rights Reserved.",13,10,0
title3 db " LANtastic is a trademark of Artisoft, Inc.",13,10,0
title4 db 13,10,"The SoftMagic Resident Message Handler is already installed.",13,10,0
IFDEF SHAREWARE
title5 db "Thanks for trying this unregistered Shareware edition.",7,13,10,0
ENDIF
init: mov cs:busy,1 ; prevent activation
@NewStack ; Set up local stack
; Display title messge
mov di,OFFSET title1
call PRT_STR
mov di,OFFSET title2
call PRT_STR
mov di,OFFSET title3
call PRT_STR
IFDEF SHAREWARE
mov di,OFFSET title5
call PRT_STR
ENDIF
; Get old LANOS message handler vector
mov ax,5FE2h
int 21h
mov word ptr old_msr,bx ; Save the location of the old vector
mov word ptr old_msr+2,es
; See if our message handler is already loaded
mov di,bx
add di,3 ; Point to name area
cmp byte ptr es:[di],254 ; Look for our signature byte
jnz SHORT install ; is it there?
mov ax,ds
mov es,ax
mov di,OFFSET title4
call PRT_STR
mov ah,4Ch ; Terminate w/return function
int 21h ; End the program
;
; Replace the LANOS message service
;
install:
mov ax,cs
mov es,ax
mov ax,5FE3h
mov bx,OFFSET MSV_entry
int 21H
;
; Replace LANtastic's internal DOS free vector
;
MOV AX,5FE0H
INT 21H ; GET THE DOS FREE VECTOR
MOV WORD PTR old_vector2,BX
MOV WORD PTR old_vector2+2,ES
;
; Set vector to our routine
;
push cs
pop es
MOV BX,OFFSET DOSFREE
MOV AX,5FE1H
INT 21H
; Terminate and stay resident
@OldStack ; Restore caller's stack
mov cs:busy, 0 ; Enable pop-up
mov dx,(offset LAST_BYTE - SEG_ORG + 15) shr 4
mov ah,31h ; free memory and leave
int 21h
main ENDP
msv ENDS
END start