home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / 1989 / 12 / ldm / autosave.asm next >
Encoding:
Assembly Source File  |  1989-09-22  |  12.5 KB  |  423 lines

  1. TITLE AutoSave
  2.  
  3. ;* ------------------------------------------------------- *
  4. ;                       AUTOSAVE.ASM                       *
  5. ;                                                          *
  6. ; Automatisches Speichern von Texten in bestimmten Zeitin- *
  7. ; tervallen für MS-WORD oder nach entsprechender Änderung  *
  8. ; von "Save_Key" für (fast) jeden Editor.                  *
  9. ; Über weitere Einsatzmöglichkeiten informiert die Doku-   *
  10. ; mentation!                                               *
  11. ;                                                          *
  12. ;            (c) 1989 Roland Geier & TOOLBOX               *
  13. ; -------------------------------------------------------- *
  14. ;                    Assemblieren/Linken:                  *
  15. ; MASM Autosave                 /     TASM Autosave        *
  16. ; LINK Autosave                 /     TLINK Autosave /t    *
  17. ; EXE2BIN Autosave Autosave.COM /     (nix!)               *
  18. ;* ------------------------------------------------------- *
  19. ; Eingabe bei Installation : AUTOSAVE <Zeitintervall/min>  *
  20. ; Eingabe bei Deaktivierung: AUTOSAVE  ohne Parameter      *
  21. ;* ------------------------------------------------------- *
  22.  
  23. ; ------------------------
  24. ; Konstantendeklarationen
  25. ; ------------------------
  26.  
  27. Save_Key      EQU 3C00h         ; Code f. F2
  28.  
  29. ; Save_Key: Erweiterter Tastaturcode für die Taste/Tasten-
  30. ; kombination, die bei dem entsprechenden Programm das
  31. ; Speichern (oder auch eine andere Funktion!) bewirkt.
  32. ; Dieser Code wird nach einem bestimmten Zeitintervall, der
  33. ; in Minuten über die Kommandozeile eingegeben wird, auto-
  34. ; matisch in den Tastaturpuffer geschrieben.
  35. ;
  36. ; Bsp.: MS-WORD      6700h (CTRL-F10) f. Textspeicherung
  37. ;       Turbo-Pascal 3C00h (F2)       f. Sourcespeicherung
  38.  
  39. PSP_Cmdl_Offs EQU 80h
  40.  
  41. ; Offset für das PSP auf die Kommandozeile bzw. deren Länge
  42.  
  43. Save_Vector   EQU 18h           ; Vektor auf ROM-BASIC
  44.  
  45. ; Interrupt, auf dessen Vektor der Originalvektor des Inter-
  46. ; rupts 1Ch gesichert wird.
  47. ; 18h ist der Vektor auf das ROM-BASIC, der bei den meisten
  48. ; Kompatiblen keine Bedeutung hat.
  49. ; Alternativen wären z.B. 44h und 45h.
  50.  
  51. Code  Segment
  52.       Assume cs:Code,ds:Code
  53.       org 0100h                 ; ein COM-Programm, mmmh!
  54.  
  55. Start:  jmp init                ; Sprung zum Start
  56.  
  57. ; -----------------------
  58. ; ... und ein paar Daten
  59. ; -----------------------
  60.  
  61. CopyRight    DB 'AUTOSAVE (c) 1989 R. Geier & TOOLBOX ','$'
  62.  
  63. Inst_Msg     DB 'installiert...',10,13,'$'
  64. Del_Msg      DB 'deaktiviert...',10,13,'$'
  65.  
  66. Inv_Cmdl_Msg DB 10,13,07,'*** Fehler: Intervallzeit in '
  67.              DB 'Minuten als Parameter angeben!'
  68.              DB 10,13,'$'
  69.  
  70. No_Cmdl_Msg  DB 10,13,10,13,'Installation : AUTOSAVE '
  71.              DB '<Intervallzeit in Minuten>',10,13
  72.              DB 'Deaktivierung: AUTOSAVE (ohne Parameter)'
  73.              DB 10,13,'$'
  74.  
  75. Counter      DW 0000h           ; Tick-Zähler
  76.  
  77. Intervall    DW 0000h           ; Da kommt das Zeitintervall
  78.                                 ; rein!
  79.  
  80. ; ----------------------------------------------------------
  81. ; Int_1C: Neue Routine für den Interrupt 1Ch
  82. ; ----------------------------------------------------------
  83.  
  84. Int_1C  Proc
  85.         push ax                 ; erst mal Register retten..
  86.         push bx
  87.         push cx
  88.         push dx
  89.         push ds
  90.         push es
  91.         push si
  92.         push di
  93.  
  94.         ; um über Segment-Override auf Daten zugreifen zu
  95.         ; können, muß ds mit dem alten Datensegment geladen
  96.         ; werden, das identisch mit der Segmentadresse des
  97.         ; Vektors 1Ch ist, an der der Handler beginnt.
  98.         ; Das Ermitteln der Segmentadresse kann nicht via
  99.         ; DOS-Funktion 35h geschehen, da DOS nicht reen-
  100.         ; trant ist. Stattdessen muß direkt auf das Vektor-
  101.         ; segment zugegriffen werden: es befindet sich ab
  102.         ; der Adresse 0000:0072h.
  103.  
  104.         xor  ax,ax
  105.         mov  es,ax
  106.         mov  ds,es:word ptr [0072h]
  107.         inc  ds:Counter         ; Counter um 1 erhöhen
  108.         mov  cx,ds:counter
  109.         cmp  cx,ds:Intervall    ; Intervall vorbei?
  110.         jb   Int_1C_End         ; -> Nein: nichts passiert
  111.  
  112.         ; Wert aus BIOS-Variable 1Ah (Head) nach dx
  113.         ; Wert aus BIOS-Variable 1Ch (Tail) nach bx
  114.  
  115.         mov  ax,0040h           ; BIOS-Variablen-Segment
  116.         mov  es,ax              ; nach es
  117.         mov  dx,es:[001Ah]
  118.         mov  bx,es:[001Ch]
  119.  
  120.         ; noch Platz im Tastaturpuffer? Nein, wenn:
  121.         ; a) Head = 001Eh und Tail = 003Dh
  122.         ; b) Head - Tail = 2
  123.  
  124.         cmp  dx,001Eh           ; Fall a)
  125.         jne  Short Buf_Not_Full ; Fall a) nicht eingetreten
  126.         cmp  bx,003Bh
  127.         je   Reset_Counter      ; Fall a) eingetreten!
  128. Buf_Not_Full:
  129.         sub  dx,bx              ; Fall b)
  130.         cmp  dx,2
  131.         je   Reset_Counter      ; Fall b) eingetreten!
  132.  
  133.         ; Es ist noch Platz: Code Save_Key in Tastaturpuffer
  134.  
  135.         cli                     ; Interrupts sperren
  136.         mov  es:[bx],Save_Key
  137.         inc  bx                 ; Tail um 2 erhöhen
  138.         inc  bx
  139.         sti                     ; Interrupts wieder zulassen
  140.  
  141.         ; Wert von Tail in BIOS-Variable 001Ch eintragen
  142.  
  143.         mov  es:[001Ch],bx
  144.  
  145.         ; Zähler wieder auf 0 zurücksetzen
  146.  
  147.  
  148. Reset_Counter:
  149.         mov  ds:Counter,0
  150.  
  151. Int_1C_End:
  152.         pop  di                 ; Register restaurieren
  153.         pop  si
  154.         pop  es
  155.         pop  ds
  156.         pop  dx
  157.         pop  cx
  158.         pop  bx
  159.         pop  ax
  160.         iret
  161. Int_1C ENDP
  162.  
  163. ; ----------------------------------------------------------
  164. ; Hier beginnt die Hauptroutine zur Installation und Deakti-
  165. ; vierung des neuen Handlers für den Interrupt 1Ch.
  166. ; Das Programm erkennt an einer Markierung in der BIOS-
  167. ; Variablen 15h, ob der Handler bereits aktiv ist (Markier-
  168. ; ung = 10) oder ob sie installiert werden muß (Mark.<>10).
  169. ;
  170. ; Der Originalvektor 1Ch wird bei Installation im Vektor
  171. ; Save_Vector gesichert.
  172. ; ----------------------------------------------------------
  173.  
  174. Init:
  175.         mov  cx,0040h           ; BIOS-Variablensegment
  176.         mov  es,cx              ; nach es
  177.  
  178.         ; Markierung aus BIOS-Variablen 15h holen
  179.  
  180.  
  181.         mov  ah,es:[0015h]
  182.         cmp  ah,0Ah             ; Markierung gesetzt?
  183.         je   Help_Label         ; ja -> Deaktivierung
  184.  
  185. ; ----------------------------------------------------------
  186. ;                          Installation
  187. ; ----------------------------------------------------------
  188.  
  189. ;----------------------------------
  190. ; I. Kommandozeilenparameter holen:
  191. ;----------------------------------
  192.  
  193.         mov  di,PSP_Cmdl_Offs   ; Offset 80h nach DI
  194.         xor  cx,cx
  195.         mov  cl,byte ptr [di]   ; Kommandozeilenlänge -> CL
  196.         jcxz No_Cmdl_found      ; Länge=0 => keine Parameter
  197.         inc  cx
  198.         mov  al,32              ; ASCII-Code f. " " nach AL
  199.         jmp  Short Lab_1
  200.  
  201. Help_Label:
  202.         jmp StopProcess
  203.  
  204.         ; führende Leerzeichen ignorieren
  205.  
  206. Lab_1:  inc  di
  207.         cmp  al,byte ptr [di]
  208.         Loope Lab_1
  209.  
  210.         ; Zehner nach al, Einer nach bh
  211.  
  212.         mov  al,byte ptr [di]
  213.         mov  bh,byte ptr [di+1]
  214.  
  215.         ; Return => einstelliger Parameter <=>
  216.         ;           kein Zehner angegeben !!!
  217.  
  218.         cmp  bh,0Dh
  219.         jne  Short No_Problem
  220.  
  221.         ; aus dem Zehner, der keiner ist, wird ein Einer
  222.  
  223.         mov  bh,al
  224.         mov  al,48              ; ASCII für 0
  225.  
  226. No_Problem:
  227.  
  228.         ; Range-Checking für die Kommandozeilenparameter
  229.  
  230.         cmp  al,48
  231.         jb   Invalid_Cmdl       ; Einer "<" 0
  232.         cmp  al,57
  233.         ja   Invalid_Cmdl       ; Einer ">" 9
  234.         cmp  bh,48
  235.         jb   Invalid_Cmdl       ; Zehner "<" 0
  236.         cmp  bh,57
  237.         ja   Invalid_Cmdl       ; Zehner ">" 9
  238.         sub  al,48              ; ASCII -> Zahl
  239.         sub  bh,48              ; ASCII -> Zahl
  240.  
  241.         ; al * 10 ergibt den Zehner!
  242.  
  243.         mov  cl,10
  244.         mul  cl
  245.  
  246.         ; Gesamtergebnis (Einer+Zehner) nach bh
  247.  
  248.         add  bh,al
  249.  
  250.         ; Ergebnis = 0 => Ungültiger Parameter
  251.  
  252.         jz   Invalid_Cmdl
  253.  
  254.         ; Zeitwert [min] in Intervall speichern
  255.  
  256.         mov  byte ptr Intervall,bh
  257.  
  258.         ; Umrechnung Minuten -> Zeitgeberticks:
  259.         ; 18.2 Ticks/Sec <=> 1092 Ticks/Min
  260.         ; Ergebnis wird in Intervall abgelegt.
  261.  
  262.         mov  cx,1092
  263.         mov  ax,Intervall
  264.         mul  cx
  265.         mov  Intervall,ax
  266.         jmp  Short Set_Int_Vecs
  267.  
  268.         ; bei fehlender Kommandozeile
  269.  
  270. No_Cmdl_Found:
  271.         mov  ah,09h
  272.         mov  dx,offset CopyRight
  273.         int  21h
  274.         mov  ah,09h
  275.         mov  dx,offset No_Cmdl_Msg
  276.         int  21h
  277.         jmp  Ende               ; ... und tschüß!
  278.  
  279.         ; bei ungültigen Kommandozeilenparamtern
  280.  
  281. Invalid_Cmdl:
  282.         mov  ah,09h
  283.         mov  dx,offset CopyRight
  284.         int  21h
  285.         mov  ah,09h
  286.         mov  dx,offset Inv_Cmdl_Msg
  287.         int  21h
  288.         jmp  Ende               ; ... und tschüß!
  289.  
  290. ;-------------------------
  291. ; II. Interrupts verbiegen
  292. ;-------------------------
  293.  
  294. Set_Int_Vecs:
  295.  
  296.         ; Interrupts sperren!!!
  297.  
  298.         cli
  299.  
  300.         ; Interruptvektor 1Ch über DOS-Funktion 35h ausle-
  301.         ; sen. Ausgabe: Segmentadresse in es, Offsetadresse
  302.         ; in bx.
  303.  
  304.         mov  ah,35h
  305.         mov  al,1Ch
  306.         int  21h
  307.  
  308.         push ds                 ; ds sichern
  309.  
  310.         ; Originalvektor 1Ch wird über DOS-Funktion 25h im
  311.         ; bedeutungslosen Vektor Save_Vector gesichert.
  312.  
  313.         mov  ah,25h
  314.         mov  al,Save_Vector
  315.         push es
  316.         pop  ds                 ; Segmentadresse nach ds
  317.         mov  dx,bx              ; Offsetadresse  nach dx
  318.         int  21h
  319.         pop  ds
  320.  
  321.  
  322.         ; Vektor 1Ch auf Int_1C verbiegen
  323.  
  324.         mov  ah,25h
  325.         mov  al,1Ch
  326.         mov  dx,offset Int_1C        ; Offsetadresse nach dx
  327.         int  21h
  328.  
  329.  
  330.         ; Interrupts wieder zulassen
  331.  
  332.         sti
  333.  
  334.         ; Installationsmeldung ausgeben
  335.  
  336.         mov  ah,09h
  337.         mov  dx,offset CopyRight
  338.         int  21h
  339.         mov  ah,09h
  340.         mov  dx,offset Inst_Msg
  341.         int  21h
  342.  
  343.  
  344.         ; Installationsmarkierung 10 (0Ah) in die unbenutzte
  345.         ; BIOS-Variable 15h eintragen
  346.  
  347.         mov  ax,0040h           ; BIOS-Variablen-Segment
  348.         mov  es,ax
  349.         mov  al,0Ah             ; 0Ah nach al...
  350.         mov  es:[0015h],al      ; ...und in d. BIOS-Variable
  351.  
  352.         ; Programm resident machen
  353.  
  354.         mov  dx,offset Init     ; Größe d. Interrupt-Routine
  355.         int  27h                ; TSR und Ende.
  356.  
  357. ; ----------------------------------------------------------
  358. ;                          Deaktivierung
  359. ; ----------------------------------------------------------
  360.  
  361. StopProcess:
  362.  
  363.         ; belegten Speicher mit DOS-Funktion 49h wieder
  364.         ; freigeben. Dazu muß in ES die Segmentadresse
  365.         ; der Interrupt-Routine übergeben werden.
  366.         ; Sie ist identisch mit der Segmentadresse des
  367.         ; Interruptvektors 1Ch, der auf den installierten
  368.         ; Handler Int_1C zeigt und kann mit der DOS-Funk-
  369.         ; tion 35h ermittelt werden.
  370.  
  371.         mov  ah,35h
  372.         mov  al,1Ch
  373.         int  21h                ; Segmentadresse nun in es
  374.         mov  ah,49h
  375.         int  21h                ; Speicher freigeben
  376.  
  377.         ; Originalvektor 1Ch aus dem Exil "Save_Vector"
  378.         ; zurückholen.
  379.         ; Ausgabe: es Segmentadresse, bx Offsetadresse
  380.  
  381.         mov  ah,35h
  382.         mov  al,Save_Vector
  383.         int  21h
  384.  
  385.         ; Originalvektor 1Ch wieder auf seine Original-
  386.         ; adresse setzen
  387.  
  388.         push ds                 ; ds sichern
  389.         mov  ah,25h
  390.         mov  al,1Ch
  391.         push es                 ; es nach ds
  392.         pop  ds
  393.         mov  dx,bx              ; bx nach dx
  394.         int  21h
  395.         pop  ds                 ; ds zurückholen
  396.  
  397.         ; Deaktivierungsmeldung ausgeben
  398.  
  399.         mov  ah,09h
  400.         mov  dx,offset CopyRight
  401.         int  21h
  402.         mov  ah,09h
  403.         mov  dx,offset Del_Msg
  404.         int  21h
  405.  
  406.         ; Installationsmarkierung 0Ah in BIOS-Variable 15h
  407.         ; wieder löschen
  408.  
  409.         mov  ax,0040h           ; BIOS-Variablen-Segment
  410.         mov  es,ax              ; nach es
  411.         xor  al,al              ; al = 0
  412.         mov  es:[0015h],al      ; 0 in Variable eintragen
  413.  
  414.         ; Programm normal beenden
  415.  
  416. Ende:   mov  ah,4Ch
  417.         int  21h
  418.  
  419. Code    Ends
  420.         End Start                    ; Aus und vorbei.
  421. ;* ------------------------------------------------------- *
  422. ;*                Ende von AUTOSAVE.ASM                    *
  423.