home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / 1991 / 09_10 / asm / listing1.asm next >
Encoding:
Assembly Source File  |  1991-07-03  |  6.0 KB  |  191 lines

  1. ;***********************************************************
  2. ;*  ZEIT.ASM:  ZEIT-MESSUNGEN  MIT  DEM  TIMER  8253       *
  3. ;*           (c) 1991 toolbox & Peter Monadjemi            *
  4. ;***********************************************************
  5. .MODEL SMALL
  6.  
  7. TIMER0_DATA     EQU 40h
  8. TIMER_MODUS     EQU 43h
  9. MODUS_8259      EQU 20h
  10.  
  11. WARTEN MACRO        ; Kleine Verzögerung für das Umschalten
  12.        JMP $+2      ; auf die einzelnen Portregister
  13.        JMP $+2
  14.        JMP $+2
  15.        ENDM
  16. .DATA
  17.  
  18. SAVE_FLAGS     DW ? ; Hier werden die Flags zwischengesp.
  19. TIMER_STAND    DW ? ; Anzahl der gemessenen Timerimpulse
  20. REF_STAND      DW ? ; Vergleichswert
  21. TIMER_OVERFLOW DB ? ; Überlaufflag falls Zeitsspanne > 54 ms
  22.  
  23. TEXT1          DB 0Dh,0Ah,'Gemessene Zeit: '
  24.                ZAEHLER_ADR    DB 5 DUP(?)
  25.                DB  ' Mikrosekunden.', 0dh, 0ah,'$'
  26.  
  27. TEXT2          DB 'Timer - Überlauf, weil gemessener '
  28.                DB 'Zeitraum zu groß !',0Dh,0Ah,'$'
  29.  
  30. .CODE
  31. PUBLIC TIMER_START, TIMER_STOP, TIMER_READ
  32.  
  33. TIMER_START PROC
  34.  
  35.  PUSH AX                 ; Zunächst AX retten
  36.  PUSHF                   ; dann die Flags nach AX
  37.  POP AX                  ; um sie von dort
  38.  MOV SAVE_FLAGS,AX       ; zwischenzuspeichern
  39.  STI                     ; Interrupts wieder zulassen
  40.  MOV AL,34h              ; Timer-Modus 2 setzen
  41.  OUT TIMER_MODUS,AL
  42.  WARTEN                  ; Kurze Verzögerung
  43.  XOR AL,AL               ; Timer0 auf Null setzen
  44.  OUT TIMER0_DATA,AL      ; Zuerst das niederwertige
  45.  WARTEN                  ; Kurze Verzögerung
  46.  OUT TIMER0_DATA,AL      ; dann das höherwertige Byte
  47.                  
  48.  WARTEN                  ; Kurze Verzögerung
  49.  
  50.  CLI                     ; Keine Interrupts bitte
  51.  MOV AL,34h              ; Timer wieder aktivieren
  52.  OUT TIMER_MODUS,AL      ; d.h. in Modus 2 schalten
  53.  WARTEN                  ; Kurze Verzögerung
  54.  XOR AL,AL               ; Timer 0 wie gehabt auf Null setzen
  55.  OUT TIMER0_DATA,AL
  56.  WARTEN
  57.  OUT TIMER0_DATA,AL
  58.  POP AX                  ; Interruptflag und AX wiederholen
  59.  RET                     ; Rückkehr zum Messprogramm
  60.  TIMER_START ENDP
  61.  
  62.  TIMER_STOP PROC         ; Timer ausschalten
  63.  PUSH AX                 ; AX retten
  64.  PUSH CX                 ; CX retten
  65.  MOV AL,0                ; Timer einfrieren
  66.  OUT TIMER_MODUS,AL      ; dazu Bit 4,5 auf Null
  67.  MOV AL,0Ah              ; 8259A auf Auftreten
  68.  OUT MODUS_8259,AL       ; eines Interrupts checken
  69.  WARTEN                  ; Kurze Verzögerung
  70.  
  71.  IN AL,MODUS_8259        ; Trat Interrupt wegen
  72.                          ; Überlauf auf?
  73.  AND AL,01h              ; Ergebnis, d.h. Bit 0
  74.  MOV TIMER_OVERFLOW,AL   ; in einer Variablen speichern
  75.  
  76.  STI                     ; Interrupts wieder zulassen
  77.  IN AL,TIMER0_DATA       ; Timer0 einlesen
  78.  WARTEN                  ; Kurze Verzögerung
  79.  MOV AH,AL               ; Erst das niederwertige Byte
  80.  IN AL,TIMER0_DATA       ; dann das höherwertige Byte
  81.  XCHG AH,AL
  82.  NEG AX                  ; Differenz berechnen
  83.  MOV TIMER_STAND,AX      ; und abspeichern
  84.  
  85.  MOV REF_STAND,0         ; Referenzzähler auf Null
  86.  MOV CX,32               ; 32 Leer-Durchläufe
  87.  CLI                     ; Auch hier keine Interrupts
  88.  L1:
  89.  CALL REF_TIMER_EIN      ; Timer0 einschalten
  90.  CALL REF_TIMER_AUS      ; Timer0 ausschalten
  91.  LOOP L1                 ; das ganze 32 Mal
  92.  
  93.  STI                     ; Wieder Interrupts erlaubt
  94.  ADD REF_STAND,16        ; Mittelwert bilden: +0.5
  95.  MOV CL,5                ; dann Speichervariable
  96.  SHR REF_STAND,CL        ; durch 32 teilen
  97.  MOV AX,REF_STAND        ; Referenzwert nach AX und
  98.  SUB TIMER_STAND,AX      ; von gemessener Zeit abziehen
  99.  
  100.  MOV AX,SAVE_FLAGS       ; Die alten Flags wiederholen
  101.  PUSH AX                 ; Flagregister zurück
  102.  POPF
  103.  
  104.  POP CX                  ; Register wiederholen
  105.  POP AX
  106.  RET
  107. TIMER_STOP ENDP
  108.  
  109. REF_TIMER_EIN PROC       ; Referenztimer-Modul
  110.  PUSH AX
  111.  PUSHF
  112.  MOV AL,34h              ; Timer einschalten
  113.  OUT TIMER_MODUS,AL
  114.  WARTEN
  115.  XOR AL,AL               ; und auf Null setzen
  116.  OUT TIMER0_DATA,AL
  117.  WARTEN
  118.  OUT TIMER0_DATA,AL
  119.  POPF
  120.  POP AX
  121.  RET
  122. REF_TIMER_EIN ENDP
  123.  
  124. REF_TIMER_AUS PROC
  125.  PUSH AX
  126.  PUSHF
  127.  MOV AL,0                ; Timer wieder ausschalten
  128.  OUT TIMER_MODUS,AL
  129.  WARTEN
  130.  IN AL,TIMER0_DATA       ; Zählerstand ablesen
  131.  WARTEN
  132.  MOV AH,AL
  133.  IN AL,TIMER0_DATA
  134.  XCHG AH,AL
  135.  NEG AX
  136.  ADD REF_STAND,AX        ; Auf Referenzzähler addieren
  137.  POPF
  138.  POP AX
  139.  RET
  140. REF_TIMER_AUS ENDP
  141.  
  142. TIMER_READ    PROC       ; Ausgabe des Zählerstandes
  143.               PUSHF      ; Register retten
  144.               PUSH AX
  145.               PUSH BX
  146.               PUSH CX
  147.               PUSH DX
  148.               PUSH DI
  149.  
  150.               CMP TIMER_OVERFLOW,0; Trat Überlauf auf?
  151.               JZ  PRINT_ZEIT      ; Nein, dann Zeit anzeigen
  152.               MOV DX,OFFSET TEXT2 ; Ansonsten Fehlermeldung
  153.               MOV AH,09
  154.               INT 21h
  155. JMP SHORT ENDE
  156.  
  157. PRINT_ZEIT:
  158.               MOV AX,TIMER_STAND ; Zählerstand nach AX
  159.               MOV DX,8381        ; in Mikrosek. umrechnen
  160.               MUL DX
  161.               MOV BX,10000
  162.               DIV BX
  163.  
  164.               MOV BX,10      ; und nacheinander jede Ziffer
  165.               MOV DI,5       ; in den Puffer ZAEHLER_ADR
  166.          L2:                 ; eintragen
  167.               XOR DX,DX      ; DX auf Null setzen
  168.               DIV BX         ; Letzte Ziffer abtrennen
  169.               ADD DL,'0'     ; In ASCII-Code umwandeln
  170.               MOV ZAEHLER_ADR-1[DI],DL
  171.               DEC DI         ; Zähler minus eins
  172.               CMP DI,0       ; Schon Null?
  173.               JNE L2         ; Nein, dann weiter
  174.  
  175.               MOV AH,09      ; Text ist jetzt im Puffer
  176.               MOV DX,OFFSET TEXT1 ; daher ges.Text ausgeben
  177.               INT 21h
  178.  
  179.          ENDE:
  180.               POP DI         ; Register wieder herstellen
  181.               POP DX
  182.               POP CX
  183.               POP BX
  184.               POP AX
  185.               POPF
  186.         RET
  187.     TIMER_READ ENDP
  188. END
  189. ;***********************************************************
  190. ;*                  Ende von ZEIT.ASM                      *
  191.