; Programm TabIt ; ; von Manuel Keáler ; ; Version 0.9 ; ; Beginn am 3.9.96 ; Update am 10.9.96 ; ; THIS CODE COMES WITH ABSOLUTELY NO WARRANTY, USE AT YOUR OWN RISK!!! ; Feel free to modify or steal this code, i release it to the public domain ; Bug reports, improvements and suggestions to: ; mlkessle@cip.physik.uni-wuerzburg.de ; .286 MODEL TINY JUMPS IFNDEF WITHC .CODE ORG 0100h los: jmp startTransient ENDIF IFDEF WITHC .DATA extrn _oldInt16 public _pspseg public _envseg public _cmdofs public _nameofs public _fileofs ELSE _oldInt16 dd ? oldDTA dd ? ENDIF _pspseg dw 0 _envseg dw 0 _cmdofs dw 0 TAB equ 9 DIRECTORY equ 16 READONLY equ 1 ATTRIBUTE equ DIRECTORY+READONLY ; Normal+Unterverzeichnis+Readonly screen db 0 line db ? col db ? lastcol db ? firstcol db ? linebuf db 160 dup (0) lineofs dw linebuf _nameofs dw linebuf _fileofs dw linebuf namelen dw 0 namesbuf db 200 dup (0) filecount db 0 filenum db 0 doserr db 13, 10, "DOS-Fehler", 13, 10, '$' .CODE public _newInt16 _newInt16 proc far ASSUME CS:DGROUP, DS:NOTHING, ES:NOTHING, SS:NOTHING cmp ah, 0 jz int16_00 ; cmp ah, 1 ; jz int16_01 cmp ah, 10h jz int16_00 ; cmp ah, 11h ; jz int16_01 jmp DWORD PTR cs:_oldInt16 ; war nicht fr uns _return:popf ret 2 _newInt16 endp int16_00: pushf call DWORD PTR cs:_oldInt16 pushf cmp al, TAB jne _return pusha push es push ds mov ah, 2fh int 21h ; get current DTA mov WORD PTR cs:oldDTA, bx mov WORD PTr cs:oldDTA+2, es mov ah, 62h int 21h ; get active PSP mov cs:_pspseg, bx IF 0 ; berflssig, da Name in MCB mov es, bx mov bx, [es:02ch] mov cs:_envseg, bx mov es, bx mov di, 0 l1: mov ax, [es:di] inc di or ax, ax jnz l1 add di, 3 mov cs:_cmdofs, di ENDIF ; Rufendes Programm berprfen (COMMAND.COM?) dec bx mov es, bx ; auf MCB cmp WORD PTR [es:08h], "OC" jne done cmp WORD PTR [es:0ah], "MM" jne done cmp WORD PTR [es:0ch], "NA" jne done cmp WORD PTR [es:0eh], 'D'+0*256 ; "COMMAND\0" checken als Progname jne done mov bx, cs mov ds, bx mov es, bx ASSUME DS:DGROUP, ES:DGROUP mov ah, 50h int 21h ; PSP neu setzen mov ah, 1ah mov dx, 80h int 21h ; DTA neu setzen ; jetzt gehts ab mov ah, 0fh int 10h ; Video-Modus und Bildschirmseite mov screen, bh mov ah, 03h int 10h ; Cursor abfragen mov lastcol, dl mov line, dh mov dl, 0 mov lineofs, OFFSET linebuf ; Zeile in linebuf holen loop1: mov ah, 02h int 10h ; Cursor setzen mov ah, 8h int 10h ; Zeichen holen mov di, lineofs mov [di], al inc di inc dl mov lineofs, di cmp dl, lastcol jle loop1 dec di mov lineofs, di mov BYTE PTR [di], 0 ; Tab berschreiben ; jetzt ist die Bildschirmzeile im linebuf, nach letztem Dateinamen suchen dec di loop2: mov al, [di] cmp al, ' ' je ready2 cmp al, ',' je ready2 cmp al, ';' je ready2 cmp al, '>' je ready2 cmp al, '<' je ready2 dec di cmp di, OFFSET linebuf jae loop2 ready2: inc di mov _fileofs, di mov si, lineofs dec si mov ah, 0 ; Flag fr Punkte im Namen loop3: mov al, [si] cmp al, '\' je ready3 cmp al, ':' je ready3 cmp al, '.' jne noPt mov ah, 1 noPt: dec si cmp si, _fileofs jae loop3 ready3: inc si mov _nameofs, si mov di, lineofs sub si, di neg si mov namelen, si mov BYTE PTR [di], '*' inc di cmp ah, 0 jne hasPt mov WORD PTR [di], "*." ; muá verkehrt herum sein !!! add di, 2 hasPt: mov BYTE PTR [di], 0 mov dx, _fileofs mov cx, ATTRIBUTE mov ah, 4eh int 21h ; Findfirst jnc hasFile mov ax, 0e07h int 10h ; Bell ausgeben mov ah, 05h mov cx, 0f08h int 16h ; Backspace nach Tab simulieren jmp done hasFile:mov di, OFFSET namesbuf mov filecount, 0 addFile:cmp di, OFFSET namesbuf+SIZE namesbuf-14 ; noch genug Platz im Puffer? ja lastFile ; falls nicht, halt aufh”ren inc filecount mov si, 80h+1eh ; auf den Namen der DTA mov ah, [es:si-1eh+15h] ; wahres Attribut add si, namelen ; schon bekanntes berspringen loop4: mov al, [es:si] inc si cmp al, 'A' jl noLetter cmp al, 'Z' ja noLetter or al, 20h ; GROSS -> klein noLetter: mov [di], al inc di or al, al jnz loop4 test ah, DIRECTORY jz noDir mov WORD PTR [di-1], '\'+0*256 ; 0 mit '\'0 berschreiben inc di noDir: mov ah, 4fh int 21h ; Findnext jnc addFile lastFile: cmp filecount, 1 ja moreFiles mov ah, 05h mov cx, 0f08h int 16h ; Backspace nach Tab simulieren mov si, OFFSET namesbuf mov ch, 0 ; braucht jemand Scancodes ?!? loop5: mov cl, [si] mov ah, 05h int 16h inc si or cl, cl jne loop5 ; alle Zeichen reinballern jmp done ; und fertig moreFiles: mov ax, 0e0dh int 10h mov ax, 0e0ah int 10h ; erstmal CR+LF mov al, filecount mov dx, OFFSET namesbuf mov filenum, al nextFile: mov bx, _nameofs mov cx, namelen jcxz ready6 loop6: mov al, [bx] mov ah, 0eh int 10h ; Zeichen ausgeben inc bx dec cx jnz loop6 ; ok, Name ist draussen, jetzt Rest ready6: mov bx, dx loop7: mov al, [bx] or al, al jz ready7 mov ah, 0eh int 10h inc bx jmp loop7 ; alle Zeichen ausgeben ready7: inc bx mov dx, bx mov ax, 0e20h int 10h mov ax, 0e20h int 10h ; nach dem Namen zwei Spaces dec filenum jnz nextFile mov ax, 0e0dh int 10h mov ax, 0e0ah int 10h ; erstmal CR+LF mov bx, OFFSET linebuf loop8: mov al, [bx] mov ah, 0eh int 10h ; Zeichen ausgeben inc bx cmp bx, lineofs jne loop8 ; ok, Zeile ist wieder draussen ; Zeile ist jetzt wieder draussen, was kann noch angeh„ngt werden? mov di, OFFSET namesbuf-1 mov cx, -1 loop9: inc di inc cx cmp BYTE PTR [di], 0 jnz loop9 jcxz ready10 inc cx mov al, filecount mov dx, cx ; L„nge des ersten Eintrages (ohne 0) cld push ds dec al ; erster Eintrag ist ja schon da pop es nextEntry: inc di ; auf n„chsten Eintrag mov si, OFFSET namesbuf mov cx, dx repe cmpsb jcxz loop11 ; inc cx sub dx, cx ; šbriggebliebener Rest ist ungleich jz ready10 ; nix mehr da loop11: cmp BYTE PTR [di], 0 ; n„chsten Eintrag suchen je noDiff inc di jmp loop11 noDiff: dec al jnz nextEntry sub dx, 1 jle ready10 mov ah, 05h mov cx, 0f08h int 16h ; Backspace nach Tab simulieren mov bx, OFFSET namesbuf mov ch, 0 loop10: mov cl, [bx] mov ah, 05h int 16h inc bx dec dx jnz loop10 ; gemeinsamer Rest raus jmp done ready10: mov ah, 05h mov cx, 0f08h int 16h ; Backspace nach Tab simulieren done: mov bx, cs:_pspseg mov ah, 50h int 21h ; PSP wieder zurck setzen mov ah, 1ah mov bx, WORD PTR cs:oldDTA mov ds, WORD PTR cs:oldDTA+2 int 21h ; DTA zurck setzen pop ds pop es popa jmp _return ;---------------------------------------------------------------------------- IF 0 int16_01: pushf call DWORD PTR cs:_oldInt16 pushf jmp _return ENDIF IFNDEF WITHC endResident LABEL BYTE startTransient PROC ASSUME CS:DGROUP, DS:DGROUP, ES:NOTHING, SS:DGROUP push cs pop ds mov ah, 09h mov dx, OFFSET Einschalt int 21h mov ax, 3516h int 21h mov WORD PTR _oldInt16, bx mov di, bx mov bx, es mov WORD PTR _oldInt16+2, bx mov si, OFFSET _newInt16 mov cx, 080h ; 256 Bytes gleich sollte reichen repe cmpsw jcxz unInstall mov ax, 2516h mov dx, OFFSET _newInt16 int 21h mov ah, 09h mov dx, OFFSET Installiert int 21h mov es, [ds:2ch] mov ah, 49h int 21h ; Environment freigeben mov ah, 3eh mov bx, 0 int 21h mov bx, 1 int 21h mov bx, 2 int 21h mov bx, 3 int 21h mov bx, 4 int 21h ; Standardhandles freigeben mov dx, OFFSET endResident add dx, 0fh shr dx, 4 mov ax, 3100h int 21h ; go TSR unInstall: push ds mov dx, WORD PTR es:_oldInt16 mov ds, WORD PTR es:_oldInt16+2 mov ax, 2516h int 21h pop ds mov ah, 49h int 21h ; Speicher freigeben mov ah, 09h mov dx, OFFSET DeInstalliert int 21h mov ax, 4c01h ; Endecode 1 => deinstalliert int 21h startTransient ENDP Einschalt db 13, 10, "TabIt V0.9 (c) 1996 von Manuel Keáler", 13, 10, '$' Installiert db "wurde erfolgreich installiert", 13, 10, '$' DeInstalliert db "wurde erfolgreich deinstalliert", 13, 10, '$' ENDIF END los