home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / assemblr / library / grafik / 136color / 136color.asm next >
Assembly Source File  |  1990-11-11  |  18KB  |  731 lines

  1. ; Programm: 136color.asm
  2. ; Autor:    Ingo Kubbilun
  3. ; (c)1990 DMV Widuch GmbH & Co. KG
  4.  
  5. ;  Implementierung neuer Grafikroutinen
  6. ;  zur Bereitstellung von 136 Farben
  7. ;  gleichzeitig für die EGA-Modi 640x200,
  8. ;  640x350, 640x480 und 800x600 in das
  9. ;  BIOS durch Halbierung der X-Auflösung
  10. ;
  11. ;  Programm installiert sich resident im
  12. ;  Speicher und kann durch nochmaligen
  13. ;  Aufruf wieder entfernt werden.
  14.  
  15. CODE  SEGMENT BYTE
  16.  
  17.       ASSUME CS:CODE,DS:CODE
  18.  
  19. ; EQU's
  20.  
  21. FBUFADR        EQU INIT
  22. TSENG          EQU 29H
  23. PARADISE       EQU 58H
  24. VIDEO7         EQU 62H
  25. VMODE_800x600  EQU -1
  26. REGAX          EQU [BP+10H]
  27.  
  28. ; Sprung zur Installierung
  29.  
  30.       ORG 0100H
  31.  
  32. START: JMP INIT
  33.       ;Sprung zur Installierungs-Sequenz
  34.  
  35. ; Daten- und Variablenbereich
  36.  
  37. ENVSEG      DW ?
  38. MSG1        DB 0DH,0AH,"136COLOR V1.0 gel"
  39.             DB "aden und aktiviert...",0DH
  40.             DB 0AH,"$"
  41. MSG2        DB 0DH,0AH,"136COLOR V1.0 aus"
  42.             DB " Speicher entfernt...",0DH
  43.             DB 0AH,"$"
  44. MSG3        DB 0DH,0AH,"136COLOR V1.0 kon"
  45.             DB "nte nicht entfernt werden"
  46.             DB "...",0DH,0AH,"$"
  47. OLDINT_10H  DW ?,?
  48. OLDSS       DW ?
  49. OLDSP       DW ?
  50. MAXX        DW ?
  51. MAXY        DW ?
  52. GETPOS_ADR  DW ?
  53. MODE_FLAG   DB ?
  54. CRT_MODE    DB ?
  55. ACTIVE_FLAG DB ?
  56. COLOR       DW ?
  57. SCR_OFFSET  DW ?
  58.  
  59. ; Farbtabelle
  60.  
  61. COLTAB      DB 00H,01H,02H,03H,04H,05H,06H
  62.             DB 07H,08H,09H,0AH,0BH,0CH,0DH
  63.             DB 0EH,0FH,11H,12H,13H,14H,15H
  64.             DB 16H,17H,18H,19H,1AH,1BH,1CH
  65.             DB 1DH,1EH,1FH,22H,23H,24H,25H
  66.             DB 26H,27H,28H,29H,2AH,2BH,2CH
  67.             DB 2DH,2EH,2FH,33H,34H,35H,36H
  68.             DB 37H,38H,39H,3AH,3BH,3CH,3DH
  69.             DB 3EH,3FH,44H,45H,46H,47H,48H
  70.             DB 49H,4AH,4BH,4CH,4DH,4EH,4FH
  71.             DB 55H,56H,57H,58H,59H,5AH,5BH
  72.             DB 5CH,5DH,5EH,5FH,66H,67H,68H
  73.             DB 69H,6AH,6BH,6CH,6DH,6EH,6FH
  74.             DB 77H,78H,79H,7AH,7BH,7CH,7DH
  75.             DB 7EH,7FH,88H,89H,8AH,8BH,8CH
  76.             DB 8DH,8EH,8FH,99H,9AH,9BH,9CH
  77.             DB 9DH,9EH,9FH,0AAH,0ABH,0ACH
  78.             DB 0ADH,0AEH,0AFH,0BBH,0BCH
  79.             DB 0BDH,0BEH,0BFH,0CCH,0CDH
  80.             DB 0CEH,0CFH,0DDH,0DEH,0DFH
  81.             DB 0EEH,0EFH,0FFH
  82.  
  83. ; Neuer Interrupt-Handler 10H 
  84.  
  85. KEYWORD DB "136COLOR"
  86.  
  87. NEWINT_10H PROC FAR
  88.       OR AH,AH
  89.       ;Funktion "Bildschirmmodus setzen" ?
  90.       JNZ TEST1
  91.       ;wenn nicht => nächste Fkt. testen
  92.       CALL SET_KOOR
  93.       ;prüfen, ob einer der vier Modi und
  94.       ;evtl. max. Bildschirmausdeh. setzen
  95.       JMP SHORT OLDINT_CALL
  96.       ;Sprung ins BIOS, um Modus zu setzen
  97. TEST1: CMP AH,0FFH
  98.       ;Funktion "Prog. installiert" ?
  99.       JNZ TEST2
  100.       ;wenn nicht => nächste Fkt. testen
  101.       MOV AL,0AAH
  102.       ;anzeigen, daß Programm installiert
  103.       IRET
  104.       ;zurück zum Aufrufer
  105. TEST2: CMP AH,0FEH
  106.       ;Funktion "Aktivieren/Deaktivieren"?
  107.       JNZ TEST3
  108.       ;wenn nicht => nächste Fkt. testen
  109.       AND AL,01H
  110.       ;nur 0 und 1 erlaubt
  111.       MOV CS:ACTIVE_FLAG,AL
  112.       ;Aktivierungs-Flag setzen
  113.       IRET
  114.       ;zurück zum Aufrufer
  115. TEST3: CMP CS:MODE_FLAG,00H
  116.       ;aktueller Modus unbekannt ?
  117.       JNZ FKT_OK
  118.       ;wenn nicht => aufzurufene Funktion
  119.       ;ausführen
  120. OLDINT_CALL: JMP DWORD PTR CS:OLDINT_10H
  121.       ;Sprung zur ursprüngl. BIOS-Funktion
  122. FKT_OK: CMP CS:ACTIVE_FLAG,00H
  123.       ;Erweiterung nicht aktiviert ?
  124.       JZ OLDINT_CALL
  125.       ;dann Sprung ins BIOS
  126.       CMP AH,0CH
  127.       ;Funktion "Punkt setzen" ?
  128.       JZ FKT_CALL
  129.       ;dann Ok.
  130.       CMP AH,0DH
  131.       ;Funktion "Punkt lesen" ?
  132.       JNZ OLDINT_CALL
  133.       ;wenn nicht => Sprung ins BIOS
  134. FKT_CALL: MOV CS:OLDSS,SS
  135.       ;Stacksegment speichern
  136.       MOV CS:OLDSP,SP
  137.       ;Stackpointer speichern
  138.       PUSH CS
  139.       POP SS
  140.       ;Stacksegment=Codesegment
  141.       MOV SP,0100H
  142.       PUSH BP
  143.       PUSH AX
  144.       MOV BP,SP
  145.       ;Basepointer zeigt auf AX
  146.       PUSH DX
  147.       PUSH DS
  148.       ;Datensegment sichern
  149.       PUSH ES
  150.       ;Extrasegment sichern
  151.       PUSH CS
  152.       POP DS
  153.       ;Datensegment=Codesegment
  154.       PUSH AX
  155.       PUSH DX
  156.       ;Register AX und DX auf Stapel
  157.       MOV DX,03CEH
  158.       MOV AX,0205H
  159.       OUT DX,AX
  160.       ;Grafikmodi für EGA-Karte setzen:
  161.       ;Lesemodus 0 / Schreibmodus 2
  162.       AND BH,03H
  163.       ;Seitenangabe zwischen 0 und 3
  164.       MOV SCR_OFFSET,0000H
  165.       ;Offset für Zugriff auf Seiten=0000H
  166.       OR BH,BH
  167.       ;Seitennummer = 0 ?
  168.       JZ SCROFF_OK
  169.       ;dann ist das Offset in Ordnung
  170.       CMP CRT_MODE,0EH
  171.       ;Modus 640x200 ?
  172.       JNZ SCROFF_640x350
  173.       ;nein ? => Seitenoffset für Modus
  174.       ;640x350 setzen
  175.       MOV AL,BH
  176.       XOR AH,AH
  177.       ;Seitennummer nach AX
  178.       MOV DX,4000H
  179.       ;Länge einer Seite nach DX
  180.       MUL DX
  181.       ;SCR_OFFSET berechnen
  182.       MOV SCR_OFFSET,AX
  183.       ;und speichern
  184.       JMP SHORT SCROFF_OK
  185.       ;Sprung zur Ausführungssequenz
  186. SCROFF_640x350: MOV SCR_OFFSET,8000H
  187.       ;Offset für Seite 1 setzen
  188. SCROFF_OK: MOV AX,0A000H
  189.       MOV ES,AX
  190.       ;Extrasegment als Videosegment inst.
  191.       POP DX
  192.       POP AX
  193.       ;Register DX und AX restaurieren
  194.       CMP AH,0CH
  195.       ;Funktion "Punkt setzen" ?
  196.       JNZ CHK_FKT1
  197.       ;wenn nicht => nächste Fkt. prüfen
  198.       CALL PUT_PIXEL
  199.       ;sonst Punkt setzen
  200.       JMP SHORT EXIT_NEWINT_10H
  201.       ;und zurück zum Aufrufer
  202. CHK_FKT1: CALL GET_PIXEL
  203.       ;Funktion "Punkt lesen"
  204. EXIT_NEWINT_10H: MOV DX,03CEH
  205.       MOV AX,0005H
  206.       OUT DX,AX
  207.       ;alten Lese-/Schreibmodus setzen
  208.       MOV AX,0FF08H
  209.       OUT DX,AX
  210.       ;Bit Mask Register installieren
  211.       POP ES
  212.       POP DS
  213.       POP DX
  214.       POP AX
  215.       POP BP
  216.       ;alle Register vom Stapel
  217.       MOV SS,CS:OLDSS
  218.       ;altes Stacksegment
  219.       MOV SP,CS:OLDSP
  220.       ;und alten Stackpointer installieren
  221.       IRET
  222.       ;zurück zum Aufrufer
  223. NEWINT_10H ENDP
  224.  
  225. ;Funktion: maximale Bildschirmausdehnung
  226. ;          für spezifischen Bildschirm-
  227. ;          modus für Grafikroutinen setzen
  228. ;Eingabe : AL = Bildschirmmodus
  229. ;Ausgabe : [MAXX], [MAXY] und [GETPOS_ADR]
  230. ;          erhalten Werte, wenn AL =
  231. ;          0EH,10H,12H oder VMODE_800x600
  232. ;          [MODE_FLAG]=1, wenn einer der
  233. ;          o.g. Modi
  234. ;          [CRT_MODE] = akt. Bildschirmm.
  235.  
  236.  
  237. SET_KOOR PROC NEAR
  238.       PUSH DS
  239.       PUSH CS
  240.       POP DS
  241.       MOV CRT_MODE,AL
  242.       ;akt. Bildschirmmodus speichern
  243.       CMP AL,0EH
  244.       ;Modus 640x200 ?
  245.       JNZ MODE1
  246.       ;wenn nicht => nächsten Modus testen
  247.       MOV MAXX,320
  248.       MOV MAXY,200
  249.       ;max. Bildschirmausdehnung eintragen
  250.       MOV GETPOS_ADR,OFFSET GPOS_320
  251.       ;Adr. der Routine zur Berechnung der
  252.       ;Bildschirmposition eintragen
  253.       JMP SHORT MODE_OK
  254.       ;Modus bestätigen
  255. MODE1: CMP AL,10H
  256.       ;Modus 640x350 ?
  257.       JNZ MODE2
  258.       MOV MAXX,320
  259.       MOV MAXY,350
  260.       MOV GETPOS_ADR,OFFSET GPOS_320
  261.       JMP SHORT MODE_OK
  262. MODE2: CMP AL,12H
  263.       ;Modus 640x480 ?
  264.       JNZ MODE3
  265.       MOV MAXX,320
  266.       MOV MAXY,480
  267.       MOV GETPOS_ADR,OFFSET GPOS_320
  268.       JMP SHORT MODE_OK
  269. MODE3: CMP AL,VMODE_800x600
  270.       ;Modus 800x600 ?
  271.       JNZ EXIT_SET_KOOR
  272.       ;wenn nicht => unbekannter Modus
  273.       MOV MAXX,400
  274.       MOV MAXY,600
  275.       MOV GETPOS_ADR,OFFSET GPOS_400
  276. MODE_OK: MOV MODE_FLAG,01H
  277.       ;"Bekannter Modus" anzeigen
  278.       POP DS
  279.       RET
  280.       ;zurück zum Aufrufer
  281. EXIT_SET_KOOR: MOV MODE_FLAG,00H
  282.       ;"Unbekannter Modus" anzeigen
  283.       MOV ACTIVE_FLAG,00H
  284.       ;erweiterte Funktionen deaktivieren
  285.       POP DS
  286.       RET
  287.       ;und zurück zum Aufrufer
  288. SET_KOOR ENDP
  289.  
  290. ;Funktion: Zu einer Farbnummer gehörenden
  291. ;          Farbwert aus COLTAB auslesen
  292. ;Eingabe : AL = Farbe (0-135)
  293. ;          DX = Y-Position
  294. ;Ausgabe : [COLOR] = linker und rechter
  295. ;          Farbwert
  296.  
  297. GET_COLOR PROC NEAR
  298.       PUSH BX
  299.       MOV BL,AL
  300.       ;Farbnummer nach BL
  301.       XOR BH,BH
  302.       MOV AL,[COLTAB+BX]
  303.       ;Farbwert auslesen
  304.       POP BX
  305.       MOV AH,AL
  306.       ;Farbwert nach AH kopieren
  307.       AND AX,0F00FH
  308.       ;oberen Farbwert in AH, bzw. unteren
  309.       ;Farbwert in AL ausmaskieren
  310.       MOV CL,04H
  311.       SHR AH,CL
  312.       ;oberen Farbwert in unteren vier Bit
  313.       ;schieben
  314.       RCR DX,1
  315.       ;unteres Bit der Y-Position ins
  316.       ;Carry-Flag
  317.       JNC GCOLOR_OK
  318.       ;wenn Y-Position gerade => Farbe Ok.
  319.       XCHG AH,AL
  320.       ;sonst linken und rechten Farbwert
  321.       ;vertauschen
  322. GCOLOR_OK: MOV COLOR,AX
  323.       ;beide Farbwerte abspeichern
  324.       RET
  325.       ;und zurück zum Aufrufer
  326. GET_COLOR ENDP
  327.  
  328. ;Funktion: Schnelles Berechnen der Bild-
  329. ;          adresse zu einem Punkt für die
  330. ;          Modi 320x200, 320x350, 320x480
  331. ;Eingabe : AL = Farbe (0-135)
  332. ;          CX = X-Position
  333. ;          DX = Y-Position
  334. ;Ausgabe : BX = Bildschirmadresse
  335.  
  336. GPOS_320 PROC NEAR
  337.       PUSH AX
  338.       PUSH DX
  339.       PUSH CX
  340.       ;Farbe, X- und Y-Position auf Stapel
  341.       MOV BX,DX
  342.       ;Y-Position nach BX
  343.       MOV CL,06H
  344.       SHL BX,CL
  345.       ;mit 64 multiplizieren
  346.       ADD BX,DX
  347.       ADD BX,DX
  348.       ADD BX,DX
  349.       ADD BX,DX
  350.       ADD BX,DX
  351.       ADD BX,DX
  352.       ADD BX,DX
  353.       ADD BX,DX
  354.       ADD BX,DX
  355.       ADD BX,DX
  356.       ADD BX,DX
  357.       ADD BX,DX
  358.       ADD BX,DX
  359.       ADD BX,DX
  360.       ADD BX,DX
  361.       ADD BX,DX
  362.       ;Y-Position 16x aufaddieren
  363.       ;=> Multiplikation mit 80 !
  364.       POP CX
  365.       PUSH CX
  366.       ;X-Position nach CX holen
  367.       SHR CX,1
  368.       SHR CX,1
  369.       ;durch 4 dividieren
  370.       ADD BX,CX
  371.       ;und zur Bildschirmadr. aufaddieren
  372.       ADD BX,SCR_OFFSET
  373.       ;Screenoffset (für Seiten) aufadd.
  374.       CALL GET_COLOR
  375.       ;Farbwert aus Farbe in AL berechnen
  376.       POP CX
  377.       POP DX
  378.       POP AX
  379.       ;alle Register restaurieren
  380.       RET
  381.       ;und zurück zum Aufrufer
  382. GPOS_320 ENDP
  383.  
  384. ;Funktion: Schnelles Berechnen der Bild-
  385. ;          adresse zu einem Punkt für den
  386. ;          Modus 400x600
  387. ;Eingabe : AL = Farbe (0-135)
  388. ;          CX = X-Position
  389. ;          DX = Y-Position
  390. ;Ausgabe : BX = Bildschirmadresse
  391.  
  392. GPOS_400 PROC NEAR
  393.       PUSH AX
  394.       PUSH DX
  395.       PUSH CX
  396.       ;Farbe, X- und Y-Position auf Stapel
  397.       MOV BX,DX
  398.       ;Y-Position nach BX
  399.       MOV CX,07H
  400.       SHL BX,CL
  401.       ;mit 128 multiplizieren
  402. SUBLOOP: SUB BX,DX
  403.       SUB BX,DX
  404.       SUB BX,DX
  405.       SUB BX,DX
  406.       LOOP SUBLOOP
  407.       ;Y-Position 28x subtrahieren
  408.       ;=> Multiplikation mit 100 !
  409.       POP CX
  410.       PUSH CX
  411.       ;X-Position nach CX holen
  412.       SHR CX,1
  413.       SHR CX,1
  414.       ;durch 4 dividieren
  415.       ADD BX,CX
  416.       ;und zur Bildschirmadr. aufaddieren
  417.       ADD BX,SCR_OFFSET
  418.       ;Screenoffset (für Seiten) aufadd.
  419.       CALL GET_COLOR
  420.       ;Farbwert aus Farbe in AL berechnen
  421.       POP CX
  422.       POP DX
  423.       POP AX
  424.       ;alle Register restaurieren
  425.       RET
  426.       ;und zurück zum Aufrufer
  427. GPOS_400 ENDP
  428.  
  429. ; Neue INT 10H-Funktionen
  430.  
  431. ;Funktion: Routine zum Setzen eines Punk-
  432. ;          tes durch Beschreiben der EGA-
  433. ;          Karte
  434. ;Eingabe : CX = X-Position
  435. ;          DX = Y-Position
  436. ;          AL = Farbnummer (auf Stack)
  437. ;Ausgabe : keine
  438.  
  439. PUT_PIXEL PROC NEAR
  440.       MOV AL,[BP]
  441.       ;Farbnummer holen
  442.       CMP CX,MAXX
  443.       ;X-Position > Bildschirmausdehnung ?
  444.       JAE END_PUTPIX
  445.       ;dann keinen Punkt setzen
  446.       CMP DX,MAXY
  447.       ;Y-Position > Bildschirmausdehnung ?
  448.       JAE END_PUTPIX
  449.       ;dann keinen Punkt setzen
  450.       CMP AL,87H
  451.       ;Farbnummer zu groß ?
  452.       JA END_PUTPIX
  453.       ;dann keinen Punkt setzen
  454.       PUSH AX
  455.       PUSH BX
  456.       PUSH CX
  457.       PUSH DX
  458.       ;Register auf Stapel
  459.       PUSH CX
  460.       ;X-Position auf Stapel
  461.       CALL GETPOS_ADR
  462.       ;Bildschirmadresse berechnen
  463.       MOV AL,ES:[BX]
  464.       ;Latch Register laden
  465.       MOV DX,03CEH
  466.       ;Graphics Controller Adresse nach DX
  467.       POP CX
  468.       ;X-Position nach CX
  469.       SHL CX,1
  470.       ;mit 2 multiplizieren
  471.       AND CL,07H
  472.       ;Bits 0-7 ausmaskieren
  473.       PUSH CX
  474.       ;Maske auf Stapel
  475.       MOV AX,8008H
  476.       ;Defaultmaske und Nr. des Bit Mask
  477.       ;Registers (08H) nach AX
  478.       SHR AH,CL
  479.       ;Maske für linken Punkt berechnen
  480.       OUT DX,AX
  481.       ;und Bit Mask Register beschreiben
  482.       MOV AX,COLOR
  483.       ;Farben nach AX holen
  484.       MOV ES:[BX],AH
  485.       ;Farbe für linken Punkt setzen
  486.       POP CX
  487.       ;Maske vom Stapel holen
  488.       INC CL
  489.       ;erhöhen => Maske für rechten Punkt
  490.       PUSH AX
  491.       ;Farben auf Stapel
  492.       MOV AL,ES:[BX]
  493.       ;Latches laden
  494.       MOV AX,8008H
  495.       ;Defaultmask./Bit Mask Reg. nach AX
  496.       SHR AH,CL
  497.       ;Maske für rechten Punkt berechnen
  498.       OUT DX,AX
  499.       ;und Bit Mask Register beschreiben
  500.       POP AX
  501.       ;Farben holen
  502.       MOV ES:[BX],AL
  503.       ;Farbe für rechten Punkt setzen
  504.       POP DX
  505.       POP CX
  506.       POP BX
  507.       POP AX
  508.       ;alle Register restaurieren
  509. END_PUTPIX: RET
  510.       ;und zurück zum Aufrufer
  511. PUT_PIXEL ENDP
  512.  
  513. ;Funktion: Routine zum Lesen eines Punktes
  514. ;          durch Beschreiben der EGA-Karte
  515. ;Eingabe : CX = X-Position
  516. ;          DX = Y-Position
  517. ;Ausgabe : AL = Farbe (0-135)
  518. ;          AL = 0FFH bedeutet Farbe nicht
  519. ;               erkannt
  520. ;Bemerkung: Ausgabe geschieht über Stack
  521.  
  522. GET_PIXEL PROC NEAR
  523.       CMP CX,MAXX
  524.       ;X-Position > Bildschirmausdehnung ?
  525.       JAE END_GETPIX
  526.       ;dann keinen Punkt lesen
  527.       CMP DX,MAXY
  528.       ;Y-Position > Bildschirmausdehnung ?
  529.       JAE END_GETPIX
  530.       ;dann keinen Punkt lesen
  531.       PUSH BX
  532.       PUSH CX
  533.       PUSH DX
  534.       PUSH SI
  535.       PUSH DI
  536.       ;Register auf Stapel
  537.       PUSH DX
  538.       ;Y-Position auf Stapel
  539.       PUSH CX
  540.       ;X-Position auf Stapel
  541.       CALL GETPOS_ADR
  542.       ;Bildschirmadresse berechnen
  543.       POP CX
  544.       ;X-Position nach CX
  545.       SHL CX,1
  546.       ;mit 2 multiplizieren
  547.       AND CL,07H
  548.       ;Bits 0-7 ausmaskieren
  549.       INC CL
  550.       ;erhöhen, damit Bitnummern 1-8
  551.       MOV DX,03CEH
  552.       ;Graphics Controller Adresse nach DX
  553.       MOV AL,04H
  554.       OUT DX,AL
  555.       ;Read Map Select Register wählen
  556.       INC DX
  557.       ;erhöhen, damit DX auf Datenregister
  558.       ;zeigt
  559.       MOV AL,03H
  560.       ;Planenummer nach AL (0-3)
  561.       MOV SI,BX
  562.       ;Bildschirmadresse nach SI
  563.       XOR BX,BX
  564.       ;linker und rechter Farbwert = 0
  565. TLOOP: OUT DX,AL
  566.       ;Plane selektieren
  567.       MOV AH,ES:[SI]
  568.       ;ein Byte aus Bildschirmspei. lesen
  569.       SHL AH,CL
  570.       ;Wert d. linken Punktes ins Carry
  571.       RCL BH,1
  572.       ;und nach BH überführen
  573.       SHL AH,1
  574.       ;Wert d. rechten Punktes ins Carry
  575.       RCL BL,1
  576.       ;und nach BL überführen
  577.       DEC AL
  578.       ;Planenummer erniedrigen
  579.       JNS TLOOP
  580.       ;Planes 3-0 bearbeiten
  581.       POP DX
  582.       ;Y-Position nach DX
  583.       RCR DX,1
  584.       ;Y-Position gerade ?
  585.       JNC TEST_OK
  586.       ;dann Farbwerte Ok.
  587.       XCHG BH,BL
  588.       ;sonst linken und rechten Farbwert
  589.       ;vertauschen
  590. TEST_OK: MOV CL,04H
  591.       SHL BH,CL
  592.       ;linken Farbwert ins obere Nibble
  593.       MOV AL,BL
  594.       OR AL,BH
  595.       ;beide Farbwerte nach AL schreiben
  596.       MOV DI,OFFSET COLTAB
  597.       ;Adresse der Farbtabelle nach DI
  598.       PUSH ES
  599.       PUSH DS
  600.       POP ES
  601.       MOV CX,136
  602.       ;136 Farben möglich
  603.       XOR AH,AH
  604.       ;Zähler auf Null setzen
  605. TLOOP1: SCASB
  606.       ;Farbwerte in AL mit Tab. vergleich.
  607.       JZ END_TLOOP1
  608.       ;wenn Farbwert gefunden => Ok.
  609.       INC AH
  610.       ;sonst Zähler erhöhen
  611.       LOOP TLOOP1
  612.       ;alle Farben vergleichen
  613.       MOV AH,0FFH
  614.       ;Wert 0FFH bedeutet Farbe nicht gef.
  615. END_TLOOP1: MOV AL,AH
  616.       ;Farbnummer nach AL
  617.       MOV [BP],AL
  618.       ;und auf Stapel
  619.       POP ES
  620.       POP DI
  621.       POP SI
  622.       POP DX
  623.       POP CX
  624.       POP BX
  625.       ;alle Register restaurieren
  626.       RET
  627.       ;zurück zum Aufrufer
  628. END_GETPIX: MOV BYTE PTR [BP],00H
  629.       ;wenn X- bzw. Y-Position außerhalb
  630.       ;des Bildschirms => Farbe 0 zurückg.
  631.       RET
  632.       ;zurück zum Aufrufer
  633. GET_PIXEL ENDP
  634.  
  635. ; Installierung
  636.  
  637. INIT: PUSH CS
  638.       POP DS
  639.       MOV AX,3510H
  640.       INT 21H
  641.       ;Interrupt-Vektor 10H lesen
  642.       MOV DI,BX
  643.       ;Offsetadresse nach DI
  644.       SUB DI,08H
  645.       ;Zeiger auf evtl. Erkennungsstring
  646.       MOV SI,OFFSET KEYWORD
  647.       ;Adr. des Erkennungsstrings nach SI
  648.       MOV CX,08H
  649.       ;Erkennungsstring ist 8 Zeichen lang
  650.       REPZ CMPSB
  651.       ;vergleichen
  652.       JZ DELETE_TSR
  653.       ;wenn Programm vorhanden => aus
  654.       ;Speicher entfernen
  655.       MOV OLDINT_10H,BX
  656.       MOV OLDINT_10H+2,ES
  657.       ;sonst alte Interrupt-Adresse spei.
  658.       MOV AH,0FH
  659.       INT 10H
  660.       ;akt. Bildschirmmodus auslesen
  661.       CALL SET_KOOR
  662.       ;evtl. max. Bildschirmausdeh. setzen
  663.       MOV AX,2510H
  664.       MOV DX,OFFSET NEWINT_10H
  665.       INT 21H
  666.       ;neue Interruptadresse setzen
  667.       MOV AX,CS:[002CH]
  668.       ;Segmentadr. des Envir.-Ber. holen
  669.       MOV ENVSEG,AX
  670.       ;und speichern (für evtl. Freigabe)
  671.       MOV AH,09H
  672.       MOV DX,OFFSET MSG1
  673.       INT 21H
  674.       ;Meldung ausgeben
  675.       MOV AX,3100H
  676.       MOV DX,OFFSET INIT
  677.       MOV CL,04H
  678.       SHR DX,CL
  679.       INC DX
  680.       ;Anzahl Paragraphen berechnen
  681.       INT 21H
  682.       ;Programm resident machen und zurück
  683.       ;zur DOS-Ebene
  684. DELETE_TSR: PUSH ES
  685.       ;Segmentadresse des residenten Pro-
  686.       ;gramms auf Stapel legen
  687.       MOV ES,ES:ENVSEG
  688.       ;Segmentadr. des Envir.-Ber. holen
  689.       MOV AH,49H
  690.       INT 21H
  691.       ;Bereich freigeben
  692.       JC ERR_DELETE_TSR
  693.       ;erfolglos => entfernen nicht mögl.
  694.       POP ES
  695.       ;Segmentadresse des res. Pro. holen
  696.       MOV AH,49H
  697.       INT 21H
  698.       ;Bereich freigeben
  699.       JC ERR_DELETE_TSR1
  700.       ;erfolglos => nicht entfernen
  701.       PUSH DS
  702.       ;akt. Datensegment sichern
  703.       MOV AX,2510H
  704.       LDS DX,DWORD PTR ES:OLDINT_10H
  705.       ;Adr. d. ursprünglichen Int. holen
  706.       INT 21H
  707.       ;und einsetzen
  708.       POP DS
  709.       ;Datensegment restaurieren
  710.       MOV AH,09H
  711.       MOV DX,OFFSET MSG2
  712.       INT 21H
  713.       ;Meldung ausgeben
  714.       MOV AX,4C01H
  715.       INT 21H
  716.       ;und zurück zur DOS-Ebene
  717.       ;(ERRORLEVEL=1)
  718. ERR_DELETE_TSR: POP ES
  719.       ;Segmentadr. d. res. Pro. holen
  720. ERR_DELETE_TSR1: MOV AH,09H
  721.       MOV DX,OFFSET MSG3
  722.       INT 21H
  723.       ;Meldung ausgeben
  724.       MOV AX,4C02H
  725.       INT 21H
  726.       ;und zurück zur DOS-Ebene
  727.       ;(ERRORLEVEL=2)
  728.  
  729. CODE  ENDS
  730.       END START
  731.