Category : Assembly Language Source Code
Archive   : NORTASM.ZIP
Filename : DISKLITE.ASM

 
Output of file : DISKLITE.ASM contained in archive : NORTASM.ZIP
;-----------------------------------------------------------------------;
; Disk Light creates an on-screen version of the disk light that is ;
; usually on disk drives. The difference, however, is that this light ;
; will only be on as long as it takes to read or write to the disk. In ;
; other words, it does not stay on while the disk spins without any ;
; activity. ;
; ;
; This program intercepts the INT 13h vector, which is the entry point ;
; for the ROM BIOS's diskette routine. On entry, Disklite displays ;
; the drive letter in the upper-right corner of the screen, and ;
; restores this section of the screen on exit. ;
;-----------------------------------------------------------------------;


;-----------------------------------------------------------------------;
; Here is the DISKLITE's entry point. It jumps to the initialization ;
; routine which is at the very end so we can throw it out of memory ;
; after we've used it. ;
;-----------------------------------------------------------------------;
CODE_SEG SEGMENT
ASSUME CS:CODE_SEG, DS:CODE_SEG
ORG 100h ;Reserve for DOS Program Segment Prefix
BEGIN: JMP INIT_VECTORS

AUTHOR_STRING DB "Installed Disklite, by John Socha"
DB 0Dh, 0Ah, '$'


ROM_DISKETTE_INT DD ?

DISPLAY_BASE DW ?
OLD_DISPLAY_CHARS DB 4 DUP (?)
DISPLAY_CHARS DB 'A', 70h, ':', 70h
NUM_FLOPPIES DB ? ;Number of floppy drives

UPPER_LEFT EQU (80 - 2) * 2 ;Offset to drive light

;-----------------------------------------------------------------------;
; This procedure intercepts calls to the ROM BIOS's diskette I/O ;
; vector, and it does several things: ;
; ;
; 1. Checks to see if the screen is in an 80 column text mode ;
; so we can write to the screen. Disklite won't write any ;
; characters to the screen if it's not in an 80 column mode. ;
; 2. Displays the disk drive letter, "A:" for example, in the ;
; upper-right corner of the screen. ;
; 3. Calls the old ROM BIOS routine to do the actual work. ;
; 4. Restores the two characters in the upper-right corner of the ;
; screen. ;
;-----------------------------------------------------------------------;
INTERCEPT_DISKETTE_INT PROC FAR
Assume CS:CODE_SEG, DS:Nothing
PUSHF ;Save the old flags
PUSH AX
PUSH SI
PUSH DI
PUSH DS
PUSH ES
CALL GET_DISPLAY_BASE ;Calculates the screen's display base
CALL SAVE_SCREEN ;Save two chars in upper right
CALL DISPLAY_DRIVE_LETTER ;Display the drive letter
POP ES
POP DS
POP DI
POP SI
POP AX
POPF ;Restore the old flags

PUSHF ;Simulate an INT call
CALL ROM_DISKETTE_INT ; to the old ROM BIOS routine

PUSHF ;Save the returned flags
PUSH AX
PUSH SI
PUSH DI
PUSH DS
PUSH ES
LEA SI,OLD_DISPLAY_CHARS ;Point to the old screen image
CALL WRITE_TO_SCREEN ;Restore two chars in upper right
POP ES
POP DS
POP DI
POP SI
POP AX
POPF ;Recover the returned flags
RET 2 ;Leave the status flags intact
INTERCEPT_DISKETTE_INT ENDP


;-----------------------------------------------------------------------;
; This procedure calculates the segment address for the display adapter ;
; that we're using. ;
; ;
; Destroys: AX ;
;-----------------------------------------------------------------------;
GET_DISPLAY_BASE PROC NEAR
Assume CS:CODE_SEG, DS:Nothing
INT 11h ;Get the current equipment flag
AND AX,30h ;Isolate the display flags
CMP AX,30h ;Is this a monochrome display?
MOV AX,0B800h ;Set for a color graphics adapter
JNE DONE_GET_BASE ;Color graphics, base already set
MOV AX,0B000h ;Set for monochrome display
DONE_GET_BASE:
MOV DISPLAY_BASE,AX ;Save this display base
RET
GET_DISPLAY_BASE ENDP


