home *** CD-ROM | disk | FTP | other *** search
- TITLE AutoSave
-
- ;* ------------------------------------------------------- *
- ; AUTOSAVE.ASM *
- ; *
- ; Automatisches Speichern von Texten in bestimmten Zeitin- *
- ; tervallen für MS-WORD oder nach entsprechender Änderung *
- ; von "Save_Key" für (fast) jeden Editor. *
- ; Über weitere Einsatzmöglichkeiten informiert die Doku- *
- ; mentation! *
- ; *
- ; (c) 1989 Roland Geier & TOOLBOX *
- ; -------------------------------------------------------- *
- ; Assemblieren/Linken: *
- ; MASM Autosave / TASM Autosave *
- ; LINK Autosave / TLINK Autosave /t *
- ; EXE2BIN Autosave Autosave.COM / (nix!) *
- ;* ------------------------------------------------------- *
- ; Eingabe bei Installation : AUTOSAVE <Zeitintervall/min> *
- ; Eingabe bei Deaktivierung: AUTOSAVE ohne Parameter *
- ;* ------------------------------------------------------- *
-
- ; ------------------------
- ; Konstantendeklarationen
- ; ------------------------
-
- Save_Key EQU 3C00h ; Code f. F2
-
- ; Save_Key: Erweiterter Tastaturcode für die Taste/Tasten-
- ; kombination, die bei dem entsprechenden Programm das
- ; Speichern (oder auch eine andere Funktion!) bewirkt.
- ; Dieser Code wird nach einem bestimmten Zeitintervall, der
- ; in Minuten über die Kommandozeile eingegeben wird, auto-
- ; matisch in den Tastaturpuffer geschrieben.
- ;
- ; Bsp.: MS-WORD 6700h (CTRL-F10) f. Textspeicherung
- ; Turbo-Pascal 3C00h (F2) f. Sourcespeicherung
-
- PSP_Cmdl_Offs EQU 80h
-
- ; Offset für das PSP auf die Kommandozeile bzw. deren Länge
-
- Save_Vector EQU 18h ; Vektor auf ROM-BASIC
-
- ; Interrupt, auf dessen Vektor der Originalvektor des Inter-
- ; rupts 1Ch gesichert wird.
- ; 18h ist der Vektor auf das ROM-BASIC, der bei den meisten
- ; Kompatiblen keine Bedeutung hat.
- ; Alternativen wären z.B. 44h und 45h.
-
- Code Segment
- Assume cs:Code,ds:Code
- org 0100h ; ein COM-Programm, mmmh!
-
- Start: jmp init ; Sprung zum Start
-
- ; -----------------------
- ; ... und ein paar Daten
- ; -----------------------
-
- CopyRight DB 'AUTOSAVE (c) 1989 R. Geier & TOOLBOX ','$'
-
- Inst_Msg DB 'installiert...',10,13,'$'
- Del_Msg DB 'deaktiviert...',10,13,'$'
-
- Inv_Cmdl_Msg DB 10,13,07,'*** Fehler: Intervallzeit in '
- DB 'Minuten als Parameter angeben!'
- DB 10,13,'$'
-
- No_Cmdl_Msg DB 10,13,10,13,'Installation : AUTOSAVE '
- DB '<Intervallzeit in Minuten>',10,13
- DB 'Deaktivierung: AUTOSAVE (ohne Parameter)'
- DB 10,13,'$'
-
- Counter DW 0000h ; Tick-Zähler
-
- Intervall DW 0000h ; Da kommt das Zeitintervall
- ; rein!
-
- ; ----------------------------------------------------------
- ; Int_1C: Neue Routine für den Interrupt 1Ch
- ; ----------------------------------------------------------
-
- Int_1C Proc
- push ax ; erst mal Register retten..
- push bx
- push cx
- push dx
- push ds
- push es
- push si
- push di
-
- ; um über Segment-Override auf Daten zugreifen zu
- ; können, muß ds mit dem alten Datensegment geladen
- ; werden, das identisch mit der Segmentadresse des
- ; Vektors 1Ch ist, an der der Handler beginnt.
- ; Das Ermitteln der Segmentadresse kann nicht via
- ; DOS-Funktion 35h geschehen, da DOS nicht reen-
- ; trant ist. Stattdessen muß direkt auf das Vektor-
- ; segment zugegriffen werden: es befindet sich ab
- ; der Adresse 0000:0072h.
-
- xor ax,ax
- mov es,ax
- mov ds,es:word ptr [0072h]
- inc ds:Counter ; Counter um 1 erhöhen
- mov cx,ds:counter
- cmp cx,ds:Intervall ; Intervall vorbei?
- jb Int_1C_End ; -> Nein: nichts passiert
-
- ; Wert aus BIOS-Variable 1Ah (Head) nach dx
- ; Wert aus BIOS-Variable 1Ch (Tail) nach bx
-
- mov ax,0040h ; BIOS-Variablen-Segment
- mov es,ax ; nach es
- mov dx,es:[001Ah]
- mov bx,es:[001Ch]
-
- ; noch Platz im Tastaturpuffer? Nein, wenn:
- ; a) Head = 001Eh und Tail = 003Dh
- ; b) Head - Tail = 2
-
- cmp dx,001Eh ; Fall a)
- jne Short Buf_Not_Full ; Fall a) nicht eingetreten
- cmp bx,003Bh
- je Reset_Counter ; Fall a) eingetreten!
- Buf_Not_Full:
- sub dx,bx ; Fall b)
- cmp dx,2
- je Reset_Counter ; Fall b) eingetreten!
-
- ; Es ist noch Platz: Code Save_Key in Tastaturpuffer
-
- cli ; Interrupts sperren
- mov es:[bx],Save_Key
- inc bx ; Tail um 2 erhöhen
- inc bx
- sti ; Interrupts wieder zulassen
-
- ; Wert von Tail in BIOS-Variable 001Ch eintragen
-
- mov es:[001Ch],bx
-
- ; Zähler wieder auf 0 zurücksetzen
-
-
- Reset_Counter:
- mov ds:Counter,0
-
- Int_1C_End:
- pop di ; Register restaurieren
- pop si
- pop es
- pop ds
- pop dx
- pop cx
- pop bx
- pop ax
- iret
- Int_1C ENDP
-
- ; ----------------------------------------------------------
- ; Hier beginnt die Hauptroutine zur Installation und Deakti-
- ; vierung des neuen Handlers für den Interrupt 1Ch.
- ; Das Programm erkennt an einer Markierung in der BIOS-
- ; Variablen 15h, ob der Handler bereits aktiv ist (Markier-
- ; ung = 10) oder ob sie installiert werden muß (Mark.<>10).
- ;
- ; Der Originalvektor 1Ch wird bei Installation im Vektor
- ; Save_Vector gesichert.
- ; ----------------------------------------------------------
-
- Init:
- mov cx,0040h ; BIOS-Variablensegment
- mov es,cx ; nach es
-
- ; Markierung aus BIOS-Variablen 15h holen
-
-
- mov ah,es:[0015h]
- cmp ah,0Ah ; Markierung gesetzt?
- je Help_Label ; ja -> Deaktivierung
-
- ; ----------------------------------------------------------
- ; Installation
- ; ----------------------------------------------------------
-
- ;----------------------------------
- ; I. Kommandozeilenparameter holen:
- ;----------------------------------
-
- mov di,PSP_Cmdl_Offs ; Offset 80h nach DI
- xor cx,cx
- mov cl,byte ptr [di] ; Kommandozeilenlänge -> CL
- jcxz No_Cmdl_found ; Länge=0 => keine Parameter
- inc cx
- mov al,32 ; ASCII-Code f. " " nach AL
- jmp Short Lab_1
-
- Help_Label:
- jmp StopProcess
-
- ; führende Leerzeichen ignorieren
-
- Lab_1: inc di
- cmp al,byte ptr [di]
- Loope Lab_1
-
- ; Zehner nach al, Einer nach bh
-
- mov al,byte ptr [di]
- mov bh,byte ptr [di+1]
-
- ; Return => einstelliger Parameter <=>
- ; kein Zehner angegeben !!!
-
- cmp bh,0Dh
- jne Short No_Problem
-
- ; aus dem Zehner, der keiner ist, wird ein Einer
-
- mov bh,al
- mov al,48 ; ASCII für 0
-
- No_Problem:
-
- ; Range-Checking für die Kommandozeilenparameter
-
- cmp al,48
- jb Invalid_Cmdl ; Einer "<" 0
- cmp al,57
- ja Invalid_Cmdl ; Einer ">" 9
- cmp bh,48
- jb Invalid_Cmdl ; Zehner "<" 0
- cmp bh,57
- ja Invalid_Cmdl ; Zehner ">" 9
- sub al,48 ; ASCII -> Zahl
- sub bh,48 ; ASCII -> Zahl
-
- ; al * 10 ergibt den Zehner!
-
- mov cl,10
- mul cl
-
- ; Gesamtergebnis (Einer+Zehner) nach bh
-
- add bh,al
-
- ; Ergebnis = 0 => Ungültiger Parameter
-
- jz Invalid_Cmdl
-
- ; Zeitwert [min] in Intervall speichern
-
- mov byte ptr Intervall,bh
-
- ; Umrechnung Minuten -> Zeitgeberticks:
- ; 18.2 Ticks/Sec <=> 1092 Ticks/Min
- ; Ergebnis wird in Intervall abgelegt.
-
- mov cx,1092
- mov ax,Intervall
- mul cx
- mov Intervall,ax
- jmp Short Set_Int_Vecs
-
- ; bei fehlender Kommandozeile
-
- No_Cmdl_Found:
- mov ah,09h
- mov dx,offset CopyRight
- int 21h
- mov ah,09h
- mov dx,offset No_Cmdl_Msg
- int 21h
- jmp Ende ; ... und tschüß!
-
- ; bei ungültigen Kommandozeilenparamtern
-
- Invalid_Cmdl:
- mov ah,09h
- mov dx,offset CopyRight
- int 21h
- mov ah,09h
- mov dx,offset Inv_Cmdl_Msg
- int 21h
- jmp Ende ; ... und tschüß!
-
- ;-------------------------
- ; II. Interrupts verbiegen
- ;-------------------------
-
- Set_Int_Vecs:
-
- ; Interrupts sperren!!!
-
- cli
-
- ; Interruptvektor 1Ch über DOS-Funktion 35h ausle-
- ; sen. Ausgabe: Segmentadresse in es, Offsetadresse
- ; in bx.
-
- mov ah,35h
- mov al,1Ch
- int 21h
-
- push ds ; ds sichern
-
- ; Originalvektor 1Ch wird über DOS-Funktion 25h im
- ; bedeutungslosen Vektor Save_Vector gesichert.
-
- mov ah,25h
- mov al,Save_Vector
- push es
- pop ds ; Segmentadresse nach ds
- mov dx,bx ; Offsetadresse nach dx
- int 21h
- pop ds
-
-
- ; Vektor 1Ch auf Int_1C verbiegen
-
- mov ah,25h
- mov al,1Ch
- mov dx,offset Int_1C ; Offsetadresse nach dx
- int 21h
-
-
- ; Interrupts wieder zulassen
-
- sti
-
- ; Installationsmeldung ausgeben
-
- mov ah,09h
- mov dx,offset CopyRight
- int 21h
- mov ah,09h
- mov dx,offset Inst_Msg
- int 21h
-
-
- ; Installationsmarkierung 10 (0Ah) in die unbenutzte
- ; BIOS-Variable 15h eintragen
-
- mov ax,0040h ; BIOS-Variablen-Segment
- mov es,ax
- mov al,0Ah ; 0Ah nach al...
- mov es:[0015h],al ; ...und in d. BIOS-Variable
-
- ; Programm resident machen
-
- mov dx,offset Init ; Größe d. Interrupt-Routine
- int 27h ; TSR und Ende.
-
- ; ----------------------------------------------------------
- ; Deaktivierung
- ; ----------------------------------------------------------
-
- StopProcess:
-
- ; belegten Speicher mit DOS-Funktion 49h wieder
- ; freigeben. Dazu muß in ES die Segmentadresse
- ; der Interrupt-Routine übergeben werden.
- ; Sie ist identisch mit der Segmentadresse des
- ; Interruptvektors 1Ch, der auf den installierten
- ; Handler Int_1C zeigt und kann mit der DOS-Funk-
- ; tion 35h ermittelt werden.
-
- mov ah,35h
- mov al,1Ch
- int 21h ; Segmentadresse nun in es
- mov ah,49h
- int 21h ; Speicher freigeben
-
- ; Originalvektor 1Ch aus dem Exil "Save_Vector"
- ; zurückholen.
- ; Ausgabe: es Segmentadresse, bx Offsetadresse
-
- mov ah,35h
- mov al,Save_Vector
- int 21h
-
- ; Originalvektor 1Ch wieder auf seine Original-
- ; adresse setzen
-
- push ds ; ds sichern
- mov ah,25h
- mov al,1Ch
- push es ; es nach ds
- pop ds
- mov dx,bx ; bx nach dx
- int 21h
- pop ds ; ds zurückholen
-
- ; Deaktivierungsmeldung ausgeben
-
- mov ah,09h
- mov dx,offset CopyRight
- int 21h
- mov ah,09h
- mov dx,offset Del_Msg
- int 21h
-
- ; Installationsmarkierung 0Ah in BIOS-Variable 15h
- ; wieder löschen
-
- mov ax,0040h ; BIOS-Variablen-Segment
- mov es,ax ; nach es
- xor al,al ; al = 0
- mov es:[0015h],al ; 0 in Variable eintragen
-
- ; Programm normal beenden
-
- Ende: mov ah,4Ch
- int 21h
-
- Code Ends
- End Start ; Aus und vorbei.
- ;* ------------------------------------------------------- *
- ;* Ende von AUTOSAVE.ASM *