home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / grafik / tiff / hercutil.asm < prev    next >
Encoding:
Assembly Source File  |  1990-07-18  |  6.6 KB  |  188 lines

  1. ; ***********************************************************
  2. ; * Programmname  : HERCUTIL.ASM                            *
  3. ; * Inhalt        : Routinen zur Ermittlung des Grafikmodus *
  4. ; *                 und der aktiven Grafikseite bei einer   *
  5. ; *                 Hercules-Karte                          *
  6. ; * Programmiert  : Chr. Monien                             *
  7. ; *               : (c) Verlag Heinz Heise Redaktion c't    *
  8. ; * ------------------------------------------------------- *
  9. ; * Assemblierung: MASM HERCUTIL.ASM;                       *
  10. ; ***********************************************************
  11.  
  12. STATUS    EQU 03BAH     ; Display-Status-Port
  13. INDEX     EQU 03B4H     ; Index-Register
  14. LPSET     EQU 03B9H     ; LP-FlipFlop setzen (Schreiben)
  15. LPRESET   EQU 03BBH     ; LP-FlipFlop löschen (Schreiben)
  16.  
  17. VRETRACE  EQU 128       ; Bit für VRETRACE
  18. HRETRACE  EQU 1         ; Bit für HRETRACE
  19. PIXEL     EQU 8         ; Bit für Pixeldaten
  20.  
  21. PUFFERLEN EQU 20        ; Länge der Zeile in Wörtern
  22. THRESHOLD EQU 2000      ; Schwellwert für Grafikmodus
  23.  
  24. PUBLIC TESTGRAPH        ; Adressen für TP zugänglich machen
  25. PUBLIC GETPAGE          ; Achtung! NEAR-Prozeduren, nicht im
  26.                         ; INTERFACE-Teil einer Unit deklarieren!
  27.  
  28. CODE  SEGMENT BYTE PUBLIC
  29.       ASSUME CS:CODE, DS:NOTHING, ES:NOTHING
  30. PHERC PROC NEAR
  31.  
  32. PUFFER DW PUFFERLEN DUP (?,?) ; Puffer anlegen (2 Zeilen)
  33.  
  34. ;------------------------------------------------------------------------
  35. ;-- TESTGRAPH ermittelt die Position des LightPens in der 340. Zeile
  36. ;--           und vergleicht das Ergebnis mit einem Schwellwert, der
  37. ;--           zur Unterscheidung von Grafik- und Textmodus dient.
  38. ;-- Aufruf von Turbo-PASCAL: function TestGraph: boolean;
  39. TESTGRAPH:
  40.   CLI                   ; bitte keine Interrupts
  41.   MOV AH,VRETRACE       ; auf vertikalen Strahlrücklauf warten
  42.   CALL WAIT_RETRACE
  43.   MOV CX,340            ; Zähler für Zeilen
  44.   MOV AH,HRETRACE       ; auf horizontalen Strahlrücklauf warten
  45. @L1:
  46.   CALL WAIT_RETRACE
  47.   LOOP @L1              ; solange bis Zeile 340 erreicht ist
  48.   CALL GETLPPOS         ; LightPen-Position lesen
  49.   CMP AX,THRESHOLD      ; Textspeicher überschritten ?
  50.   MOV AL,0
  51.   JNA @L2               ; Nein, FALSE zurück
  52.   INC AL                ; TRUE zurück
  53. @L2:
  54.   STI                   ; Interrupts erlauben
  55.   RET
  56.  
  57. ;------------------------------------------------------------------------
  58. ;-- WAIT_RETRACE wartet auf eine positive Flanke der vertikalen bzw.
  59. ;--              horizontalen Synchronisationssignale.
  60. ;-- Eingabe    : AH= 080H  Warten auf VRETRACE
  61. ;--              AH= 001H  Warten auf HRETRACE
  62. ;-- Ausgabe    : keine
  63. WAIT_RETRACE:
  64.   MOV DX,STATUS
  65. @L3:                    ; Loop, solange Bit gesetzt
  66.   IN AL,DX
  67.   TEST AL,AH
  68.   JNE @L3
  69. @L4:                    ; Loop, solange Bit gelöscht
  70.   IN AL,DX
  71.   TEST AL,AH
  72.   JE @L4
  73.   RET
  74.  
  75. ;------------------------------------------------------------------------
  76. ;-- GETLPPOS liest aus den Registern 16 und 17 des CRTC 6845 die
  77. ;--          aktuelle Position des LightPens
  78. ;-- Eingabe: keine
  79. ;-- Ausgabe: AX= Offsetadresse des LightPens
  80. GETLPPOS:
  81.   MOV DX,LPRESET        ; Reset und Set des LightPen-FlipFlops
  82.   OUT DX,AL
  83.   MOV DL,LOW LPSET
  84.   OUT DX,AL
  85.  
  86.   MOV AL,16             ; Register 16 (High-Byte) auslesen
  87.   MOV DL,LOW INDEX
  88.   OUT DX,AL
  89.   INC DX
  90.   IN AL,DX
  91.   MOV AH,AL
  92.  
  93.   MOV AL,17             ; Register 17 (Low-Byte) auslesen
  94.   DEC DX
  95.   OUT DX,AL
  96.   INC DX
  97.   IN AL,DX
  98.   RET
  99.  
  100. ;------------------------------------------------------------------------
  101. ;-- GETPAGE ermittelt die aktuelle Bildschirmseite im Grafikmodus,
  102. ;--         indem der Pixeldatenstrom zum Anfang des Bildes geprüft
  103. ;--         wird. Dazu werden Teile der ersten Zeile von beiden Seiten
  104. ;--         gespeichert und mit 0 (Seite 0, Segment B000h) bzw. 1
  105. ;--         (Seite 1, Segment B800h) aufgefüllt, um eindeutige Ergeb-
  106. ;--         nisse zu erzielen. Nach dem Test wird der alte Bildkontext
  107. ;--         wieder hergestellt.
  108. ;-- Aufruf von Turbo-PASCAL: function GetPage: byte;
  109. GETPAGE:
  110.   PUSH DS               ; Segmentreg. retten
  111.   PUSH ES
  112.   CLD                   ; aufsteigend zählen
  113.   MOV CX,PUFFERLEN      ; Länge steht immer in CX
  114.   CALL SAVE_LINE        ; Zeilen sichern und auf Seite 0 Zeile löschen
  115.                         ; bzw. auf Seite 1 setzen
  116.  
  117.   MOV DX,STATUS         ; Statusport wird abgefragt
  118.   CLI                   ; bitte nicht stören
  119. @L5:
  120.   IN AL,DX              ; auf vertikalen Strahlrücklauf warten
  121.   TEST AL,VRETRACE
  122.   JNE @L5
  123. @L6:
  124.   IN AL,DX              ; auf Ausgabe der 1. Zeile warten
  125.   TEST AL,HRETRACE
  126.   JNE @L6
  127.  
  128.   IN AL,DX              ; Pixeldatum gibt Auskunft über Bildschirmseite
  129.   AND AL,PIXEL
  130.   SHR AL,1              ; auf Bit-Position 0 verschieben
  131.   SHR AL,1
  132.   SHR AL,1
  133.  
  134.   STI                   ; Interrupts wieder freigeben
  135.  
  136.   CALL RESTORE_LINE     ; Originalzustand der Zeilen wiederherstellen
  137.   POP ES                ; Register wiederherstellen
  138.   POP DS
  139.   RET
  140.  
  141. ;------------------------------------------------------------------------
  142. ;-- SAVE_LINE speichert jeweils die erste Zeile von beiden Grafikseiten
  143. ;--           und belegt diese Zeilen mit 0 (Seite 0) bzw. FFFFh
  144. ;--           (Seite 1)
  145. ;-- Eingabe: CX= Länge der Zeile in Wörtern
  146. SAVE_LINE:
  147.   PUSH CS               ; ES= CS
  148.   POP ES
  149.   XOR AX,AX             ; Zeile mit 0 auffüllen
  150.   MOV SI,0B000H         ; Segment von Seite 0
  151.   MOV DI,OFFSET PUFFER  ; Ziel ist der Puffer
  152.   CALL SAVE
  153.   NOT AX                ; Zeile mit 1 auffüllen
  154.   MOV SI,0B800H         ; Segment von Seite 1
  155. SAVE:
  156.   MOV DS,SI             ; DS mit Bildschirm-Segment laden
  157.   XOR SI,SI             ; Offset ist 0
  158.   PUSH CX               ; Anzahl in CX retten
  159. @L7:
  160.   MOVSW                 ; Bildkontext speichern
  161.   MOV WORD PTR DS:[SI-2],AX; Zeile mit AX laden
  162.   LOOP @L7              ; bis Puffer voll
  163.   POP CX                ; CX wieder vom Stack holen
  164.   RET
  165.  
  166. ;------------------------------------------------------------------------
  167. ;-- RESTORE_LINE stellt den alten Bildschirminhalt wieder her.
  168. ;-- Eingabe: CX= Länge der Zeile in Wörtern
  169. RESTORE_LINE:
  170.   PUSH CS               ; DS= CS
  171.   POP DS
  172.   MOV DI,0B000H         ; Segment von Seite 0
  173.   MOV SI,OFFSET PUFFER  ; Quelle ist der Puffer
  174.   CALL RESTORE
  175.   MOV DI,0B800H         ; Segemnt von Seite 1
  176. RESTORE:
  177.   MOV ES,DI             ; ES mit Bildschirm-Segemnt laden
  178.   XOR DI,DI             ; Offset ist 0
  179.   PUSH CX               ; Anzahl in CX retten
  180.   REP MOVSW             ; Bildkontext wieder auf den Bildschirm
  181.   POP CX                ; CX wieder vom Stack nehmen
  182.   RET
  183.  
  184. PHERC ENDP
  185. CODE  ENDS
  186. END
  187.  
  188.