;-----------------------------------------------------------------------;
; This procedure saves the two characters in the upper right corner of ;
; the screen so that we can restore them later. ;
; ;
; Destroys: AX, SI, DI, DS, ES ;
;-----------------------------------------------------------------------;
SAVE_SCREEN PROC NEAR
Assume CS:CODE_SEG, DS:Nothing
MOV SI,UPPER_LEFT ;Read chars from the screen
LEA DI,OLD_DISPLAY_CHARS ;Write chars to local memory
MOV AX,DISPLAY_BASE ;Get segment address of screen
MOV DS,AX
MOV AX,CS ;Point to the local data
MOV ES,AX
CLD ;Set for auto-increment
MOVSW ;Move two characters
MOVSW
RET
SAVE_SCREEN ENDP


;-----------------------------------------------------------------------;
; This procedure displays the drive letter in the upper-right corner of ;
; the screen. ;
; ;
; Destroys: AX, SI ;
;-----------------------------------------------------------------------;
DISPLAY_DRIVE_LETTER PROC NEAR
Assume CS:CODE_SEG, DS:Nothing
MOV AL,DL ;Get the drive number
CMP AL,80h ;Is this a hard disk drive?
JB DISPLAY_LETTER ;No, then continue
SUB AL,80h ;Convert to hard disk number
ADD AL,NUM_FLOPPIES ;Convert to correct disk number
DISPLAY_LETTER:
ADD AL,'A' ;Convert this into a drive letter
LEA SI,DISPLAY_CHARS ;Point to new char image
MOV CS:[SI],AL ;Save this character
CALL WRITE_TO_SCREEN
RET
DISPLAY_DRIVE_LETTER ENDP


;-----------------------------------------------------------------------;
; This procedure writes two characters in the upper-right corner of the ;
; screen. ;
; ;
; On entry: CS:SI Screen image for two characters ;
; Destroys: AX, SI, DI, DS, ES ;
;-----------------------------------------------------------------------;
WRITE_TO_SCREEN PROC NEAR
Assume CS:CODE_SEG, DS:Nothing
MOV DI,UPPER_LEFT ;Write chars to the screen
MOV AX,DISPLAY_BASE ;Get segment address of screen
MOV ES,AX
MOV AX,CS ;Point to the local data
MOV DS,AX
CLD ;Set for auto-increment
MOVSW ;Move two characters
MOVSW
RET
WRITE_TO_SCREEN ENDP

;-----------------------------------------------------------------------;
; This procedure daisy-chains Disklite onto the diskette I/O vector ;
; so that we can monitor the disk activity. ;
;-----------------------------------------------------------------------;
INIT_VECTORS PROC NEAR
Assume CS:CODE_SEG, DS:CODE_SEG
LEA DX,AUTHOR_STRING ;Print out the author notice
MOV AH,9 ;Display this string
INT 21h

CALL GET_NUM_FLOPPIES ;See how many floppy drives installed

MOV AH,35h ;Ask for an interrupt vector
MOV AL,13h ;Get the vector for INT 13h
INT 21h ;Put vector in ES:BX
MOV Word Ptr ROM_DISKETTE_INT,BX
MOV Word Ptr ROM_DISKETTE_INT[2],ES

MOV AH,25h ;Ask to set an interrupt vector
MOV AL,13h ;Set the INT 13h vector to DS:DX
MOV DX,Offset INTERCEPT_DISKETTE_INT
INT 21h ;Set INT 13h to point to our procedure

MOV DX,Offset INIT_VECTORS ;End of resident portion
INT 27h ;Terminate but stay resident
INIT_VECTORS ENDP


;-----------------------------------------------------------------------;
; This procedure determines how many logical floppy disk drives are in ;
; the system. The next drive letter will be used for hard disk drives. ;
;-----------------------------------------------------------------------;
GET_NUM_FLOPPIES PROC NEAR
Assume CS:CODE_SEG, DS:CODE_SEG
INT 11h ;Get the equipment flag
MOV CL,6
SHR AX,CL ;Right justify num of floppies
AND AL,3 ;Strip all the other flags
INC AL ;Returns 0 for 1 floppy
CMP AL,1 ;Is this a one floppy system?
JA DONE_GET_FLOPPIES ;No, then this is the correct number
MOV AL,2 ;Yes, there are 2 logical drives
DONE_GET_FLOPPIES:
MOV NUM_FLOPPIES,AL ;Save this number
RET
GET_NUM_FLOPPIES ENDP


CODE_SEG ENDS

END BEGIN


  3 Responses to “Category : Assembly Language Source Code
Archive   : NORTASM.ZIP
Filename : DISKLITE.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/