home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / assemblr / tutorial / asmlehrg / schnecke.asm < prev    next >
Assembly Source File  |  1993-07-29  |  5KB  |  145 lines

  1. ;
  2. ; Programm : SCHNECKE.ASM
  3. ; Verfasser: J. Altfeld
  4. ; Sprache  : Assembler
  5. ; Compiler : MASM 4.0
  6. ; Datum    : 25.02.89
  7. ; Assemblieren: MASM Schnecke;
  8. ;            LINK Schnecke;
  9. ;            EXE2BIN Schnecke Schnecke.COM
  10. ;
  11. ;*****  SCHNECKE.ASM   Version 2.02  *****
  12. ;
  13. BIOS    SEGMENT AT 40H
  14.         ORG 1AH
  15. HEAD    DW ? ; Zeiger auf Puffer-Kopf
  16. TAIL    DW ? ; Zeiger auf Puffer-Schwanz
  17. BUFFER  DW 16 DUP (?) ; Tastatur-Puffer
  18. B_ENDE  LABEL WORD ; Ende des Puffers
  19. BIOS    ENDS
  20. ;
  21. ; Programm beginnt nach Aufruf hier
  22. ;
  23. CODE    SEGMENT
  24.         ASSUME CS:CODE, DS:BIOS, ES:CODE
  25.         ORG 100H ; Notwendig für COM-Datei
  26. START:  JMP INIT ; Initialisierungsroutine
  27. ;
  28. ; Variablen
  29. ;
  30. WARTE   DB ? ; Dauer der Verzögerung
  31. AKTIV   DB 0 ; Verzögerung ein/aus (255/0)
  32. ; Speicher für alte Interrupt-Adressen
  33. ALTINT8 DW 2 DUP (?) ; Systemzeitinterrupt
  34. ALTINT9 DW 2 DUP (?) ; Tastatur-Interrupt
  35. ;
  36. ; Neue Interrupt-Routine INT_9:
  37. ;
  38. INT_9:  PUSH AX ; alle Register retten,
  39.         PUSH BX ; die verändert werden
  40.         PUSH DS
  41. ; Alte Tastatur-Routine aufrufen
  42.         PUSHF
  43.         CALL CS:DWORD PTR ALTINT9
  44.         CLI ; alle Interrupts sperren!
  45. ; Prüfen, ob eine Taste gedrückt wurde
  46.         MOV AX,BIOS
  47.         MOV DS,AX
  48.         MOV BX,TAIL ; prüfen, ob Puffer
  49.         CMP BX,HEAD ; leer ist
  50.         JNE JA1 ; Nein, dann auswerten
  51.         JMP ENDE1 ; sonst Routine beenden
  52. ; Gedrückte Taste aus RING-Puffer holen
  53. JA1:    SUB BX,2
  54.         CMP BX,OFFSET BUFFER
  55.         JAE OK1
  56.         MOV BX,OFFSET B_ENDE-2
  57. OK1:    MOV AX,[BX] ; Scan- und ASCII-Code
  58. ; Ist es ein erweiterter Tastencode?
  59.         AND AL,AL ; (AL gleich null?)
  60.         JNZ ENDE1 ; nein, dann abbrechen
  61. ; Wurde gültige Hotkey-Taste gedrückt?
  62.         CMP AH,78H ; Wert der Taste ALT-1
  63.         JB ENDE1 ; nein -> abbrechen
  64.         CMP AH,81H ; Wert der Taste ALT-0
  65.         JA ENDE1 ; nein -> abbrechen
  66.         JNZ NEIN1 ; Taste ALT-0 gedrückt?
  67. ; Verzögerung ausschalten und abbrechen
  68.         MOV CS:BYTE PTR AKTIV,0
  69.         JMP ENDE2
  70. ; Verzögerungswert ausrechnen
  71. NEIN1:  SUB AH,77H ; Tastcode umrechnen
  72.         MOV AL,28 ; Verzögerungs-Multiplikator
  73.         MUL AH ; Verzögerung ausrechnen
  74. ; Verzögerungswert speichern
  75.         MOV CS:BYTE PTR WARTE,AL
  76. ; und Verzögerung einschalten
  77.         MOV CS:BYTE PTR AKTIV,255
  78. ; gedrückte Hotkey aus Puffer löschen
  79. ENDE2:  MOV TAIL,BX
  80. ; Routine ordnungsgemäß beenden/abbrechen
  81. ENDE1:  POP DS
  82.         POP BX
  83.         POP AX
  84.         STI ; Interrupts wieder erlauben
  85.         IRET ; Interruptroutine beenden
  86. ;
  87. ; Neue Interrupt-Routine INT_8 (Timer,
  88. ; wird 18,2 mal pro Sekunde aufgerufen)
  89. ;
  90. INT_8:  PUSHF
  91. ; Systemfunktionen und INT 1Ch ausführen
  92.         CALL CS:DWORD PTR ALTINT8
  93.         CLI ; Interrupts sperren
  94.         PUSH BX ; Register retten
  95.         PUSH CX
  96. ; Testen, ob verzögert werden soll
  97.         CMP CS:BYTE PTR AKTIV,0
  98.         JE ENDE ; nein -> Routine beenden
  99. ; Verzögerungsschleifen durchlaufen
  100.         MOV CL,CS:BYTE PTR WARTE ; Dauer
  101.         XOR CH,CH ; der Verzög. laden
  102. GO0:    MOV BX,100 ; 2. Verzögerungswert!
  103. GO1:    DEC BX ; Innere Schleife
  104.         JNZ GO1
  105.         LOOP GO0 ; Äußere Schleife
  106. ENDE:   POP CX ; Register restaurieren
  107.         POP BX
  108.         STI ; Interrupts erlauben
  109.         IRET ; Interrupt-Routine beenden
  110. ;
  111. ; Initialisieren der Interrupt-Vektoren
  112. ; und Routinen speicherresistent machen
  113. ;
  114.         ASSUME DS:CODE ; Neue Basis
  115. INIT:   MOV AH,35H ; Adresse des alten
  116.         MOV AL,09H ; INT 09h holen
  117.         INT 21H
  118.         MOV ALTINT9,BX
  119.         MOV ALTINT9[2],ES ; und speichern
  120.         MOV AX,3508H ; Adresse des alten
  121.         INT 21H ; INT 08h holen
  122.         MOV ALTINT8,BX
  123.         MOV ALTINT8[2],ES ; und speichern
  124.         MOV AX,2509H ; INT 09h neu setzen
  125.         MOV DX,OFFSET INT_9
  126.         INT 21H
  127.         MOV AX,2508H ; INT 08h neu setzen
  128.         MOV DX,OFFSET INT_8
  129.         INT 21H
  130.         MOV DX,OFFSET TEXT ; kurze Meldung
  131.         MOV AH,09 ; ausgeben
  132.         INT 21H ; String schreiben
  133. ; Adresse zum resistent-machen laden
  134.         MOV DX,OFFSET INIT ; und Programm
  135.         INT 27H ; resistent beenden
  136. ;
  137. TEXT:   DB 13,10,10,10,'  SCHNECKE - Verlangsamt und stoppt Programme'
  138.         DB 13,10,'  Programmiert von Jürgen Altfeld'
  139.         DB 13,10,'  ALT-0 = Normale Geschwindigkeit    ALT-1 bis ALT-9 = '
  140.         DB 'Verzögerungsfaktor'
  141.         DB 13,10,10,'SCHNECKE ist INSTALLIERT; normale Geschwindigkeit'
  142.         DB 13,10,10,10,'$'
  143. CODE    ENDS
  144.         END START
  145.