home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Black Box 4
/
BlackBox.cdr
/
lan
/
netlight.arj
/
NETLIGHT.ASM
< prev
next >
Wrap
Assembly Source File
|
1991-01-15
|
8KB
|
332 lines
PAGE 90,132
TITLE NETLIGHT - Flashes a light to indicate Network traffic.
SUBTTL Based on an original idea by Apricot Computers Ltd.
COMMENT #
This terminate-and-stay-resident program attempts to flash a light on
the outside of an Apricot machine to indicate Network activity.
The particular light used depends on the model of computer.
On XEN-S and QI models, the LAN light is used.
On XEN-I models, the VOICE light is used.
On XEN (generic) models, the VOICE light is used.
Note that the standard NETLIGHT.COM, as provided by Apricot, only works
on the IBM-compatible models.
This program was written because of lack of support for my XEN, and the
large store overhead of NETLIGHT.COM (480 bytes). In addition, since the
standard version is a .COM file, it can not be AMLOADed unless at least 64K
is available for it. Since this version is a .EXE file, it can be AMLOADed
into as little as 804 bytes.
Because of careful coding (what some would say are very suspect techniques)
this program only keeps a mimimum of store when resident.
The actual figures are:
204 bytes on an Apricot XEN
176 bytes on an Apricot XEN-I, XEN-S or QI.
On other machines, the program aborts with an explanatory error message and
an ERRORLEVEL of 1.
Usage:
NETLIGHT [/n]
where the optional /n denotes that the light is to be turned on when hardware
interrupt n occurs. If the /n is omitted, the light is turned on when the
standard network interrupt (2Ah) is accessed by an application.
So, if the network software does not use interrupt 2Ah, and the network board
is attached to IRQ 12, then the command line should be:
NETLIGHT /12
On Apricot XEN machines, the /n parameter is ignored.
#
INCLUDE legal.inc
Lf EQU 0ah
Cr EQU 0dh
MINSES EQU 0 ;Non-zero to use int 2Ah.
;
DOSSEG
.MODEL small
.STACK 100
.CODE
.286
OldIntAddress equ 5Ch ;Holds address of Hardware Int.
OldInt08Address equ 60h ;Old Timer address.
NetLightPort equ 64h ;Port address to turn light on/off
NetLightCount equ 66h ;Timer counter for turning off.
CodeHolder equ 68h ;Address to hold routines in PSP.
;
; This routine turn on the light when a hardware Interrupt occurs.
;
IH_HARDWARE PROC FAR
push dx
push ax
mov dx,WORD PTR cs:NetLightPort
mov al,1
out dx,al
pop ax
pop dx
mov WORD PTR cs:NetLightCount,2
jmp DWORD PTR cs:[OldIntAddress]
IH_HARDWARE_L equ $-IH_HARDWARE
IH_HARDWARE ENDP
;
; This routine turns the light on when MINSES is activated.
;
IH_MINSES PROC FAR
if MINSES
cmp ah,50H
ja LOC_RET_1
endif
push dx
push ax
mov dx,WORD PTR cs:NetLightPort
mov al,1
out dx,al
mov WORD PTR cs:NetLightCount,2
pop ax
pop dx
LOC_RET_1:
jmp DWORD PTR cs:[OldIntAddress]
IH_MINSES_L equ $-IH_MINSES
IH_MINSES ENDP
;
; This routine turns the light OFF when the time is up.
IH_TIMER PROC FAR
cmp WORD PTR cs:NetLightCount,0
jz LOC_2
dec WORD PTR cs:NetLightCount
jnz LOC_2
push dx
push ax
mov dx,WORD PTR cs:NetLightPort
mov al,0
out dx,al
pop ax
pop dx
LOC_2:
jmp DWORD PTR cs:[OldInt08Address]
IH_TIMER_L equ $-IH_TIMER
IH_TIMER ENDP
;
; This routine turns the XEN voice light on when MINSES is activated.
;
AH_MINSES PROC FAR
cmp ah,50H
ja AH_LOC_RET_1
push ax
push bx
push dx
push es
xor ax,ax
mov es,ax
les bx,DWORD PTR es:[722h]
mov al,es:[bx+8] ;Get Write-only LED register copy.
or al,01h ;Add in the VOICE bit.
mov es:[bx+8],al
mov dx,0C00h ;Xen LED port address.
out dx,al
pop es
pop dx
pop bx
pop ax
mov WORD PTR cs:NetLightCount,5
AH_LOC_RET_1:
jmp DWORD PTR cs:[OldIntAddress]
AH_MINSES_L equ $-AH_MINSES
AH_MINSES ENDP
;
; This routine turns the XEN Voice light OFF when the time is up.
AH_TIMER PROC FAR
cmp WORD PTR cs:NetLightCount,0
jz AH_LOC_2
dec WORD PTR cs:NetLightCount
jnz AH_LOC_2
push ax
push bx
push dx
push es
xor ax,ax
mov es,ax
les bx,DWORD PTR es:[722h]
mov al,es:[bx+8] ;Get Write-only LED register copy.
and al,0FEh ;Remove the VOICE bit.
mov es:[bx+8],al
mov dx,0C00h ;Xen LED port address.
out dx,al
pop es
pop dx
pop bx
pop ax
AH_LOC_2:
jmp DWORD PTR cs:[OldInt08Address]
AH_TIMER_L equ $-AH_TIMER
AH_TIMER ENDP
TopOfCode LABEL BYTE ;Last address in TSR portion of code
ApricotData LABEL DWORD ;Pointer to "APRICOT" in ROM.
dw 0,0FFFCh
What db '@(#) ' ;For use by WHAT.EXE
SignOn db 'Apricot Netlight Utility V1.2',9
db '(C) 1991 by MicroExpansions Ltd.',Cr,Lf,'$'
Msg_Not_Apricot db 'Not a Suitable Machine!',Cr,Lf,'$'
; List of things to install:
OnVec db 2Ah ;Interrupt vector for LIGHT ON.
OnAddr dw IH_MINSES ;Address of routine for LIGHT ON.
OnLen dw IH_MINSES_L ;Length of routine for LIGHT ON.
OffVec db 08h ;Interrupt vector for LIGHT OFF
OffAddr dw IH_TIMER ;Address of routine for LIGHT OFF
OffLen dw IH_TIMER_L ;Length of routine for LIGHT OFF
PspSegment dw 0 ;For initialisation.
Initialise:
mov cs:PspSegment,ds ;Remember Address of PSP
push cs
pop ds
mov es,es:[2Ch] ;Get environment segment address.
mov ah,49h
int 21h ;Release the environment.
les bx,DWORD PTR cs:ApricotData
cmp WORD PTR ES:[bx],'PA'
jnz Not_Apricot
cmp WORD PTR ES:[bx+2],'IR'
jnz Not_Apricot
cmp WORD PTR ES:[bx+4],'OC'
jnz Not_Apricot
cmp BYTE PTR ES:[bx+6],'T'
jz Is_Apricot
Not_Apricot:
xor ax,ax
mov es,ax ;Point at low end of RAM.
cmp WORD PTR es:[404h],1234h
jne Not_Xen ;J if not Apricot Generic.
cmp BYTE PTR es:[401h],3
jne Not_Xen ;J if not XEN.
mov cs:OnAddr,OFFSET AH_MINSES
mov cs:OnLen,AH_MINSES_L ;Adjust to use Xen Voice on routine.
mov cs:OffAddr,OFFSET AH_TIMER
mov cs:OffLen,AH_TIMER_L
mov cs:OffVec,0FFh ;& 50 times a second timer.
jmp SHORT Use_MINSES ;Hook on to 2A routine ONLY.
Not_Xen:
lea dx,Msg_Not_Apricot
mov ah,9
int 21H
mov ax,4C01h
int 21H
Is_Apricot:
cmp BYTE PTR ES:[bx+8],4
jb Use_Voice
mov es,cs:PspSegment
mov WORD PTR es:NetLightPort,28h
jmp SHORT Use_Lan
Use_Voice:
mov es,cs:PspSegment
mov WORD PTR es:NetLightPort,0F003h
Use_Lan:
mov di,80H
mov cl,ES:[di]
mov ch,0
inc di
mov al,'/'
repnz scasb
jnz Use_MINSES
mov ax,0
mov bl,0ah
Scan_Number:
cmp BYTE PTR ES:[di],'0'
jb Scan_Exit
cmp BYTE PTR ES:[di],'9'
ja Scan_Exit
mul bl
add al,ES:[di]
sub al,'0'
inc di
loop Scan_Number
Scan_Exit:
cmp al,0FH
ja Use_MINSES
cmp al,7
ja Use_Slave
and al,7
add al,8
jmp SHORT Use_IRQ
Use_Slave:
and al,7
add al,70H
Use_IRQ:
mov cs:OnVec,al
mov cs:OnAddr,OFFSET IH_HARDWARE
mov cs:OnLen,IH_HARDWARE_L
jmp SHORT Hook_Int
Use_MINSES:
if MINSES
mov BYTE PTR cs:OnVec,2ah
else
mov BYTE PTR cs:OnVec,5Ch
endif
; Installation routine:
Hook_Int:
mov ah,35h
mov al,cs:OnVec
int 21h ;Get address of original routine.
push es
mov es,cs:PspSegment
mov WORD PTR es:OldIntAddress,bx
pop WORD PTR es:OldIntAddress+2;Save it in our PSP.
mov ah,35h
mov al,cs:OffVec ;Do same for Lights Off.
int 21h
push es
mov es,cs:PspSegment
mov WORD PTR es:OldInt08Address,bx
pop WORD PTR es:OldInt08Address+2
mov es,cs:PspSegment
mov di,CodeHolder
mov si,cs:OnAddr
mov cx,cs:OnLen
rep movsb ;Copy the ON routine to the PSP.
mov cs:OnLen,di ;Save address for OFF routine.
mov si,cs:OffAddr
mov cx,cs:OffLen
rep movsb ;Copy the OFF routine to the PSP.
mov cs:OffLen,di ;Remember address of last of the code.
;
mov ah,25h
mov al,cs:OnVec
mov dx,CodeHolder ;Set up the LIGHT ON code.
mov ds,cs:PspSegment
int 21h
mov ah,25h
mov al,cs:OffVec
mov dx,cs:OnLen ;Set up the LIGHT OFF code.
mov ds,cs:PspSegment
int 21h
push cs
pop ds
lea dx,SignOn
mov ah,9
int 21H
mov dx,cs:OffLen
add dx,15 ;Round up.
shr dx,4
mov ax,3100h
int 21H ;Stay resident.
;
END Initialise