home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / assemblr / library / nor_asm / disklite.asm < prev    next >
Assembly Source File  |  1989-08-14  |  8KB  |  224 lines

  1. ;-----------------------------------------------------------------------;
  2. ; Disk Light creates an on-screen version of the disk light that is    ;
  3. ; usually on disk drives.  The difference, however, is that this light    ;
  4. ; will only be on as long as it takes to read or write to the disk.  In ;
  5. ; other words, it does not stay on while the disk spins without any    ;
  6. ; activity.                                ;
  7. ;                                    ;
  8. ; This program intercepts the INT 13h vector, which is the entry point    ;
  9. ; for the ROM BIOS's diskette routine.    On entry, Disklite displays    ;
  10. ; the drive letter in the upper-right corner of the screen, and     ;
  11. ; restores this section of the screen on exit.                ;
  12. ;-----------------------------------------------------------------------;
  13.  
  14.  
  15. ;-----------------------------------------------------------------------;
  16. ; Here is the DISKLITE's entry point.  It jumps to the initialization    ;
  17. ; routine which is at the very end so we can throw it out of memory    ;
  18. ; after we've used it.                            ;
  19. ;-----------------------------------------------------------------------;
  20. CODE_SEG    SEGMENT
  21.     ASSUME    CS:CODE_SEG, DS:CODE_SEG
  22.     ORG    100h            ;Reserve for DOS Program Segment Prefix
  23. BEGIN:    JMP    INIT_VECTORS
  24.  
  25. AUTHOR_STRING        DB    "Installed Disklite, by John Socha"
  26.             DB    0Dh, 0Ah, '$'
  27.  
  28.  
  29. ROM_DISKETTE_INT    DD    ?
  30.  
  31. DISPLAY_BASE        DW    ?
  32. OLD_DISPLAY_CHARS    DB    4 DUP (?)
  33. DISPLAY_CHARS        DB    'A', 70h, ':', 70h
  34. NUM_FLOPPIES        DB    ?        ;Number of floppy drives
  35.  
  36. UPPER_LEFT    EQU    (80 - 2) * 2        ;Offset to drive light
  37.  
  38. ;-----------------------------------------------------------------------;
  39. ; This procedure intercepts calls to the ROM BIOS's diskette I/O    ;
  40. ; vector, and it does several things:                    ;
  41. ;                                    ;
  42. ;    1. Checks to see if the screen is in an 80 column text mode    ;
  43. ;       so we can write to the screen.  Disklite won't write any    ;
  44. ;       characters to the screen if it's not in an 80 column mode.    ;
  45. ;    2. Displays the disk drive letter, "A:" for example, in the    ;
  46. ;       upper-right corner of the screen.                ;
  47. ;    3. Calls the old ROM BIOS routine to do the actual work.    ;
  48. ;    4. Restores the two characters in the upper-right corner of the ;
  49. ;       screen.                            ;
  50. ;-----------------------------------------------------------------------;
  51. INTERCEPT_DISKETTE_INT    PROC    FAR
  52.     Assume    CS:CODE_SEG, DS:Nothing
  53.     PUSHF                ;Save the old flags
  54.     PUSH    AX
  55.     PUSH    SI
  56.     PUSH    DI
  57.     PUSH    DS
  58.     PUSH    ES
  59.     CALL    GET_DISPLAY_BASE    ;Calculates the screen's display base
  60.     CALL    SAVE_SCREEN        ;Save two chars in upper right
  61.     CALL    DISPLAY_DRIVE_LETTER    ;Display the drive letter
  62.     POP    ES
  63.     POP    DS
  64.     POP    DI
  65.     POP    SI
  66.     POP    AX
  67.     POPF                ;Restore the old flags
  68.  
  69.     PUSHF                ;Simulate an INT call    
  70.     CALL    ROM_DISKETTE_INT    ; to the old ROM BIOS routine
  71.  
  72.     PUSHF                ;Save the returned flags
  73.     PUSH    AX
  74.     PUSH    SI
  75.     PUSH    DI
  76.     PUSH    DS
  77.     PUSH    ES
  78.     LEA    SI,OLD_DISPLAY_CHARS    ;Point to the old screen image
  79.     CALL    WRITE_TO_SCREEN     ;Restore two chars in upper right
  80.     POP    ES
  81.     POP    DS
  82.     POP    DI
  83.     POP    SI
  84.     POP    AX
  85.     POPF                ;Recover the returned flags
  86.     RET    2            ;Leave the status flags intact
  87. INTERCEPT_DISKETTE_INT    ENDP
  88.  
  89.  
  90. ;-----------------------------------------------------------------------;
  91. ; This procedure calculates the segment address for the display adapter ;
  92. ; that we're using.                            ;
  93. ;                                    ;
  94. ; Destroys:    AX                            ;
  95. ;-----------------------------------------------------------------------;
  96. GET_DISPLAY_BASE    PROC    NEAR
  97.     Assume    CS:CODE_SEG, DS:Nothing
  98.     INT    11h            ;Get the current equipment flag
  99.     AND    AX,30h            ;Isolate the display flags
  100.     CMP    AX,30h            ;Is this a monochrome display?
  101.     MOV    AX,0B800h        ;Set for a color graphics adapter
  102.     JNE    DONE_GET_BASE        ;Color graphics, base already set
  103.     MOV    AX,0B000h        ;Set for monochrome display
  104. DONE_GET_BASE:
  105.     MOV    DISPLAY_BASE,AX     ;Save this display base
  106.     RET
  107. GET_DISPLAY_BASE    ENDP
  108.  
  109.  
  110. ;-----------------------------------------------------------------------;
  111. ; This procedure saves the two characters in the upper right corner of    ;
  112. ; the screen so that we can restore them later.             ;
  113. ;                                    ;
  114. ; Destroys:    AX, SI, DI, DS, ES                    ;
  115. ;-----------------------------------------------------------------------;
  116. SAVE_SCREEN    PROC    NEAR
  117.     Assume    CS:CODE_SEG, DS:Nothing
  118.     MOV    SI,UPPER_LEFT        ;Read chars from the screen
  119.     LEA    DI,OLD_DISPLAY_CHARS    ;Write chars to local memory
  120.     MOV    AX,DISPLAY_BASE     ;Get segment address of screen
  121.     MOV    DS,AX
  122.     MOV    AX,CS            ;Point to the local data
  123.     MOV    ES,AX
  124.     CLD                ;Set for auto-increment
  125.     MOVSW                ;Move two characters
  126.     MOVSW
  127.     RET
  128. SAVE_SCREEN    ENDP
  129.  
  130.  
  131. ;-----------------------------------------------------------------------;
  132. ; This procedure displays the drive letter in the upper-right corner of ;
  133. ; the screen.                                ;
  134. ;                                    ;
  135. ; Destroys:    AX, SI                            ;
  136. ;-----------------------------------------------------------------------;
  137. DISPLAY_DRIVE_LETTER    PROC    NEAR
  138.     Assume    CS:CODE_SEG, DS:Nothing
  139.     MOV    AL,DL            ;Get the drive number
  140.     CMP    AL,80h            ;Is this a hard disk drive?
  141.     JB    DISPLAY_LETTER        ;No, then continue
  142.     SUB    AL,80h            ;Convert to hard disk number
  143.     ADD    AL,NUM_FLOPPIES     ;Convert to correct disk number
  144. DISPLAY_LETTER:
  145.     ADD    AL,'A'            ;Convert this into a drive letter
  146.     LEA    SI,DISPLAY_CHARS    ;Point to new char image
  147.     MOV    CS:[SI],AL        ;Save this character
  148.     CALL    WRITE_TO_SCREEN
  149.     RET
  150. DISPLAY_DRIVE_LETTER    ENDP
  151.  
  152.  
  153. ;-----------------------------------------------------------------------;
  154. ; This procedure writes two characters in the upper-right corner of the ;
  155. ; screen.                                ;
  156. ;                                    ;
  157. ; On entry:    CS:SI    Screen image for two characters         ;
  158. ; Destroys:    AX, SI, DI, DS, ES                    ;
  159. ;-----------------------------------------------------------------------;
  160. WRITE_TO_SCREEN     PROC    NEAR
  161.     Assume    CS:CODE_SEG, DS:Nothing
  162.     MOV    DI,UPPER_LEFT        ;Write chars to the screen
  163.     MOV    AX,DISPLAY_BASE     ;Get segment address of screen
  164.     MOV    ES,AX
  165.     MOV    AX,CS            ;Point to the local data
  166.     MOV    DS,AX
  167.     CLD                ;Set for auto-increment
  168.     MOVSW                ;Move two characters
  169.     MOVSW
  170.     RET
  171. WRITE_TO_SCREEN     ENDP
  172.  
  173. ;-----------------------------------------------------------------------;
  174. ; This procedure daisy-chains Disklite onto the diskette I/O vector    ;
  175. ; so that we can monitor the disk activity.                ;
  176. ;-----------------------------------------------------------------------;
  177. INIT_VECTORS    PROC    NEAR
  178.     Assume    CS:CODE_SEG, DS:CODE_SEG
  179.     LEA    DX,AUTHOR_STRING    ;Print out the author notice
  180.     MOV    AH,9            ;Display this string
  181.     INT    21h
  182.  
  183.     CALL    GET_NUM_FLOPPIES    ;See how many floppy drives installed
  184.  
  185.     MOV    AH,35h            ;Ask for an interrupt vector
  186.     MOV    AL,13h            ;Get the vector for INT 13h
  187.     INT    21h            ;Put vector in ES:BX
  188.     MOV    Word Ptr ROM_DISKETTE_INT,BX
  189.     MOV    Word Ptr ROM_DISKETTE_INT[2],ES
  190.  
  191.     MOV    AH,25h            ;Ask to set an interrupt vector
  192.     MOV    AL,13h            ;Set the INT 13h vector to DS:DX
  193.     MOV    DX,Offset INTERCEPT_DISKETTE_INT
  194.     INT    21h            ;Set INT 13h to point to our procedure
  195.     
  196.     MOV    DX,Offset INIT_VECTORS    ;End of resident portion
  197.     INT    27h            ;Terminate but stay resident
  198. INIT_VECTORS    ENDP
  199.  
  200.  
  201. ;-----------------------------------------------------------------------;
  202. ; This procedure determines how many logical floppy disk drives are in    ;
  203. ; the system.  The next drive letter will be used for hard disk drives. ;
  204. ;-----------------------------------------------------------------------;
  205. GET_NUM_FLOPPIES    PROC    NEAR
  206.     Assume    CS:CODE_SEG, DS:CODE_SEG
  207.     INT    11h            ;Get the equipment flag
  208.     MOV    CL,6
  209.     SHR    AX,CL            ;Right justify num of floppies
  210.     AND    AL,3            ;Strip all the other flags
  211.     INC    AL            ;Returns 0 for 1 floppy
  212.     CMP    AL,1            ;Is this a one floppy system?
  213.     JA    DONE_GET_FLOPPIES    ;No, then this is the correct number
  214.     MOV    AL,2            ;Yes, there are 2 logical drives
  215. DONE_GET_FLOPPIES:
  216.     MOV    NUM_FLOPPIES,AL     ;Save this number
  217.     RET
  218. GET_NUM_FLOPPIES    ENDP
  219.  
  220.  
  221. CODE_SEG    ENDS
  222.  
  223.     END    BEGIN
  224.