home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / grafik / tiff / vgaload.asm < prev    next >
Encoding:
Assembly Source File  |  1990-06-25  |  20.4 KB  |  516 lines

  1. ;****************************************
  2. ;* VGALOAD.ASM
  3. ;*
  4. ;* Syntax: VGALOAD dateiname [/A] [/E] [/Wnn]
  5. ;*
  6. ;* Bedeutung der Parameter: /A: Bildschirm am Anfang eingeschaltet lassen
  7. ;*                          /E: Bildschirm am Ende eingeschaltet lassen
  8. ;*                          /W: nach Laden und Anzeige des Bildes
  9. ;*                              nn Sekunden warten
  10. ;*
  11. ;****************************************
  12.  
  13. ;*** Makro zum Lesen von Zeichen aus Parameterzeile
  14.  
  15. getpar  macro
  16.         local mac002         ;Lokale Sprungmarke definieren
  17.  
  18.         mov  al,ds:anzpar    ;Anzahl Zeichen in Parameterzeile holen
  19.         mov  ah,00           ;auf 16 Bit bringen
  20.         cmp  si,ax           ;Zeiger in Parameterzeile mit Anzahl vgl.
  21.         stc                  ;Ende signalisieren
  22.         je   mac002          ;Ende erreicht
  23.         mov  al,parzeil[si]  ;noch kein Ende: Zeichen nach al holen
  24.         inc  si              ;Zeiger in Parameterzeile erhöhen
  25.         clc                  ;Carry-Flag löschen -> Ende nicht erreicht
  26. mac002:
  27.         endm                 ;Ende des Makros
  28.  
  29. ;*** Konstanten
  30.  
  31. anzpar  equ  offset 80h      ;PSP Offset 80h: Länge der Parameterzeile
  32. parzeil equ  offset 82h      ;PSP Offset 81h: Parameterzeile
  33.         ;                     (eigentlich 81h, dort aber Leerzeichen)
  34. video   equ  0a000h          ;Segment-Adresse des Video-RAMs
  35. pufflen equ  1024            ;Größe des Puffers beim Dateilesen
  36. stdmod  equ  7               ;Standard-Text-Modus für Fehlermeldungen
  37.  
  38. code    segment para 'CODE'
  39.  
  40.         org  100h            ;256 Byte für PSP reservieren
  41.  
  42.         assume cs:code, ds:code, es:code, ss:code
  43.  
  44. main    proc near            ;Hauptprogramm
  45.  
  46. start:  jmp  start1          ;Variablenbereich überspringen
  47.  
  48. ;*** Variablen
  49.  
  50. handle  dw   (?)             ;DOS-Datei-Handle
  51. pag     db   0               ;Nummer des Video-RAM-Segments
  52. kennung db   (?)             ;Kennungsbyte für Wiederholungen
  53. zaehler equ  this word       ;Zähler beim Dekomprimieren
  54. anz_l   db   (?)             ;dessen Low-Byte
  55. anz_h   db   (?)             ;dessen High-Byte
  56. wdhflag db   0               ;Flag/Status beim Lesen von Wiederholungen
  57.         ;                     0: Normal, keine Wdh. lesen
  58.         ;                     1: Low-Byte d. Anzahl d. Wdh. lesen
  59.         ;                     2: dto. High-Byte
  60.         ;                     3: zu wiederholendes Byte lesen
  61. endeflg db   0               ;Flag für Dateiende
  62. openflg db   0               ;Flag für Datei geöffnet ja/nein
  63. para_a  db   0               ;Schalter für Parameter "A":
  64.         ;                     Bildschirm am Anfang eingeschaltet lassen
  65. para_e  db   0               ;Schalter für Parameter "E":
  66.         ;                     Bildschirm am Ende eingeschaltet lassen
  67. para_w  db   0               ;Schalter für Parameter "W":
  68.         ;                     Nach Anzeige gewisse Zeit warten
  69. pause   dw   0               ;Länge der Pause für Parameter "W"
  70. anzahl  dw   (?)             ;Anzahl der gelesenen Zeichen im Puffer
  71. altmode db   (?)             ;Video-Modus bei Einsprung
  72. altint  equ  this dword      ;Adresse für alten Interrupt-Vektor
  73. altinto dw   (?)             ;dessen Offset-Adresse
  74. altints dw   (?)             ;dessen Segment-Adresse
  75. fehler  dw   0               ;Fehlercode bei Programmende (ERRORLEVEL)
  76. err_tab equ  this word       ;Tabelle mit Zeigern auf Fehlermeldungen
  77.         dw   0               ;kein Fehler, Dummy
  78.         dw   meld1           ;File-Sharing nicht möglich
  79.         dw   meld2           ;Datei nicht gefunden
  80.         dw   meld3           ;zu viele geöffnete Dateien
  81.         dw   meld4           ;Zugriff verweigert
  82.         dw   meld5           ;unerwartetes Dateiende
  83.         dw   meld6           ;Bildüberlauf, Datei zu lang
  84.         dw   meld7           ;unbekannter Fehler
  85.         dw   meld8           ;Dateiname fehlt
  86.         dw   meld9           ;ungültige Parameterzeile
  87.  
  88. adjust  db   0,1,2,2,3,4,7   ;Abgleichungstabelle für DOS-Fehlernummern
  89.         db   7,7,7,7,7,4
  90.  
  91. sec_t10 dw      0, 182, 364  ;Sekunden-Zehner-Tabelle
  92.         dw    546, 728, 910
  93.         dw   1092,1274,1456
  94.         dw   1638,1820
  95. sec_t1  dw     0, 18, 36, 55 ;Sekunden-Einer-Tabelle
  96.         dw    73, 91,109,127
  97.         dw   146,164,182
  98. puffer  db   pufflen dup (?) ;Puffer beim Dateilesen
  99.  
  100. filenam db   80 dup (0)      ;Name der zu lesenden Datei
  101.  
  102. ;*** Fehlermeldungen
  103.  
  104. meld1:  db   "File-Sharing ist nicht möglich!",13,10,13,10,"$"
  105. meld2:  db   "Datei nicht gefunden!",13,10,13,10,"$"
  106. meld3:  db   "Zu viele Dateien geöffnet!",13,10,13,10,"$"
  107. meld4:  db   "Zugriff verweigert!",13,10,13,10,"$"
  108. meld5:  db   "Unerwartetes Dateiende!",13,10,13,10,"$"
  109. meld6:  db   "Datei zu lang, Bildüberlauf!",13,10,13,10,"$"
  110. meld7:  db   "Fehler! Ursache unklar!",13,10,13,10,"$"
  111. meld8:  db   "Dateiname fehlt!",13,10,13,10,"$"
  112. meld9:  db   "ungültige Parameterzeile!",13,10,13,10,"$"
  113.  
  114. ;*** Code-Beginn
  115.  
  116. start1  label near           ;eigentlicher Programm-Start
  117.  
  118. ;*** Parameterzeile analysieren
  119.  
  120.         mov  si,0            ;Zeiger in Parameterzeile initialisieren
  121.  
  122. ;*** Dateinamen holen
  123.  
  124.         mov  di,0            ;Zeiger in Zielbereich für Dateinamen init.
  125.         mov  bx,8            ;Fehlernummer initialisieren
  126.  
  127. get_n0: getpar               ;Zeichen aus Parameterzeile holen
  128.         jc   readerr         ;Ende vorzeitig erreicht
  129.  
  130.         cmp  al,32           ;Leerzeichen überlesen
  131.         je   get_n0
  132.  
  133. get_n1: mov  filenam[di],al  ;Zeichen in Dateinamen übernehmen
  134.         inc  di              ;Zeiger in Dateinamen erhöhen
  135.         getpar               ;Zeichen aus Parameterzeile holen
  136.         jnc  cont1           ;Ende der Parameterzeile noch nicht erreicht
  137. jmpopen:jmp  open            ;Sprung zum Öffnen der Datei
  138.  
  139. cont1:  cmp  al,32           ;Zeichen mit Leerzeichen vgl.
  140.         jne  get_n1          ;kein Leerzeichen, dann aufnehmen
  141.  
  142.         mov  bx,9            ;Fehlernummer initialisieren
  143.  
  144. get_p0: getpar               ;Parameter-Behandlung
  145.         jc   jmpopen         ;Ende der Parameterzeile erreicht
  146.         cmp  al,32           ;Leerzeichen überlesen
  147.         je   get_p0
  148.  
  149.         cmp  al,"/"          ;handelt es sich um Parameterangabe ?
  150.         jne  readerr         ;nein, dann Fehler
  151.  
  152.         getpar               ;Parameter-Buchstaben einlesen
  153.         jc   readerr         ;nicht gefunden, also Fehler
  154.  
  155.         cmp  al,"a"          ;Test auf Schalter "A"
  156.         je   set_p1          ;ggf. setzen
  157.         cmp  al,"A"          ;dto. Großschreibung
  158.         je   set_p1
  159.  
  160.         cmp  al,"e"          ;Test auf Schalter "E"
  161.         je   set_p2          ;ggf. setzen
  162.         cmp  al,"E"          ;dto. Großschreibung
  163.         je   set_p2
  164.  
  165.         cmp  al,"w"          ;Test auf Schalter "W"
  166.         je   get_pw0         ;ggf. weiter einlesen
  167.         cmp  al,"W"          ;dto. Großschreibung
  168.         je   get_pw0
  169.  
  170. readerr:mov  fehler,bx       ;Fehlernummer setzen
  171.         jmp  errausg         ;Fehlermeldung ausgeben
  172.  
  173. set_p1: mov  para_a,1        ;Schalter "A" setzen
  174.         jmp  short get_p0    ;weiter einlesen
  175.  
  176. set_p2: mov  para_e,1        ;Schalter "E" setzen
  177.         jmp  short get_p0    ;weiter einlesen
  178.  
  179. get_pw0:mov  para_w,1        ;Schalter "W" setzen
  180.         mov  bp,sec_t10      ;Zeiger auf Sekunden-Zehner-Tabelle setzen
  181.         mov  pause,0         ;Pausenlänge initialisieren
  182.         mov  cx,2            ;Schleifen-Zähler
  183.  
  184. get_pw1:getpar               ;1. Ziffer lesen
  185.         jc   readerr         ;vorzeitiges Ende, also Fehler
  186.         sub  al,"0"          ;Test auf Ziffer
  187.         js   readerr         ;kleiner als 0, also Fehler
  188.         cmp  al,9            ;größer als 9
  189.         jg   readerr         ;ja, also Fehler
  190.         shl  al,1            ;mit 2 multiplizieren (Wortzugriff)
  191.         mov  ah,0            ;auf 16 Bit bringen
  192.         mov  di,ax           ;ins Index-Register übertragen
  193.         mov  ax,pause        ;bisherige Pausenlänge nach AX
  194.         add  ax,[bp+di]      ;Pausenlänge aufsummieren
  195.         mov  pause,ax        ;Ergebnis zurückschreiben
  196.         mov  bp,sec_t1       ;Zeiger auf Sekunden-Einer-Tabelle setzen
  197.         loop get_pw1         ;Schleifenende
  198.         jmp  get_p0          ;weiter einlesen
  199.  
  200. ;*** Datei öffnen
  201.  
  202. open:   mov  ah,3dh          ;DOS-Fkt. 3dh: Datei öffnen (Handle)
  203.         mov  al,0            ;Zugriffsmodus 0: Lesen
  204.         mov  dx,offset filenam;Adresse des Dateinamens
  205.         int  21h             ;Öffnen ausführen
  206.         jc   doserr          ;bei Fehlern Abbruch
  207.  
  208.         mov  handle,ax       ;DOS-Handle merken
  209.         mov  openflg,1       ;Flag für Datei geöffnet setzen
  210.  
  211. ;*** bisherigen Video-Modus holen
  212.  
  213.         mov  ah,0fh          ;Funktion 0fh: Video-Informationen liefern
  214.         int  10h             ;ausführen
  215.         mov  altmode,al      ;Video-Modus merken
  216.  
  217. ;*** Video-Modus setzen
  218.  
  219.         mov  ah,0            ;Funktion 0: Modus setzen
  220.         mov  al,30h          ;Modus 30h: 800*600 P., 256 Farben aus 256K
  221.         int  10h             ;ausführen
  222.  
  223. ;*** Bildschirm abschalten
  224.  
  225.         mov  al,para_a       ;Abschalten unterbunden ?
  226.         jne  skipoff         ;ggf. überspringen
  227.  
  228.         mov  dx,3c4h         ;DX auf TS Index Register
  229.         mov  al,1            ;Index 1 -> TS Mode
  230.         out  dx,al           ;TS Mode adressieren
  231.         mov  dx,3c5h         ;Port-Adresse indexed TS Register nach DX
  232.         in   al,dx           ;TS-Mode holen
  233.         and  al,11011111b    ;Bit 5 löschen (Screen Off Bit)
  234.         out  dx,al           ;zurückschreiben
  235. skipoff:
  236.  
  237. ;*** Paletten-Register und Kennzeichen laden
  238.  
  239.         mov  ah,3fh          ;DOS-Fkt. 3fh: Datei lesen (Handle)
  240.         mov  bx,handle       ;DOS-Handle holen
  241.         mov  cx,3*256+3      ;Anzahl der zu lesenden Zeichen:
  242.         ;                     256 Farbwerte à 3 Byte,
  243.         ;                     1 Byte Paging Mode,
  244.         ;                     1 Byte Color Page,
  245.         ;                     1 Byte Kennzeichen für Wdh.
  246.         mov  dx,offset puffer;Zielbereich für Daten
  247.         int  21h             ;Daten lesen
  248.         jnc  ok2             ;kein Fehler, dann weiter
  249.  
  250. doserr: mov  di,ax           ;Fehlernummer nach di
  251.         cmp  di,12           ;Vergleich mit größter bekannter Fehlernr.
  252.         jbe  bekannt         ;bekannter Fehler, dann weiter
  253.         mov  ax,7            ;sonst Nummer für unbekannten Fehler
  254.         jmp  close
  255. bekannt:mov  al,adjust[di]   ;abgeglichene Fehlernummer nach AL
  256.         mov  ah,0            ;auf 16 Bit bringen
  257.         jmp  close           ;Fehlermeldung, Ende
  258.  
  259. ok2:    cmp  ax,3*256+3      ;Kontrolle, ob alle Zeichen gelesen
  260.         je   palette         ;ok, dann Paletten-Register setzen
  261.         mov  ax,5            ;sonst Fehler: Unerwartetes Dateiende
  262.         jmp  close           ;Fehlermeldung, Datei schließen, Ende
  263.  
  264. ;*** Paletten-Register setzen
  265.  
  266. palette:mov  ah,10h          ;Fkt. 10h: Paletten-Register bearbeiten
  267.         mov  al,12h          ;Sub-Fkt. 12h: Gruppe von Farb-Reg. setzen
  268.         push ds              ;ES:DX = Zeiger auf Tabelle mit Farbwerten
  269.         pop  es              ;DS nach ES kopieren
  270.         mov  dx,offset puffer;Offset der Tabelle nach DX
  271.         mov  bx,0            ;Start bei Farb-Register 0
  272.         mov  cx,256          ;256 Register setzen
  273.         int  10h             ;ausführen
  274.  
  275. ;*** Paging Mode setzen
  276.  
  277.         mov  ah,10h          ;Fkt. 10h: Paletten-Register bearbeiten
  278.         mov  al,13h          ;Sub-Fkt. 13h: Color-Page bearbeiten
  279.         mov  bl,0            ;Select Paging Mode
  280.         mov  bh,puffer[3*256];Modus aus Lesepuffer holen
  281.         int  10h             ;setzen
  282.  
  283. ;*** Color Page setzen
  284.  
  285.         mov  ah,10h          ;Fkt. 10h: Paletten-Register bearbeiten
  286.         mov  al,13h          ;Sub-Fkt. 13h: Color-Page bearbeiten
  287.         mov  bl,1            ;Select Page
  288.         mov  bh,puffer[3*256+1];Seite aus Lesepuffer holen
  289.         int  10h             ;setzen
  290.  
  291. ;*** Kennzeichen für Wiederholungen setzen
  292.  
  293.         mov  al,puffer[3*256+2];Kennzeichen aus Lesepuffer holen
  294.         mov  kennung,al      ;und merken
  295.  
  296. ;*** Initialisierungen
  297.  
  298.         mov  di,0            ;Offset in Video-Segment
  299.         mov  ax,video        ;ES auf Startadresse Video-RAM setzen
  300.         mov  es,ax
  301.  
  302. ;*** erstes Video-RAM-Segment selektieren
  303.  
  304.         mov  dx,3cdh         ;DX auf Segment-Select-Register setzen
  305.         in   al,dx           ;einlesen
  306.         and  al,11111000b    ;Write-Segment-Pointer (Bit 0-2) auf 0
  307.         out  dx,al           ;und zurückschreiben
  308.  
  309. ;*** Puffer füllen / laden
  310.  
  311. loadpuf:mov  ah,3fh          ;DOS-Fkt. 3fh: Datei lesen (Handle)
  312.         mov  bx,handle       ;DOS-Handle holen
  313.         mov  cx,pufflen      ;Anz. d. zu lesenden Zeichen auf Pufferlänge
  314.         mov  dx,offset puffer;Zielbereich für Daten ist Puffer
  315.         int  21h             ;Datei lesen
  316.         jc   doserr          ;bei Fehlern Abbruch
  317.  
  318.         cmp  ax,pufflen      ;Puffer voll, d.h. noch nicht eof?
  319.         je   skip1           ;ja, dann weiter
  320.  
  321.         mov  endeflg,1       ;sonst Ende-Flag setzen
  322.  
  323. skip1:  mov  anzahl,ax       ;Anzahl der gelesenen Zeichen merken
  324.  
  325.         mov  si,0            ;Index in Puffer auf 0
  326.  
  327. test_i: cmp  si,anzahl       ;Puffer komplett ausgelesen?
  328.         jne  read            ;nein, dann weiter auslesen
  329.  
  330.         cmp  endeflg,1       ;Ende der Datei erreicht?
  331.         jne  loadpuf         ;nein, dann erneut Puffer füllen/laden
  332.  
  333.         mov  ax,0            ;kein Fehler
  334.         jmp  close           ;Datei schließen, Ende
  335.  
  336. ;*** Puffer auslesen
  337.  
  338. read:   mov  al,puffer[si]   ;Byte[Index] holen
  339.  
  340.         cmp  wdhflag,0       ;wird gerade eine Wiederholung gelesen?
  341.         je   normal          ;nein, dann Byte normal behandeln
  342.  
  343.         cmp  wdhflag,1       ;wurde Low-Byte d. Anz. d. Wdh. gelesen?
  344.         je   lies_l          ;ja
  345.  
  346.         cmp  wdhflag,2       ;wurde High-Byte d. Anz. d. Wdh. gelesen?
  347.         je   lies_h          ;ja
  348.  
  349. ;*** Byte-Wiederholung
  350.  
  351. poke0:  mov  es:[di],al      ;Byte in Video-RAM schreiben
  352.         inc  di              ;Offset in Video-Segment erhöhen
  353.         jnz  test_z          ;Ende Segment nocht nicht erreicht
  354.         inc  pag             ;Nummer des Video-RAM-Segments erhöhen
  355.         cmp  pag,8           ;letztes Segment überschritten?
  356.         jb   segok0          ;nein, dann weiter
  357.  
  358.         mov  ax,6            ;sonst Fehler: Bildüberlauf
  359.         jmp  close           ;Datei schließen, Ende
  360.  
  361. segok0: push ax              ;AX-Register sichern
  362.         mov  dx,3cdh         ;DX auf Segment-Select-Register setzen
  363.         in   al,dx           ;einlesen
  364.         and  al,11111000b    ;Write-Segment-Pointer zunächst init.
  365.         or   al,pag          ;dann Nr. des Video-RAM-Segments odern
  366.         out  dx,al           ;zurückschreiben
  367.         pop  ax              ;AX-Register wiederherstellen
  368.  
  369. test_z: dec  zaehler         ;Zähler für Wiederholungen vermindern
  370.         jne  poke0           ;Ende noch nicht erreicht, Schleife
  371.         mov  wdhflag,0       ;sonst Flag für Wdh. löschen
  372.         jmp  short i_plus    ;nächstes Byte lesen
  373.  
  374. ;*** keine Wiederholung zu lesen
  375.  
  376. normal: cmp  al,kennung      ;Kennzeichen für Wiederholung gelesen?
  377.         je   kenn            ;ja, dann Kennung setzen
  378.  
  379. poke:   mov  es:[di],al      ;Byte in Video-RAM schreiben
  380.  
  381.         inc  di              ;Offset in Video-Segment erhöhen
  382.         jnz  i_plus          ;Ende Segment noch nicht erreicht
  383.  
  384.         inc  pag             ;sonst Nummer des Video-RAM-Segments erhöhen
  385.         cmp  pag,8           ;letztes Segment überschritten?
  386.         jb   segok           ;nein, in Ordnung
  387.  
  388.         mov  ax,6            ;sonst Fehler: Bildüberlauf
  389.         jmp  close           ;Datei schließen, Ende
  390.  
  391. segok:  mov  dx,3cdh         ;DX auf Segment-Select-Register
  392.         in   al,dx           ;einlesen
  393.         and  al,11111000b    ;Write-Segment-Pointer zunächst init.
  394.         or   al,pag          ;dann Nummer des Video-RAM-Segments odern
  395.         out  dx,al           ;und zurückschreiben
  396.  
  397. ;*** Index erhöhen
  398.  
  399. i_plus: inc  si              ;Index in Lese-Puffer erhöhen
  400.         jmp  test_i          ;auf Ende testen
  401.  
  402. ;*** Wiederholung wurde gelesen
  403.  
  404. lies_l: mov  anz_l,al        ;Low-Byte der Anzahl der Wdh. merken
  405.         mov  wdhflag,2       ;Kennzeichen weiterzählen
  406.         jmp  short i_plus    ;weiterlesen
  407.  
  408. lies_h: mov  anz_h,al        ;High-Byte der Anzahl der Wdh. merken
  409.         mov  wdhflag,3       ;Kennzeichen weiterzählen
  410.         jmp  short i_plus    ;weiterlesen
  411.  
  412. ;*** Kennzeichen wurde gelesen/erkannt
  413.  
  414. kenn:   mov  wdhflag,1       ;Kennzeichen für Wiederholungen setzen
  415.         jmp  short i_plus    ;weiterlesen
  416.  
  417. ;*** Datei schließen
  418.  
  419. close:  mov  fehler,ax       ;Fehlernummer merken
  420.  
  421.         mov  al,openflg      ;Dateischließen erforderlich?
  422.         je   skip_cl         ;nein, Schließen überspringen
  423.  
  424.         mov  ah,3eh          ;DOS-Fkt. 3eh: Datei schließen (Handle)
  425.         mov  bx,handle       ;DOS-Handle holen
  426.         int  21h             ;Datei schließen
  427.  
  428. skip_cl:cmp  fehler,0        ;ist ein Fehler aufgetreten?
  429.         je   show            ;nein, Bildschirm einschalten
  430.  
  431. ;*** auf Video-Textmodus umschalten
  432.  
  433.         mov  ah,0            ;Funktion 0: Modus setzen
  434.         mov  al,stdmod       ;Video-Modus für Fehlermeldungen holen
  435.         int  10h             ;ausführen
  436.  
  437. ;*** Fehlermeldung ausgeben
  438.  
  439. errausg:mov  ax,fehler       ;Fehlernummer nach AX
  440.         shl  ax,1            ;mit 2 multiplizieren (Wort-Zugriff)
  441.         mov  si,ax           ;Ergebnis ins Index-Register
  442.         mov  dx,err_tab[si]  ;Offset der Fehlermeldung nach DX
  443.         mov  ah,09h          ;DOS-Fkt. 09h: Zeichenkette ausgeben
  444.         int  21h             ;Fehlermeldung ausgeben
  445.         jmp  short ende      ;zum Programm-Ende
  446.  
  447. ;*** Bildschirm einschalten
  448.  
  449. show:   mov  dx,3c4h         ;DX auf TS Index Register
  450.         mov  al,1            ;Index auf 1 -> TS Mode
  451.         out  dx,al           ;TS-Mode adressieren
  452.         mov  dx,3c5h         ;Port-Adresse indexed TS Register nach DX
  453.         in   al,dx           ;TS-Mode holen
  454.         or   al,00100000b    ;Bit 5 setzten (Screen Off Bit)
  455.         out  dx,al           ;zurückschreiben
  456.  
  457. ;*** Warteschleife
  458.  
  459.         mov  al,para_w       ;Warten erwünscht ?
  460.         je   exit            ;nein, dann Aussprung
  461.  
  462.         mov  ah,35h          ;DOS-Fkt. 35h: Interrupt-Vektor holen
  463.         mov  al,1ch          ;Interrupt 1ch: Periodischer Interrupt
  464.         int  21h             ;bisherige Interrupt-Adresse holen
  465.         mov  altints,es      ;Segmentadresse merken
  466.         mov  altinto,bx      ;Offsetadresse merken
  467.         mov  ah,25h          ;DOS-Fkt. 25h: Interrupt-Vektor setzen
  468.         mov  al,1ch          ;Interrupt 1ch: Periodischer Interrupt
  469.         mov  dx,offset waitint;Offsetadresse des Pausen-Interrupts
  470.         int  21h             ;Interrupt-Vektor setzen
  471. warten: mov  ax,pause        ;Pausenzähler testen
  472.         jne  warten          ;noch nicht null, weiter warten
  473.         mov  ah,25h          ;Interrupt 25h: Interrupt-Vektor setzen
  474.         mov  ah,1ch          ;Interrupt 1ch: Periodischer Interrupt
  475.         push ds              ;Datensegmentregister retten
  476.         mov  dx,altinto      ;Vektor wiederherstellen (Offset)
  477.         mov  ax,altints      ;Vektor wiederherstellen (Segment)
  478.         mov  ds,ax
  479.         int  21h             ;alten Interrupt-Vektor wiederherstellen
  480.         pop  ds              ;Datensegmentregister wiederherstellen
  481.  
  482. ;*** Bildschirm zurückschalten
  483.  
  484. exit:   mov  al,para_e       ;Zurückschalten unterbunden ?
  485.         jne  ende            ;ggf. Bildschirmmodus unverändert lassen
  486.  
  487.         mov  ah,0            ;Funktion 0: Modus setzen
  488.         mov  al,altmode      ;Video-Modus bei Einsprung holen
  489.         int  10h             ;ausführen
  490.  
  491. ;*** Programm beenden
  492.  
  493. ende:   mov  ah,4ch          ;DOS-Fkt. 4ch: Programm beenden
  494.         mov  ax,fehler       ;Fehler-Code für ERRORLEVEL holen
  495.         int  21h             ;Programm beenden
  496.  
  497. main    endp
  498.  
  499. ;*** Warte-Interrupt für Pause nach Anzeige eines Bildes
  500. ;*** vermindert bei jedem Aufruf den Pausenzähler "pause",
  501. ;*** das Hauptprogramm wartet, bis dieser Zähler Null erreicht
  502.  
  503. waitint proc far             ;Prozedur-Beginn
  504.  
  505.         pushf                ;Flags sichern - Interrupt simulieren
  506.         call cs:[altint]     ;bisherigen Interrupt ausführen
  507.  
  508.         dec  cs:pause        ;Pausenzähler vermindern
  509.  
  510.         iret                 ;Interrupt beenden
  511.  
  512. waitint endp                 ;Prozedur-Ende
  513.  
  514. code    ends                 ;Code-Ende
  515.         end main
  516.