home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / SOURCE.ZIP / DELZ.ASM < prev    next >
Assembly Source File  |  1986-02-05  |  15KB  |  328 lines

  1. INTERRUPTS      SEGMENT AT 0H
  2.         ORG     9H*4            ;holds the address of its service routine
  3. KEYBOARD_INT    LABEL   DWORD  
  4.         ORG     21H*4           ;This is to use INT 21H
  5. INT_21H         LABEL   DWORD   ;which is the DOS function call interrupt
  6. INTERRUPTS      ENDS
  7.  
  8. ROM_BIOS_DATA   SEGMENT AT 40H  ;BIOS statuses held here, also keyboard buffer
  9.  
  10.         ORG     1AH
  11.         HEAD DW      ?                  ;Unread chars go from Head to Tail
  12.         TAIL DW      ?
  13.         BUFFER       DW      16 DUP (?)         ;The buffer itself
  14.         BUFFER_END   LABEL   WORD
  15.  
  16. ROM_BIOS_DATA   ENDS
  17.  
  18. CODE_SEG        SEGMENT
  19.         ASSUME  CS:CODE_SEG
  20.         ORG     100H            ;ORG = 100H to make this into a 
  21.                                 ;".com" file
  22. FIRST:  JMP     LOAD_INT_21H
  23.  
  24.         COPY_RIGHT      DB      '(C)1985 S Holzner'
  25.         BYPASS_FLAG     DB      0       ;Bypass our checking for #? 1=Yes
  26.         ZERO_FLAG       DB      0       ;Was there a zero in filename? 1=Yes
  27.         CR_FLAG         DB      0
  28.         DTA             DD      ?       ;The old disk transfer area address
  29.         OLD_INT_21H     DD      ?       ;Address INT 21H uses normally
  30.         OLD_KEYBOARD_INT        DD      ?       ;Location of old kbd interrupt
  31.         COUNT           DW      ?
  32.         FCB_OFFSET      DW      ?       ;Offset of given filename to be deleted
  33.         FCB_SEG         DW      0       ;Segment address of the same.        
  34.         COMMAND_INDEX   DW      0
  35.         DEL_Z           DB      'DEL/Z',0
  36.         CRLF    DB      13,10,'$'       ;Carriage return, linefeed for messages
  37.         MSG     DB      ' ZEROED AND DELETED.',13,10,'$'      ;The message
  38.         ERR     DB      'Error deleting $'              ;Error message
  39.  
  40. DELZ    PROC    FAR    ;The function call interrupt will now come here.
  41.  
  42.         PUSHF                   ;Save flags first (will get changed by CMPs)
  43.         CMP     AH,13H          ;Are we deleting?
  44.         JNE     JUMP            ;No, jump to function call Int and do not return
  45.         CMP     ZERO_FLAG,1     ;Are we supposed to zero?
  46.         JNE     JUMP            ;If not, don't
  47.         TEST    BYPASS_FLAG,1   ;We are deleting. Is bypass on?
  48.         JZ      DEL_CHECK       ;No, check if we should delete file.
  49. JUMP:   POPF                    ;Restore flags
  50.         JMP     OLD_INT_21H     ;Jump to function call Int. (CALL won't work).
  51. DEL_CHECK:      ;DS:DX are pointing to filename to be deleted (from delete call)
  52.         PUSH    BX              ;Save all used registers to be polite
  53.         PUSH    CX
  54.         PUSH    DX
  55.         PUSH    SI
  56.         PUSH    DI
  57.         PUSH    AX    ;Save AX last since will pop first and return status in it
  58.  
  59.         MOV     FCB_OFFSET,DX   ;Save address of the file-to-be-deleted's FCB   
  60.         MOV     FCB_SEG,DS      ;Ditto for the segment address
  61.  
  62.         MOV     AH,2FH          ;Now get Disk Transfer Area (DTA) address
  63.         INT     21H             ;This will work since AH is not equal to 13H
  64.  
  65.         MOV     DTA,BX          ;Store DTA address Low part
  66.         MOV     DTA[2],ES       ;Ditto High part
  67.         PUSH    DS              ;Save file-to-be-deleted's FCB's Segment address
  68.         MOV     AH,1AH          ;Put the new DTA in our Program Segment Prefix,
  69.         MOV     DX,80H          ; CS:0080H (CS came from INT 21H vector we set)
  70.         PUSH    CS              ;Now move DS into CS to set DTA
  71.         POP     DS
  72.         INT     21H             ;Set Disk Transfer Area (DTA)
  73.         POP     DS              ;Restore Segment address of given file's FCB
  74.  
  75.         MOV     DX,FCB_OFFSET   ;Restore the given file's FCB's address low part
  76.         MOV     AH,11H          ;Ask for DOS service 11H, which asks for the 
  77.         INT     21H             ; first match to the given file's FCB
  78.  
  79.         TEST    AL,1            ;Was a match found?
  80.         JZ      TOP             ;Yes, start checking if we should delete.
  81.         POP     AX              ;No, return status 0FF (not found) in AL
  82.         MOV     AL,0FFH
  83.         JMP     NONE_FOUND      ;Over and out.
  84. TOP:    
  85.         MOV     SI,81H          ;the matching file's FCB is in DTA from search
  86.         MOV     DI,0C0H         ;We will move the name to print and scan for #
  87.         MOV     CX,0BH          ;11 characters per file
  88.         PUSH    DS              ;Get ready for string move, set up DS and ES
  89.         PUSH    CS              ;Set them both to CS (use program segment
  90.         POP     DS              ; prefix area)
  91.         MOV     DX,80H          ;Point to match to open file
  92.         MOV     AH,0FH          ;Select the correct DOS call
  93.         INT     21H
  94.         CMP     AL,0            ;If error opening file, exit
  95.         JNE     ERROR
  96.         MOV     BX,80H          ;Set record size to 512
  97.         MOV     WORD PTR [BX+14],512
  98.         MOV     AX,[BX+16]              ;Find the file's size in sectors
  99.         XOR     DX,DX                   
  100.         TEST    AX,511                  ;Do we have to add an add'l sector?
  101.         JZ      SHIF                    ;No, do the shift
  102.         INC     DX                      ;Yes, add 1
  103. SHIF:   MOV     CL,9                    ;Divide by 512
  104.         SHR     AX,CL
  105.         MOV     COUNT,AX                ;Store in Count
  106.         ADD     COUNT,DX                ;And add possible add'l sector
  107.         MOV     AX,[BX+18]              ;Now for the high part of size
  108.         MOV     CL,7                    ;Mult by 65536 div by 512
  109.         SHL     AX,CL
  110.         ADD     COUNT,AX                ;And add to what we already have
  111.         MOV     DX,80H                  ;Now prepare for sequential write
  112.         MOV     CX,COUNT                ;Do COUNT sectors
  113.         MOV     AH,15H
  114. FILL:   INT     21H                     ;Fill with copies of this prog.
  115.         CMP     AL,0                    ;Error writing?
  116.         JNE     ERROR                   ;Yes, jump to ERROR
  117.         LOOP    FILL                    ;No, go back for next one
  118.         MOV     AH,10H                  ;Close the file now.
  119.         INT     21H
  120.         CMP     AL,0                    ;Error closing?
  121.         JNE     ERROR                   ;Yep, go to ERROR
  122.         MOV     AH,13H                  ;No, delete the file at last (Whew)
  123.         MOV     BYPASS_FLAG,1           ;Don't intercept this call
  124.         INT     21H
  125.         MOV     BYPASS_FLAG,0
  126.         CMP     AL,0                    ;Everything OK?
  127.         JNE     ERROR                   ;No, go to ERROR
  128.         CALL    PRINT_NAME              ;Yes, print the name
  129.         LEA     DX,MSG                  ;And the zeroed message
  130.         MOV     AH,9
  131.         INT     21H
  132.         JMP     SAVE
  133. ERROR:  MOV     AH,10H                  ;First make sure file is closed
  134.         INT     21H
  135.         LEA     DX,ERR                  ;Then print error message and go on
  136.         MOV     AH,9                    ; to next file
  137.         INT     21H
  138.         CALL    PRINT_NAME
  139. SAVE:   POP     DS              ;Get segment of original given file's FCB
  140.         MOV     DX,FCB_OFFSET   ;Search for next match -- point to original FCB
  141.         MOV     AH,12H          ;Search for next match
  142.         INT     21H             
  143.         TEST    AL,1            ;Was a match found?
  144.         JNZ     OUT
  145.         JMP     TOP
  146.  
  147. OUT:    POP     AX              ;At least one file deleted, set AL acordingly,
  148.         MOV     AL,0            ; which means set it to 0
  149. NONE_FOUND:
  150.         PUSH    DS              ;Now we have to reset the Disk Transfer Area
  151.         PUSH    AX              ;Save AX since it contains success status
  152.         MOV     AH,1AH          ;Function call 1AH will do want we want
  153.         MOV     DX,DTA[2]       ;Get original DTA's segment into DS
  154.         MOV     DS,DX
  155.         MOV     DX,DTA          ;Now get offset inside that segment of same
  156.         INT     21H             ;And reset DTA
  157.         POP     AX              ;Restore AX with status
  158.         POP     DS              ;And DS with original DS
  159.  
  160.         POP     DI              ;And restore the other registers 
  161.         POP     SI
  162.         POP     DX
  163.         POP     CX
  164.         POP     BX
  165.         POPF                    ;We musn't forget our original PUSHF
  166.         IRET                    ;An interrupt deserves an IRET
  167.  
  168. DELZ    ENDP            ;And that's it 
  169.  
  170. PRINT_NAME      PROC    NEAR    ;This small subroutine just prints
  171.         MOV     BX,80H+1        ; file's name from the FCB
  172.         MOV     AH,2            ;Use DOS service 2
  173.         MOV     CX,11           ;Print all 11 letters
  174. PRINT:  MOV     DL,[BX]         ;Printing loop
  175.         INT     21H
  176.         INC     BX              ;Get next letter
  177.         LOOP    PRINT
  178.         RET                     ;And return
  179. PRINT_NAME      ENDP
  180.  
  181. READ_KEY   PROC    NEAR            ;The keyboard interrupt will now come here.
  182.         ASSUME  CS:CODE_SEG
  183.         PUSH    AX              ;Save the used registers for good form
  184.         PUSH    BX
  185.         PUSH    CX
  186.         PUSH    DX
  187.         PUSH    DI
  188.         PUSH    SI
  189.         PUSH    DS
  190.         PUSHF                   ;First, call old keyboard interrupt
  191.         CALL    OLD_KEYBOARD_INT
  192.  
  193.         ASSUME  DS:ROM_BIOS_DATA        ;Examine the char just put in
  194.         MOV     BX,ROM_BIOS_DATA
  195.         MOV     DS,BX
  196.         MOV     BX,TAIL                 ;Point to current tail
  197.         CMP     BX,HEAD                 ;If at head, kbd int has deleted char
  198.         JNE     CR                      ;So leave 
  199.         JMP     NOCR
  200. CR:     SUB     BX,2                    ;Point to just read in character
  201.         CMP     BX,OFFSET BUFFER        ;Did we undershoot buffer?
  202.         JAE     NO_WRAP                 ;Nope
  203.         MOV     BX,OFFSET BUFFER_END    ;Yes -- move to buffer top
  204.         SUB     BX,2                    
  205. NO_WRAP:MOV     DX,[BX]                 ;Char in DX now
  206.  
  207.         CMP     DL,'Z'                  ;Make sure we are in upper case
  208.         JBE     CHAROK                  
  209.         SUB     DL,'a'-'A'              ;Make REALLY sure.
  210. CHAROK: PUSH    CS
  211.         POP     DS                      ;Point to Code Seg with DS
  212.         ASSUME  DS:CODE_SEG
  213.         CMP     CR_FLAG,1               ;CR_Flag resets Zero_Flag
  214.         JNE     CHECK
  215.         MOV     CR_FLAG,0               ;Reset CR_Flag
  216.         MOV     ZERO_FLAG,0             ;And Zero_Flag
  217.         MOV     COMMAND_INDEX,0         ;As well as Command_Index
  218. CHECK:  LEA     SI,DEL_Z                ;Check the typed character
  219.         ADD     SI,COMMAND_INDEX        ;Find place in test string
  220.         CMP     DL,[SI]                 ;Match?
  221.         JNE     NOSET                   ;If not, forget it
  222.         INC     COMMAND_INDEX           ;Match! Move to next char next time
  223.         
  224.         CMP     DL,'/'                  ;For DOS 3+, delete the /Z from buffer
  225.         JNE     NOTSLSH
  226.         ASSUME  DS:ROM_BIOS_DATA        ;Examine the char just put in
  227.         MOV     CX,ROM_BIOS_DATA
  228.         MOV     DS,CX
  229.         MOV     TAIL,BX                 ;Erase character from buffer
  230.         MOV     AH,10                   ;Get ready to print the character
  231.         MOV     CX,1
  232.         MOV     AL,DL
  233.         XOR     BX,BX                   ;Display page 0
  234.         INT     10H                     ;Print the '/'
  235.         MOV     AH,3                    ;Now prepare to move cursor over 1
  236.         INT     10H                     ;Get present position
  237.         ADD     DX,1                    ;Add 1
  238.         MOV     AH,2                    ;And reset cursor
  239.         INT     10H
  240.  
  241. NOTSLSH:CMP     DL,'Z'                  ;For DOS 3+, delete the /Z from buffer
  242.         JNE     NOTZ
  243.         ASSUME  DS:ROM_BIOS_DATA        ;Examine the char just put in
  244.         MOV     CX,ROM_BIOS_DATA
  245.         MOV     DS,CX                   
  246.         MOV     TAIL,BX                 ;Erase character from the buffer
  247.         MOV     AH,10                   ;Prepare to type the 'Z'
  248.         MOV     CX,1                       
  249.         MOV     AL,DL
  250.         XOR     BX,BX
  251.         INT     10H
  252.         MOV     AH,3                    ;And now adjust the cursor
  253.         INT     10H                     ;Moving it to the left 1 space
  254.         ADD     DX,1                    
  255.         MOV     AH,2
  256.         INT     10H
  257.  
  258. NOTZ:   ASSUME  DS:CODE_SEG
  259.         PUSH    CS
  260.         POP     DS
  261.  
  262.         CMP     BYTE PTR [SI+1],0
  263.         JNE     NOSET
  264.         MOV     ZERO_FLAG,1
  265.         MOV     COMMAND_INDEX,0
  266. NOSET:  MOV     CR_FLAG,0
  267.         CMP     DX,1C0DH
  268.         JNE     NOCR
  269.         MOV     CR_FLAG,1
  270. NOCR:   POP     DS
  271.         POP     SI
  272.         POP     DI
  273.         POP     DX
  274.         POP     CX
  275.         POP     BX
  276.         POP     AX
  277.         IRET
  278. READ_KEY        ENDP
  279.  
  280. LOAD_INT_21H   PROC    NEAR     ;This subroutine installs DELZ 
  281.  
  282.         ASSUME  DS:INTERRUPTS           ;Now set DS to point to INTERRUPTS seg.
  283.         MOV     AX,INTERRUPTS
  284.         MOV     DS,AX
  285.  
  286.         MOV     AX,KEYBOARD_INT         ;Get the old interrupt service routine
  287.         MOV     OLD_KEYBOARD_INT,AX     ;address and put it into our location
  288.         MOV     AX,KEYBOARD_INT[2]      ;OLD_KEYBOARD_INT so we can call it.
  289.         MOV     OLD_KEYBOARD_INT[2],AX
  290.         
  291.         MOV     KEYBOARD_INT,OFFSET READ_KEY
  292.         MOV     KEYBOARD_INT[2],CS         ;routine into the keyboard interrupt
  293.  
  294.         MOV     AX,INT_21H              ;Get the original function call INT's
  295.         MOV     OLD_INT_21H,AX          ;address and put it into our location
  296.         MOV     AX,INT_21H[2]           ;OLD_INT_21H so we can still jump there
  297.         MOV     OLD_INT_21H[2],AX
  298.           
  299.         MOV     INT_21H[2],CS           ;Install our delete filter's address
  300.         MOV     INT_21H,OFFSET DELZ     ; as new function call INT
  301.  
  302.         PUSH    CS                      ;Now point to CS in preparation for
  303.         POP     DS                      ; terminate and stay resident call
  304.  
  305.         MOV     DX,OFFSET LOAD_INT_21H    ;Set up everything but LOAD_INT_21H to
  306.         INT     27H                       ;stay and attach itself to DOS
  307.  
  308. LOAD_INT_21H   ENDP                       ;End of loading subroutine
  309.  
  310.         CODE_SEG        ENDS            ;End of Code Segment
  311.         
  312.         END     FIRST   ;END "FIRST" so 8088 will go to FIRST first.
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320.  
  321.  
  322.  
  323.  
  324.  
  325.  
  326.  
  327.  
  328.