home *** CD-ROM | disk | FTP | other *** search
/ Informática Multimedia Fácil 56 / INF1297.iso / SOFCAS / EDUCA / EVSIM11.ZIP / EV-SYS.ASM < prev    next >
Assembly Source File  |  1996-04-27  |  78KB  |  1,798 lines

  1.  
  2. ;┌───────────────────────────────────────────────────────────────────┐
  3. ;│                                                                   │
  4. ;│                 RUTINAS EN ENSAMBLADOR PARA EV                    │
  5. ;│                                                                   │
  6. ;│           Incluir en un fichero de proyecto con EV.C              │
  7. ;│       El modelo de memoria debe ser necesariamente LARGE          │
  8. ;│                                                                   │
  9. ;└───────────────────────────────────────────────────────────────────┘
  10.  
  11.                PUBLIC    _VGAModeX     ; inicializar modo X
  12.                PUBLIC    _setpix       ; trazar puntos
  13.                PUBLIC    _set16pix     ; trazar bloques de 16 puntos
  14.                PUBLIC    _set4pix      ; trazar bloques de 4 puntos
  15.                PUBLIC    _getpix       ; obtener color de un punto
  16.                PUBLIC    _recta        ; trazado de una recta
  17.                PUBLIC    _lineahoriz   ; trazar línea horizontal
  18.                PUBLIC    _showpage     ; elegir página a mostrar
  19.                PUBLIC    _setpage      ; página para setpix y getpix
  20.                PUBLIC    _FuenteInfo   ; puntero juego caracteres 8*16
  21.                PUBLIC    _segvideo     ; segmento de vídeo activo
  22.                PUBLIC    _Xprcar       ; escribir carácter en modo X
  23.                PUBLIC    _prcar        ; escribir carácter en 16 colores
  24.                PUBLIC    _PintaBitMap  ; imprimir mapa de bits
  25.                PUBLIC    _MoveVram     ; copiar un área de vídeo
  26.                PUBLIC    _MoveMem      ; copiar una zona de memoria a otra
  27.                PUBLIC    _prbios       ; imprimir con la BIOS
  28.                PUBLIC    _set80x30     ; modo texto VGA 80x30 (font 8x16)
  29.                PUBLIC    _ResetVideo   ; Reset del modo de vídeo
  30.                PUBLIC    _NuevaInt24   ; nuevo gestor errores críticos
  31.                PUBLIC    _NoHayTecla   ; indicar si no hay tecla en el buffer
  32.  
  33.  
  34. _TEXT          SEGMENT WORD PUBLIC 'CODE'
  35.                ASSUME  CS:_TEXT, DS:_DATA
  36.  
  37. ; ------------ Establecer cualquier modo X no soportado por la BIOS.
  38. ;              Declaración:  void VGAModeX (int hvertical);
  39. ;
  40. ;                    Modo X      Valor de hvertical
  41. ;                 -----------    ------------------
  42. ;                 320x200x256           200
  43. ;                 320x240x256           240
  44. ;                 320x400x256           400
  45. ;                 320x480x256           480
  46. ;
  47. ;              Basado en una rutina original de:
  48. ;                     Pedro Gimeno Fortea (Fido 2:346/207.62)
  49.  
  50. hvertical      EQU   WORD PTR [BP+6]   ; para modelo LARGE
  51.  
  52. _VGAModeX      PROC  FAR
  53.                PUSH  BP
  54.                MOV   BP,SP
  55.                PUSH  SI
  56.                PUSH  DI
  57.                PUSH  DS
  58.                MOV   AX,40h
  59.                MOV   DS,AX
  60.                MOV   AL,DS:[10h]
  61.                AND   AL,0CFh      ; por si estamos en modo 7...
  62.                OR    AL,20h
  63.                MOV   DS:[10h],AL  ; ...forzar modo de color
  64.                POP   DS
  65.                MOV   AX,12h       ; Modo estándar 640x480x16 (480/240)
  66.                CMP   hvertical,480
  67.                JE    vini_ok
  68.                CMP   hvertical,240
  69.                JE    vini_ok
  70.                MOV   AX,0Eh       ; Modo estándar 640x200x16 (400/200)
  71. vini_ok:       INT   10h
  72.                MOV   DX,3CEh      ; Graphics Controller
  73.                MOV   AX,4005h     ; bit de 256c en Mode Register
  74.                CLI
  75.                OUT   DX,AX
  76.                MOV   DX,3DAh      ; Asegurar que el Attribute Controller
  77.                IN    AL,DX        ; está en modo Registro, no en modo Dato
  78.                MOV   DX,3C0h      ; Attribute Controller
  79.                MOV   AL,0         ; desactivar acceso de VGA; reg. paleta 0
  80.                MOV   CX,16        ; Programaremos 16 registros en total
  81. SetPalReg:     JMP   SHORT $+2
  82.                JMP   SHORT $+2
  83.                OUT   DX,AL        ; Meter en el registro N-ésimo...
  84.                JMP   SHORT $+2
  85.                JMP   SHORT $+2
  86.                OUT   DX,AL        ; ... el valor N
  87.                INC   AL           ; Siguiente registro / valor
  88.                LOOP  SetPalReg
  89.                MOV   AL,30h       ; Registro 10h (de modo), bit de acceso
  90.                OUT   DX,AL        ; de VGA activado
  91.                MOV   AL,41h       ; Activar el modo de 256 colores
  92.                OUT   DX,AL
  93.                CMP   hvertical,200
  94.                JE    dup_ok       ; ya se partía con Scanline duplicado
  95.                CMP   hvertical,480
  96.                JE    dup_ok       ; ya se partía con Scanline sin duplicar
  97.                MOV   DX,3D4h      ; CRT controller
  98.                MOV   AL,09h
  99.                OUT   DX,AL
  100.                INC   DX
  101.                IN    AL,DX
  102.                AND   AL,7Fh       ; desactivar duplicación (400)
  103.                CMP   hvertical,400
  104.                JE    set_dup
  105.                OR    AL,80h       ; Duplicar tamaño de Scanline (240)
  106. set_dup:       OUT   DX,AL
  107. dup_ok:        STI
  108.                PUSH  DS
  109.                MOV   AX,40h
  110.                MOV   DS,AX
  111.                MOV   BYTE PTR DS:[49h],13h  ; simular modo 13h
  112.                POP   DS
  113.                POP   DI
  114.                POP   SI
  115.                POP   BP
  116.                RET
  117. _VGAModeX      ENDP
  118.  
  119.  
  120. ; ------------ Pintar un punto en modo X.
  121. ;              Declaración: void setpix (int x, int y, int color);
  122.  
  123. x0             EQU   [BP+6]            ; para modelo LARGE
  124. y0             EQU   [BP+8]
  125. color          EQU   [BP+10]
  126.  
  127. _setpix        PROC  FAR
  128.                PUSH  BP
  129.                MOV   BP,SP
  130.                PUSH  DS
  131.                PUSH  DI
  132.                MOV   AX,320/4          ; calcular offset en VRAM
  133.                MUL   WORD PTR y0
  134.                MOV   CX,x0
  135.                MOV   DI,CX
  136.                SHR   DI,1
  137.                SHR   DI,1
  138.                ADD   DI,AX             ; offset en DI
  139.                AND   CL,3              ; calcular máscara para el
  140.                MOV   AH,1              ; mapa a direccionar en AH
  141.                SHL   AH,CL
  142.                MOV   AL,2              ; a AL el número de registro
  143.                MOV   DX,3C4h
  144.                OUT   DX,AX             ; cargar registro de máscara
  145.                MOV   AL,color
  146.                MOV   DS,_segvideo      ; DS -> VRAM
  147.                MOV   [DI],AL           ; trazar punto
  148.                POP   DI
  149.                POP   DS
  150.                POP   BP
  151.                RET
  152. _setpix        ENDP
  153.  
  154. ; ------------ Pintar un cuadrado de 4x4 en modo X (coords. multiplo de 4).
  155. ;              Declaración: void set16pix (int x, int y, int color);
  156.  
  157. x16            EQU   [BP+6]            ; para modelo LARGE
  158. y16            EQU   [BP+8]
  159. color16        EQU   [BP+10]
  160.  
  161. _set16pix      PROC  FAR
  162.                PUSH  BP
  163.                MOV   BP,SP
  164.                PUSH  DS
  165.                PUSH  DI
  166.                MOV   AX,320/4          ; calcular offset en VRAM
  167.                MUL   WORD PTR y16
  168.                MOV   DI,x16
  169.                SHR   DI,1
  170.                SHR   DI,1
  171.                ADD   DI,AX             ; offset en DI
  172.                MOV   AX,1111b*256+2    ; direccionar 4 mapas en AH
  173.                MOV   DX,3C4h           ; (AL el número de registro)
  174.                OUT   DX,AX             ; cargar registro de máscara
  175.                MOV   AL,color16
  176.                MOV   DS,_segvideo      ; DS -> VRAM
  177.                MOV   [DI],AL           ; trazar puntos
  178.                MOV   [DI+80],AL        ; trazar puntos
  179.                ADD   DI,160
  180.                MOV   [DI],AL           ; trazar puntos
  181.                MOV   [DI+80],AL        ; trazar puntos
  182.                POP   DI
  183.                POP   DS
  184.                POP   BP
  185.                RET
  186. _set16pix      ENDP
  187.  
  188. ; ------------ Pintar un cuadrado de 2x2 en modo X (coords. multiplo de 2).
  189. ;              Declaración: void set4pix (int x, int y, int color);
  190.  
  191. x4             EQU   [BP+6]            ; para modelo LARGE
  192. y4             EQU   [BP+8]
  193. color4         EQU   [BP+10]
  194.  
  195. _set4pix       PROC  FAR
  196.                PUSH  BP
  197.                MOV   BP,SP
  198.                PUSH  DS
  199.                PUSH  DI
  200.                MOV   AX,320/4          ; calcular offset en VRAM
  201.                MUL   WORD PTR y4
  202.                MOV   CX,x4
  203.                MOV   DI,CX
  204.                SHR   DI,1
  205.                SHR   DI,1
  206.                ADD   DI,AX             ; offset en DI
  207.                TEST  CL,2
  208.                MOV   AX,0011b*256+2    ; direccionar 2 mapas en AH
  209.                JZ    m4pix_ok
  210.                MOV   AH,1100b
  211. m4pix_ok:      MOV   DX,3C4h           ; (AL el número de registro)
  212.                OUT   DX,AX             ; cargar registro de máscara
  213.                MOV   AL,color4
  214.                MOV   DS,_segvideo      ; DS -> VRAM
  215.                MOV   [DI],AL           ; trazar puntos
  216.                MOV   [DI+80],AL        ; trazar puntos
  217.                POP   DI
  218.                POP   DS
  219.                POP   BP
  220.                RET
  221. _set4pix       ENDP
  222.  
  223. ; ------------ Obtener el color de un punto en modo X.
  224. ;              (Se suponen 80 columnas en el eje X).
  225. ;              Declaración:
  226. ;                 int lineahoriz (int x, int y, int largo, int color);
  227.  
  228. x_h            EQU   [BP+6]            ; para modelo LARGE
  229. y_h            EQU   [BP+8]
  230. l_h            EQU   [BP+10]
  231. c_h            EQU   [BP+12]
  232.  
  233. _lineahoriz    PROC  FAR
  234.                PUSH  BP
  235.                MOV   BP,SP
  236.                PUSH  ES
  237.                PUSH  DI
  238.                MOV   AX,320/4          ; calcular offset en VRAM
  239.                MUL   WORD PTR y_h
  240.                MOV   DI,x_h
  241.                ADD   DI,AX             ; offset en DI
  242.                MOV   AH,00001111b      ; direccionar 4 mapas en AH
  243.                MOV   AL,2              ; a AL el número de registro
  244.                MOV   DX,3C4h
  245.                OUT   DX,AX             ; cargar registro de máscara
  246.                MOV   CX,l_h
  247.                MOV   AL,c_h
  248.                MOV   ES,_segvideo      ; DS -> VRAM
  249.                REP   STOSB             ; trazar línea
  250.                POP   DI
  251.                POP   ES
  252.                POP   BP
  253.                RET
  254. _lineahoriz    ENDP
  255.  
  256. ; ------------ Trazar línea horizontal en modo X.
  257. ;              Declaración: int getpix (int x, int y);
  258.  
  259. x1             EQU   [BP+6]            ; para modelo LARGE
  260. y1             EQU   [BP+8]
  261.  
  262. _getpix        PROC  FAR
  263.                PUSH  BP
  264.                MOV   BP,SP
  265.                PUSH  DS
  266.                PUSH  SI
  267.                MOV   AX,320/4          ; calcular offset en VRAM
  268.                MUL   WORD PTR y1
  269.                MOV   SI,x1
  270.                MOV   CX,SI
  271.                SHR   SI,1
  272.                SHR   SI,1
  273.                ADD   SI,AX
  274.  
  275.                AND   CL,3              ; calcular máscara para el
  276.                MOV   AH,CL             ; mapa a direccionar en AH
  277.                MOV   AL,4
  278.                MOV   DX,3CEh
  279.                OUT   DX,AX             ; cargar registro Read-Map
  280.  
  281.                MOV   DS,_segvideo      ; DS -> VRAM
  282.                MOV   AL,[SI]           ; obtener color del punto
  283.                MOV   AH,0              ; (int)
  284.                POP   SI
  285.                POP   DS
  286.                POP   BP
  287.                RET
  288. _getpix        ENDP
  289.  
  290. ; ------------ Trazar una recta a través del algoritmo de Bresenham.
  291. ;              Declaración: void recta (int x1, int y1, x2, y2, color, modo);
  292. ;              Si modo es 0, utiliza la BIOS; si no, asume modo de 16 colores.
  293.  
  294. rx1            EQU   [BP+6]            ; para modelo LARGE
  295. ry1            EQU   [BP+8]
  296. rx2            EQU   [BP+10]
  297. ry2            EQU   [BP+12]
  298. rcolor         EQU   [BP+14]
  299. rmodo          EQU   [BP+16]
  300.  
  301. _recta         PROC  FAR
  302.                PUSH  BP
  303.                MOV   BP,SP
  304.                PUSH  SI
  305.                PUSH  DI
  306.                CMP   WORD PTR rmodo,0
  307.                JE    rm_ok1
  308.                MOV   DX,3CEh
  309.                MOV   AX,205h           ; modo read 0 y write 2
  310.                OUT   DX,AX
  311. rm_ok1:        MOV   CX,rx1
  312.                MOV   DX,ry1
  313.                MOV   SI,rx2
  314.                MOV   DI,ry2            ; de (CX,DX) a (SI,DI)
  315.                PUSH  DS
  316.                MOV   AL,BYTE PTR rcolor
  317.                MOV   AH,BYTE PTR rmodo
  318.                MOV   DS,AX             ; pocos registros tiene el 8086 :-)
  319.                PUSH  BP
  320.                CMP   CX,SI
  321.                JNE   tst_ok
  322.                CMP   DX,DI
  323.                JNE   tst_ok
  324.                MOV   AX,DS
  325.                CALL  rpunto            ; línea de un solo punto
  326.                JMP   fin
  327. tst_ok:        MOV   AX,SI
  328.                SUB   AX,CX             ; AX = X2-X1
  329.                JNC   absx2x1
  330.                NEG   AX
  331.                XCHG  CX,SI
  332.                XCHG  DX,DI
  333. absx2x1:       MOV   BX,DI             ; AX = ABS(X2-X1) = «dx»
  334.                SUB   BX,DX
  335.                MOV   BP,1              ; BP = 1  = «yincr» si  Y2>Y1
  336.                JNC   absy2y1
  337.                NEG   BP                ; BP = -1  = «yincr» si  Y2<=Y1
  338.                NEG   BX
  339. absy2y1:       CMP   AX,BX             ; BX = ABS(Y2-Y1) = «dy»
  340.                PUSHF
  341.                JA    noswap            ; ABS(pendiente) menor de 1
  342.                XCHG  AX,BX
  343. noswap:        SHL   BX,1              ; BX = «dy» * 2
  344.                MOV   SI,BX
  345.                SUB   SI,AX             ; SI = «dy» * 2 - «dx» = «d»
  346.                MOV   DI,BX
  347.                SUB   DI,AX
  348.                SUB   DI,AX             ; DI = «dy»*2-«dx»*2 = «incr2»
  349.                POPF
  350.                JBE   penmay1           ; pendiente mayor de 1
  351. penmen1:       PUSH  AX
  352.                MOV   AX,DS
  353.                CALL  rpunto            ; en (CX, DX) = («x», «y»)
  354.                POP   AX
  355.                INC   CX                ; «x»++
  356.                AND   SI,SI             ; (SI>0) ?   ->  «d» > 0 ?
  357.                JS    noincy
  358.                ADD   SI,DI             ; «d» > 0 : «d» = «d» + «incr2»
  359.                ADD   DX,BP             ; «y» = «y» + «yincr»
  360.                DEC   AX                ; «dx»--
  361.                JNZ   penmen1
  362.                JMP   fin
  363. noincy:        ADD   SI,BX             ; «d» < 0 : «d» = «d» + «incr1»
  364.                DEC   AX
  365.                JNZ   penmen1
  366.                JMP   fin
  367. penmay1:       PUSH  AX
  368.                MOV   AX,DS
  369.                CALL  rpunto            ; en (CX, DX) = («x», «y»)
  370.                POP   AX
  371.                ADD   DX,BP             ; «y» = «y» + «yincr»
  372.                AND   SI,SI             ; (SI>0) ?   ->  «d» > 0 ?
  373.                JS    noincx
  374.                ADD   SI,DI             ; «d» > 0 : «d» = «d» + «incr2»
  375.                INC   CX                ; «x»++
  376.                DEC   AX                ; «dx»--
  377.                JNZ   penmay1
  378.                JMP   fin
  379. noincx:        ADD   SI,BX             ; «d» = «d» + «incr1»
  380.                DEC   AX                ; «dx»--
  381.                JNZ   penmay1
  382. fin:           POP   BP
  383.                POP   DS                ;-)
  384.                CMP   WORD PTR rmodo,0
  385.                JE    rm_ok2
  386.                MOV   DX,3CEh
  387.                MOV   AX,5
  388.                OUT   DX,AX             ; modo read 0 y write 0 de la BIOS
  389.                MOV   AX,0FF08h
  390.                OUT   DX,AX             ; registro máscara de bit a 0xFF
  391. rm_ok2:        POP   DI
  392.                POP   SI
  393.                POP   BP
  394.                RET
  395. _recta         ENDP
  396.  
  397. rpunto         PROC
  398.                AND   AH,AH
  399.                JZ    rpuntobios
  400.                PUSH  BX
  401.                PUSH  CX
  402.                PUSH  DX
  403.                PUSH  DS
  404.                PUSH  AX
  405.                MOV   AX,80
  406.                MUL   DX
  407.                MOV   BX,CX
  408.                MOV   DX,CX
  409.                MOV   CL,3
  410.                SHR   BX,CL
  411.                ADD   BX,AX
  412.                MOV   AX,0A000h
  413.                MOV   DS,AX             ; DS:BX -> VRAM
  414.                AND   DL,00000111b
  415.                MOV   CL,DL
  416.                MOV   DX,3CEh
  417.                MOV   AH,10000000b
  418.                SHR   AH,CL
  419.                MOV   AL,8
  420.                OUT   DX,AX             ; actualizar registro de máscara
  421.                POP   AX
  422.                MOV   AH,[BX]           ; cargar latches
  423.                MOV   [BX],AL           ; trazar punto
  424.                POP   DS
  425.                POP   DX
  426.                POP   CX
  427.                POP   BX
  428.                RET
  429. rpuntobios:    PUSH  BX               ; preservar registros (salvo AX)
  430.                PUSH  CX
  431.                PUSH  DX
  432.                PUSH  BP
  433.                PUSH  SI
  434.                PUSH  DI
  435.                MOV   AH,0Ch            ; trazar punto usando BIOS
  436.                XOR   BX,BX
  437.                INT   10h
  438.                POP   DI
  439.                POP   SI
  440.                POP   BP
  441.                POP   DX
  442.                POP   CX
  443.                POP   BX
  444.                RET
  445. rpunto         ENDP
  446.  
  447.  
  448. ; ------------ Selecciona la página de trabajo para setpix/getpix
  449. ;              en los modos que admiten varias.
  450. ;              Declaración: void setpage (int pagina);
  451.  
  452. pags           EQU   [BP+6]            ; para modelo LARGE
  453.  
  454. _setpage       PROC  FAR
  455.                PUSH  BP
  456.                MOV   BP,SP
  457.                MOV   AX,0A000h
  458.                CMP   WORD PTR pags,0
  459.                JE    sp_ok
  460.                MOV   AX,0A800h
  461. sp_ok:         MOV   _segvideo,AX      ; nueva dirección de vídeo
  462.                POP   BP
  463.                RET
  464. _setpage       ENDP
  465.  
  466.  
  467. ; ------------ Selecciona la página de trabajo visualizada en los
  468. ;              modos que admiten varias.
  469. ;              Declaración: void showpage (int pagina);
  470.  
  471. pagv           EQU   [BP+6]            ; para modelo LARGE
  472.  
  473. _showpage      PROC  FAR
  474.                PUSH  BP
  475.                MOV   BP,SP
  476.                MOV   DX,3DAh
  477.                PUSH  DS
  478.                MOV   AX,40h
  479.                MOV   DS,AX
  480.                MOV   CX,9              ; timeout de 0.5 segundos
  481.                MOV   AH,DS:[6Ch]
  482. frt_vert:      CMP   AH,DS:[6Ch]
  483.                JNE   frt_nvert
  484.                IN    AL,DX             ; esperar primero final del
  485.                TEST  AL,8              ; retrazado vertical
  486.                JNZ   frt_vert
  487.                JMP   irt_vert
  488. frt_nvert:     MOV   AH,DS:[6Ch]
  489.                LOOP  frt_vert
  490.                JMP   fin_shw           ; no llega el retrazo
  491. irt_vert:      CMP   AH,DS:[6Ch]
  492.                JNE   irt_nvert
  493.                IN    AL,DX             ; esperar inicio del
  494.                TEST  AL,8              ; retrazado vertical
  495.                JZ    irt_vert
  496.                JMP   fin_shw
  497. irt_nvert:     MOV   AH,DS:[6Ch]
  498.                LOOP  irt_vert
  499. fin_shw:       MOV   AX,pagv
  500.                AND   AL,AL             ; ¿página 0?
  501.                JZ    wp_ok             ; así es
  502.                MOV   AL,80h            ; página 1, con offset 8000h
  503. wp_ok:         MOV   DX,3D4h           ; direccionar CRT
  504.                MOV   AH,AL             ; byte alto del offset a AH
  505.                MOV   AL,0Ch
  506.                OUT   DX,AX
  507.                POP   DS
  508.                POP   BP
  509.                RET
  510. _showpage      ENDP
  511.  
  512.  
  513. ; ------------ Imprimir carácter de la fuente en modo X.
  514. ;              Declaración: void Xprcar (int car, int x, int y, int largo,
  515. ;                             int alto, int tinta, int papel, int pitch);
  516.  
  517. car            EQU   [BP+6]            ; para modelo LARGE
  518. c_x            EQU   [BP+8]
  519. c_y            EQU   [BP+10]
  520. largo          EQU   [BP+12]
  521. alto           EQU   [BP+14]
  522. tinta          EQU   [BP+16]
  523. papel          EQU   [BP+18]
  524. pitch          EQU   [BP+20]
  525.  
  526. _Xprcar        PROC  FAR
  527.                PUSH  BP
  528.                MOV   BP,SP
  529.                PUSH  ES
  530.                PUSH  SI
  531.                PUSH  DI
  532.                MOV   AX,320/4          ; calcular offset en VRAM
  533.                MUL   WORD PTR c_y
  534.                MOV   DI,c_x
  535.                SHR   DI,1
  536.                SHR   DI,1
  537.                ADD   DI,AX
  538.                MOV   ES,_segvideo      ; ES:DI -> VRAM
  539.                MOV   AL,car
  540.                MOV   AH,0
  541.                MOV   CL,4
  542.                SHL   AX,CL             ; carácter * 16
  543.                ADD   AX,OFFSET _FuenteInfo
  544.                MOV   SI,AX             ; SI -> fuente
  545.                MOV   CX,c_x
  546.                AND   CL,3              ; calcular máscara para el
  547.                MOV   BH,00010001b      ; mapa a direccionar en BH
  548.                ROL   BH,CL
  549.                MOV   BL,10000000b      ; pixel en curso en BL
  550.  
  551.                MOV   CX,8
  552. pr_horiz:      PUSH  CX
  553.  
  554.                MOV   CX,largo
  555. pr_duphoriz:   PUSH  CX
  556.                PUSH  SI
  557.                PUSH  DI
  558.  
  559.                MOV   AL,2              ; a AL el número de registro
  560.                MOV   AH,BH
  561.                MOV   DX,3C4h
  562.                OUT   DX,AX             ; cargar registro de máscara
  563.  
  564.                MOV   AH,tinta          ; tinta inicial
  565.  
  566.                MOV   DX,16
  567. pr_vert:
  568.                MOV   AL,AH             ; tinta en curso
  569.                TEST  [SI],BL
  570.                JNZ   pr_tin
  571.                MOV   AL,papel
  572.                CMP   AL,0FFh
  573.                JNE   pr_pap
  574.  
  575.                MOV   CX,alto
  576.                PUSH  BX
  577.                MOV   BL,AH
  578.                SHL   BX,1
  579. pr_nulvert:    ADD   DI,80             ; siguiente línea
  580.                ADD   BX,pitch
  581.                LOOP  pr_nulvert
  582.                SHR   BX,1
  583.                MOV   AH,BL
  584.                POP   BX
  585.                JMP   pr_otrop
  586.  
  587. pr_pap:        MOV   CX,alto
  588.                PUSH  BX
  589.                MOV   BL,AH
  590.                SHL   BX,1
  591. pr_papvert:    MOV   ES:[DI],AL        ; trazar punto de papel
  592.                ADD   DI,80             ; siguiente línea
  593.                ADD   BX,pitch
  594.                LOOP  pr_papvert
  595.                SHR   BX,1
  596.                MOV   AH,BL
  597.                POP   BX
  598.                JMP   pr_otrop
  599.  
  600. pr_tin:        MOV   CX,alto
  601.                PUSH  BX
  602.                MOV   BL,AL
  603.                SHL   BX,1
  604. pr_tinvert:    MOV   ES:[DI],AL        ; trazar punto de tinta
  605.                ADD   DI,80             ; siguiente línea
  606.                ADD   BX,pitch
  607.                MOV   AX,BX
  608.                SHR   AX,1
  609.                LOOP  pr_tinvert
  610.                MOV   AH,AL
  611.                POP   BX
  612.  
  613. pr_otrop:      INC   SI                ; siguiente scan
  614.  
  615.                DEC   DX
  616.                JNZ   pr_vert
  617.  
  618.                POP   DI
  619.                POP   SI
  620.  
  621.                ROL   BH,1              ; siguiente mapa de bits
  622.                JNC   pr_np
  623.                INC   DI                ; siguiente dirección VRAM
  624. pr_np:
  625.                POP   CX
  626.                LOOP  pr_duphoriz
  627.  
  628.                ROR   BL,1              ; siguiente pixel
  629.                POP   CX
  630.                DEC   CX
  631.                JZ    pr_ex
  632.  
  633.                JMP   pr_horiz
  634.  
  635. pr_ex:         POP   DI
  636.                POP   SI
  637.                POP   ES
  638.                POP   BP
  639.                RET
  640. _Xprcar        ENDP
  641.  
  642.  
  643. ; ------------ Imprimir carácter 8 ó 9x16 de la VGA en modo de 16 colores.
  644. ;              Declaración: int prcar (int car, int x, int y,
  645. ;                                      int tinta, int papel);
  646. ;              Devuelve la anchura efectiva usada (8 ó 9, según carácter).
  647.  
  648. chr            EQU   [BP+6]            ; para modelo LARGE
  649. chr_x          EQU   [BP+8]
  650. chr_y          EQU   [BP+10]
  651. chr_tinta      EQU   [BP+12]
  652. chr_papel      EQU   [BP+14]
  653.  
  654. _prcar         PROC  FAR
  655.                PUSH  BP
  656.                MOV   BP,SP
  657.                PUSH  ES
  658.                PUSH  DS
  659.                PUSH  SI
  660.                PUSH  DI
  661.                CMP   f8x16_seg,0
  662.                JNE   pr_rapido         ; punteros a fuentes ya inicializados
  663.                MOV   AX,1130h
  664.                MOV   BH,6
  665.                PUSH  ES                ; *
  666.                PUSH  BP                ; **
  667.                INT   10h
  668.                MOV   BX,BP
  669.                MOV   AX,ES             ; AX:BX -> juego 8x16
  670.                POP   BP                ; **
  671.                POP   ES                ; *
  672.                MOV   f8x16_off,BX
  673.                MOV   f8x16_seg,AX
  674.                MOV   AX,1130h
  675.                MOV   BH,7
  676.                PUSH  ES                ; *
  677.                PUSH  BP                ; **
  678.                INT   10h
  679.                MOV   BX,BP
  680.                MOV   AX,ES             ; AX:BX -> caracteres 9x16
  681.                POP   BP                ; **
  682.                POP   ES                ; *
  683.                MOV   fix9x16_off,BX
  684.                MOV   fix9x16_seg,AX
  685. pr_rapido:     MOV   DX,_segvideo      ; DX -> VRAM
  686.                MOV   AH,chr
  687.                PUSH  ES
  688.                MOV   DI,fix9x16_off
  689.                MOV   ES,fix9x16_seg
  690.                MOV   CX,256            ; «timeout»
  691. busca9:        MOV   AL,ES:[DI]
  692.                CMP   AL,AH
  693.                JNE   fin9?
  694.                ADD   SP,2              ; "POP ES"
  695.                MOV   CH,1              ; anchura = 9 pixels (8+1)
  696.                JMP   pfuente_ok        ; fuente en ES:DI+1
  697. fin9?:         AND   AL,AL
  698.                JZ    usar8
  699.                ADD   DI,17
  700.                LOOP  busca9
  701. usar8:         POP   ES
  702.                MOV   AL,chr
  703.                MOV   AH,0
  704.                MOV   BL,AL
  705.                MOV   CL,4
  706.                SHL   AX,CL
  707.                MOV   DI,f8x16_off
  708.                MOV   ES,f8x16_seg
  709.                ADD   DI,AX
  710.                DEC   DI
  711.                MOV   CH,0              ; anchura = 8 pixels (8+0)
  712.                CMP   BL,255
  713.                JNE   pfuente_ok        ; código 255: 9 pixels de ancho
  714.                INC   CH
  715. pfuente_ok:    INC   DI                ; fuente en ES:DI
  716.                MOV   DS,DX             ; DS -> VRAM
  717.  
  718.                MOV   SI,chr_x
  719.                MOV   BX,SI
  720.                MOV   CL,3
  721.                SHR   SI,CL             ; SI = chr_x / 8
  722.                MOV   AX,80             ; bytes por línea
  723.                MUL   WORD PTR chr_y
  724.                ADD   SI,AX             ; DS:SI -> VRAM carácter
  725.                AND   BL,00000111b
  726.                MOV   CL,BL             ; CL = bits a respetar por la izda
  727.                MOV   DX,3CEh
  728.                MOV   AX,205h           ; modo read 0 y write 2
  729.                OUT   DX,AX
  730.                MOV   BL,16             ; altura de la fuente
  731.  
  732. pr_print8:     MOV   AX,0FF08h
  733.                SHR   AH,CL             ; AH = máscara de papel rotada
  734.                OUT   DX,AX             ; actualizar registro máscara
  735.                MOV   AH,[SI]           ; actualizar latches
  736.                MOV   BH,chr_papel
  737.                MOV   [SI],BH           ; escribir VRAM con color fondo izdo
  738.                MOV   AH,[SI]           ; cargar latches con color de fondo
  739.                MOV   AH,ES:[DI]        ; trama del carácter
  740.                SHR   AH,CL             ; rotada a su sitio
  741.                OUT   DX,AX             ; registro máscara de bit con trama
  742.                MOV   BH,chr_tinta
  743.                MOV   [SI],BH           ; pintar izda carácter (color tinta)
  744.                AND   CH,CH
  745.                JNZ   no_skip_b2
  746.                AND   CL,CL
  747.                JZ    skip_b2
  748. no_skip_b2:    INC   SI                ; parte derecha
  749.                PUSH  CX
  750.                SUB   CL,8
  751.                NEG   CL                ; bits a correr a la izda
  752.                SUB   CL,CH             ; 8/9
  753.                MOV   AX,0FF08h
  754.                SHL   AH,CL             ; AH = máscara de papel rotada
  755.                OUT   DX,AX             ; actualizar registro máscara
  756.                MOV   AH,[SI]           ; actualizar latches
  757.                MOV   BH,chr_papel
  758.                MOV   [SI],BH           ; escribir VRAM con color fondo dcho
  759.                MOV   AH,[SI]           ; cargar latches con color de fondo
  760.                ADD   CL,CH             ; 8/9
  761.                MOV   AH,ES:[DI]        ; trama del carácter
  762.                SHL   AH,CL             ; rotada a su sitio
  763.                OUT   DX,AX             ; registro máscara de bit con trama
  764.                MOV   BH,chr_tinta
  765.                MOV   [SI],BH           ; pintar dcha carácter (color tinta)
  766.                POP   CX
  767.                DEC   SI
  768. skip_b2:       INC   DI                ; preparar para siguiente scan
  769.                ADD   SI,80             ; siguiente línea en pantalla
  770.                DEC   BL
  771.                JNZ   pr_print8
  772.  
  773.                MOV   AX,5
  774.                OUT   DX,AX             ; modo read 0 y write 0 de la BIOS
  775.                MOV   AX,0FF08h
  776.                OUT   DX,AX             ; registro máscara de bit a 0xFF
  777.                POP   DI
  778.                POP   SI
  779.                POP   DS
  780.                POP   ES
  781.                POP   BP
  782.                MOV   AL,CH
  783.                ADD   AL,8
  784.                MOV   AH,0              ; retornar anchura carácter
  785.                RET
  786. _prcar         ENDP
  787.  
  788.  
  789. ; ------------ Imprimir mapa de bits en modo X.
  790. ;              Declaración: void PintaBitMap (char *bitmap, int ancho,
  791. ;                                            int relx, int rely, int lx,
  792. ;                                            int ly, int x, int y, int modo);
  793.  
  794. bitmap         EQU   [BP+6]            ; para modelo LARGE
  795. ancho          EQU   [BP+10]
  796. relx           EQU   [BP+12]           ; coordenadas relativas sobre
  797. rely           EQU   [BP+14]           ; el propio bitmap
  798. lx             EQU   [BP+16]
  799. ly             EQU   [BP+18]
  800. p_x            EQU   [BP+20]
  801. p_y            EQU   [BP+22]
  802. modo           EQU   [BP+24]
  803.  
  804. _PintaBitMap   PROC  FAR
  805.                PUSH  BP
  806.                MOV   BP,SP
  807.                PUSH  SI
  808.                PUSH  DI
  809.                PUSH  DS
  810.                PUSH  ES
  811.                MOV   ES,_segvideo
  812.                LDS   SI,bitmap
  813.  
  814.                MOV   BX,320/4
  815.                CMP   WORD PTR modo,0
  816.                JE    bm_ini_ok
  817.                NEG   BX
  818.                MOV   AX,lx             ; empezar por el final
  819.                DEC   AX
  820.                ADD   p_x,AX
  821.                MOV   AX,ly
  822.                DEC   AX
  823.                ADD   p_y,AX
  824.  
  825. bm_ini_ok:     MOV   AX,rely
  826.                MUL   WORD PTR ancho
  827.                ADD   AX,relx
  828.                ADD   SI,AX             ; DS:SI -> bitmap
  829.  
  830.                MOV   AX,320/4          ; calcular offset en VRAM
  831.                MUL   WORD PTR p_y
  832.                MOV   CX,p_x
  833.                MOV   DI,CX
  834.                SHR   DI,1
  835.            SHR   DI,1
  836.                ADD   DI,AX             ; offset en DI
  837.                AND   CL,3              ; calcular máscara para el
  838.                MOV   AH,00010001b      ; mapa a direccionar en AH
  839.                ROL   AH,CL
  840.                MOV   AL,2              ; a AL el número de registro
  841.                MOV   DX,3C4h
  842.                OUT   DX,AX             ; cargar registro de máscara
  843.  
  844.                MOV   CX,lx
  845. bm_horiz:      PUSH  CX
  846.                PUSH  SI
  847.                PUSH  DI
  848.                PUSH  DS
  849.                MOV   CX,ly
  850. bm_vert:       MOV   AL,[SI]
  851.                MOV   ES:[DI],AL        ; trazar punto
  852.                ADD   DI,BX             ; siguiente scan
  853.                ADD   SI,ancho          ; siguiente punto vertical
  854.                JNC   si_ok1
  855.                PUSH  AX                ; desbordamiento de segmento
  856.                MOV   AX,DS
  857.                ADD   AX,1000h
  858.                MOV   DS,AX
  859.                POP   AX
  860. si_ok1:        LOOP  bm_vert
  861.                POP   DS
  862.                POP   DI
  863.                POP   SI
  864.                INC   SI                ; siguiente punto horizontal
  865.                JNZ   si_ok2
  866.                PUSH  AX                ; desbordamiento de segmento
  867.                MOV   AX,DS
  868.                ADD   AX,1000h
  869.                MOV   DS,AX
  870.                POP   AX
  871. si_ok2:        AND   BX,BX
  872.                JNS   bm_derecho
  873.                ROR   AH,1              ; impresión al revés
  874.                JNC   bm_np
  875.                DEC   DI
  876.                JMP   bm_np
  877. bm_derecho:    ROL   AH,1              ; siguiente mapa de bits
  878.                JNC   bm_np
  879.                INC   DI                ; siguiente dirección VRAM
  880. bm_np:         MOV   AL,2
  881.                OUT   DX,AX
  882.                POP   CX
  883.                LOOP  bm_horiz
  884.  
  885.                POP   ES
  886.                POP   DS
  887.                POP   DI
  888.                POP   SI
  889.                POP   BP
  890.                RET
  891. _PintaBitMap   ENDP
  892.  
  893.  
  894. ; ------------ Copiar bloque de una zona de vídeo a otra en modo X.
  895. ;              Declaración: void MoveVram (void *fuente, void *destino,
  896. ;                                          unsigned numbytes);
  897.  
  898. fuente         EQU   [BP+6]            ; para modelo LARGE
  899. destino        EQU   [BP+10]
  900. numbytes       EQU   [BP+14]
  901.  
  902. _MoveVram      PROC  FAR
  903.                PUSH  BP
  904.                MOV   BP,SP
  905.                PUSH  SI
  906.                PUSH  DI
  907.                PUSH  DS
  908.                PUSH  ES
  909.                LDS   SI,fuente
  910.                LES   DI,destino
  911.                MOV   CX,numbytes
  912.                MOV   BH,0001b          ; para registro de máscara
  913.                MOV   BL,0              ; para registro Read-Map
  914.                CLD
  915. copia_plano:   PUSH  SI
  916.                PUSH  DI
  917.                PUSH  CX
  918.                MOV   AL,2
  919.                MOV   AH,BH
  920.                MOV   DX,3C4h           ; registro de máscara
  921.                OUT   DX,AX
  922.                MOV   AL,4
  923.                MOV   AH,BL
  924.                MOV   DX,3CEh           ; registro Read-Map
  925.                OUT   DX,AX
  926.                REP   MOVSB             ; copiar plano de bits
  927.                POP   CX
  928.                POP   DI
  929.                POP   SI
  930.                SHL   BH,1              ; siguiente plano escritura
  931.                INC   BL                ; siguiente plano lectura
  932.                CMP   BL,4
  933.                JB    copia_plano       ; completar los 4 planos
  934.                POP   ES
  935.                POP   DS
  936.                POP   DI
  937.                POP   SI
  938.                POP   BP
  939.                RET
  940. _MoveVram      ENDP
  941.  
  942.  
  943. ; ------------ Copiar un bloque de memoria a otro sitio. El compilador
  944. ;              tiene media docena de funciones o mas pero ni una sola
  945. ;              que funcione bien. Requiere punteros huge.
  946. ;
  947. ;              Declaración:
  948. ;                 void MoveMem (char huge *fuente, char huge *destino,
  949. ;                               unsigned numbytes);
  950.  
  951. fuente         EQU   [BP+6]            ; para modelo LARGE
  952. destino        EQU   [BP+10]
  953. numbytes       EQU   [BP+14]
  954.  
  955. _MoveMem       PROC  FAR
  956.                PUSH  BP
  957.                MOV   BP,SP
  958.                PUSH  SI
  959.                PUSH  DI
  960.                PUSH  DS
  961.                PUSH  ES
  962.                LDS   SI,fuente
  963.                LES   DI,destino
  964.                MOV   CX,numbytes
  965.                SHR   CX,1
  966.                CLD
  967.                PUSHF
  968.                REP   MOVSW
  969.                POPF
  970.                JNC   fin_mv
  971.                MOVSB
  972. fin_mv:        POP   ES
  973.                POP   DS
  974.                POP   DI
  975.                POP   SI
  976.                POP   BP
  977.                RET
  978. _MoveMem       ENDP
  979.  
  980.  
  981. ; ------------ Impresión en pantalla en color usando la BIOS. Al hacer
  982. ;              scroll se intenta respetar el posible color global de fondo.
  983. ;
  984. ;                 0 -> final de cadena
  985. ;                 1 -> inicializar rutina (necesario si cambia el modo
  986. ;                      de pantalla): automático la primera vez
  987. ;                 2 -> el siguiente carácter indica la tinta (BIOS)
  988. ;                 3 -> el siguiente carácter indica el papel (BIOS)
  989. ;                 4 -> el siguiente carácter indica el nº de veces que
  990. ;                      se imprimirá el que viene detrás
  991. ;                 5 -> avanzar cursor a la derecha
  992. ;                10 -> retorno de carro y salto de línea estilo UNIX
  993. ;
  994. ;              Declaración: void prbios (char *cadena);
  995.  
  996. cadena         EQU   [BP+6]            ; para modelo LARGE
  997.  
  998. _prbios        PROC  FAR
  999.                PUSH  BP
  1000.                MOV   BP,SP
  1001.                PUSH  SI
  1002.                PUSH  DI
  1003.                PUSH  DS
  1004.                PUSH  ES
  1005.                LES   BX,cadena
  1006.  
  1007.                CMP   pr_pagina,-1      ; ¿primera vez?
  1008.                JNE   pr_otro
  1009.                CALL  prbios_init
  1010.  
  1011. pr_otro:       MOV   AL,ES:[BX]
  1012.                PUSH  BX
  1013.                CMP   AL,' '
  1014.                JAE   pr_ASCII          ; no es un código de control
  1015.                AND   AL,AL
  1016.                JZ    pr_exit           ; código de control 0: final
  1017.                CMP   AL,1
  1018.                JE    pr_init           ; código de control 1: reset
  1019.                CMP   AL,2
  1020.                JE    pr_settinta       ; código de control 2: tinta
  1021.                CMP   AL,3
  1022.                JE    pr_setpapel       ; código de control 3: papel
  1023.                CMP   AL,4
  1024.                JE    pr_setveces       ; código de control 4: repetir
  1025. pr_ASCII:      CALL  pr_AL_bios
  1026.                POP   BX
  1027.                INC   BX
  1028.                JMP   pr_otro
  1029. pr_settinta:   MOV   AL,ES:[BX+1]
  1030.                AND   AL,15
  1031.                AND   pr_color,240
  1032.                OR    pr_color,AL       ; actualizar color tinta
  1033.                POP   BX
  1034.                ADD   BX,2
  1035.                JMP   pr_otro
  1036. pr_setpapel:   MOV   AL,ES:[BX+1]
  1037.                AND   AL,240
  1038.                AND   pr_color,15
  1039.                OR    pr_color,AL       ; actualizar color papel
  1040.                POP   BX
  1041.                ADD   BX,2
  1042.                JMP   pr_otro
  1043. pr_setveces:   MOV   AL,ES:[BX+1]
  1044.                MOV   pr_veces,AL       ; actualizar repeticiones
  1045.                POP   BX
  1046.                ADD   BX,2
  1047.                JMP   pr_otro
  1048. pr_init:       CALL  prbios_init
  1049.                POP   BX
  1050.                INC   BX
  1051.                JMP   pr_otro
  1052. pr_exit:       POP   BX
  1053.  
  1054.                POP   ES
  1055.                POP   DS
  1056.                POP   DI
  1057.                POP   SI
  1058.                POP   BP
  1059.                RET
  1060. _prbios        ENDP
  1061.  
  1062. pr_AL_bios     PROC                    ; imprimir en color usando BIOS
  1063.                PUSH  AX
  1064.                MOV   AH,3
  1065.                MOV   BH,pr_pagina
  1066.                INT   10h               ; DX = coordenadas del cursor
  1067.                POP   AX
  1068.                CMP   AL,5
  1069.                JE    pr_derecha        ; código de control 3: avanzar
  1070.                CMP   AL,10
  1071.                JE    pr_crlf           ; código de control 10: CR & LF
  1072.                MOV   AH,9
  1073.                MOV   BH,pr_pagina
  1074.                MOV   BL,pr_color
  1075.                MOV   CL,pr_veces
  1076.                XOR   CH,CH
  1077.                PUSH  DX
  1078.                INT   10h               ; imprimir carácter
  1079.                POP   DX
  1080. pr_derecha:    ADD   DL,pr_veces
  1081.                MOV   pr_veces,1
  1082.                CMP   DL,pr_maxX
  1083.                JBE   pr_av
  1084. pr_crlf:       XOR   DL,DL             ; volver al inicio de línea
  1085.                INC   DH                ; salto a la siguiente
  1086.                PUSH  DS
  1087.                MOV   AX,40h
  1088.                MOV   DS,AX
  1089.                CMP   DH,DS:[84h]       ; variable de nº líneas - 1
  1090.                POP   DS
  1091.                JBE   pr_av
  1092.                DEC   DH
  1093.                PUSH  DX                ; es preciso hacer scroll
  1094.                PUSH  DS
  1095.                MOV   AX,40h
  1096.                MOV   DS,AX
  1097.                MOV   DH,DS:[84h]
  1098.                POP   DS
  1099.                MOV   AX,601h
  1100.                MOV   BH,pr_colorb      ; color por defecto
  1101.                XOR   CX,CX
  1102.                MOV   DL,pr_maxX
  1103.                INT   10h               ; hacer scroll usando BIOS
  1104.                POP   DX
  1105. pr_av:         MOV   BH,pr_pagina
  1106.                MOV   AH,2
  1107.                INT   10h               ; posicionar cursor
  1108.                RET
  1109. pr_AL_bios     ENDP
  1110.  
  1111. prbios_init    PROC
  1112.                PUSH  BX
  1113.                MOV   AH,15
  1114.                INT   10h
  1115.                MOV   pr_pagina,BH
  1116.                MOV   AH,8
  1117.                INT   10h               ; obtener color por defecto
  1118.                MOV   pr_color,AH
  1119.                MOV   pr_colorb,AH
  1120.                PUSH  DS
  1121.                MOV   AX,40h
  1122.                MOV   DS,AX
  1123.                MOV   AX,DS:[4Ah]
  1124.                CMP   BYTE PTR DS:[84h],24  ; variable de nº líneas - 1
  1125.                JAE   pr_ln_ok
  1126.                MOV   BYTE PTR DS:[82h],24  ; inicializar esta variable
  1127. pr_ln_ok:      POP   DS
  1128.                MOV   pr_maxX,AL
  1129.                POP   BX
  1130.                RET
  1131. prbios_init    ENDP
  1132.  
  1133. pr_pagina      DB    -1      ; página de visualización activa
  1134. pr_veces       DB    1       ; veces que se imprime cada carácter
  1135. pr_color       DB    ?       ; color BIOS para imprimir
  1136. pr_colorb      DB    ?       ; color por defecto en pantalla
  1137. pr_maxX        DB    ?       ; máxima coordenada X en pantalla
  1138.  
  1139.  
  1140. ; ------------ Establecer el modo 80x30 en la VGA (fuente 8x16).
  1141. ;              Declaración: int set80x30 (void);
  1142. ;              Devuelve 1 si funciona y 0 si falla (no hay VGA o
  1143. ;              no estaba en modo texto de color) además de asignar
  1144. ;              en ese caso el nº de líneas a 25 (por si la variable
  1145. ;              de la BIOS está indefinida).
  1146.  
  1147. _set80x30      PROC  FAR
  1148.                PUSH  SI
  1149.                PUSH  DI
  1150.                MOV   AX,1A00h
  1151.                INT   10h
  1152.                CMP   AL,1Ah
  1153.                JNE   set80err      ; no es VGA
  1154.                CMP   BL,7
  1155.                JE    es_vga
  1156.                CMP   BL,8
  1157.                JE    es_vga
  1158.                CMP   BL,9
  1159.                JE    es_vga
  1160.                CMP   BL,12
  1161.                JBE   set80err      ; no es VGA
  1162. es_vga:        MOV   AH,0Fh
  1163.                INT   10h
  1164.                CMP   AL,3
  1165.                JA    set80err      ; no es modo texto de color
  1166.  
  1167. set30:         MOV   DX,3D4h       ; Dirección base del CRTC
  1168.                CLI
  1169.                MOV   AX,00C11h     ; Vertical Display End (desproteger regs. 0-7)
  1170.                OUT   DX,AX
  1171.                MOV   AX,00D06h     ; Vertical Total
  1172.                OUT   DX,AX
  1173.                MOV   AX,03E07h     ; Overflow
  1174.                OUT   DX,AX
  1175.                MOV   AX,0EA10h     ; Vertical Retrace Start
  1176.                OUT   DX,AX
  1177.                MOV   AX,08C11h     ; Vertical Retrace End (y proteger regs. 0-7)
  1178.                OUT   DX,AX
  1179.                MOV   AX,0DF12h     ; Vertical Display Enable End
  1180.                OUT   DX,AX
  1181.                MOV   AX,0E715h     ; Start Vertical Blanking
  1182.                OUT   DX,AX
  1183.                MOV   AX,00616h     ; End Vertical Blanking
  1184.                OUT   DX,AX
  1185.                MOV   DX,3CCh       ; Miscellaneous Output
  1186.                IN    AL,DX
  1187.                AND   AL,00110011b  ; Cambiamos sólo el clock mode a 1
  1188.                OR    AL,11000100b  ; y la VSP a negativa.
  1189.                MOV   DX,3C2h
  1190.                OUT   DX,AL
  1191.                STI
  1192.                PUSH  DS
  1193.                MOV   AX,0040h                  ; área de la BIOS
  1194.                MOV   DS,AX
  1195.                MOV   WORD PTR DS:[004Ch],8192  ; nuevo tamaño de página en bytes
  1196.                MOV   BYTE PTR DS:[0084h],29    ; número de líneas-1
  1197.                POP   DS
  1198.                MOV   AX,1          ; función con éxito
  1199.                POP   DI
  1200.                POP   SI
  1201.                RET
  1202.  
  1203. set80err:      PUSH  DS
  1204.                MOV   AX,0040h                  ; área de la BIOS
  1205.                MOV   DS,AX
  1206.                MOV   BYTE PTR DS:[0084h],24    ; número de líneas-1
  1207.                POP   DS
  1208.                MOV   AX,0          ; función con fallo
  1209.                POP   DI
  1210.                POP   SI
  1211.                RET
  1212. _set80x30      ENDP
  1213.  
  1214.  
  1215. ; ------------ Restablecer el modo de vídeo normal.
  1216. ;              Declaración:  void ResetVideo (void);
  1217.  
  1218. _ResetVideo    PROC  FAR
  1219.                PUSH  SI
  1220.                PUSH  DI
  1221.                PUSH  DS
  1222.                MOV   DI,40h
  1223.                MOV   DS,DI
  1224.                MOV   AL,DS:[49h]
  1225.                POP   DS
  1226.                XOR   AH,AH
  1227.                INT   10h                       ; reponer modo en curso
  1228.                POP   DI
  1229.                POP   SI
  1230.                RET
  1231. _ResetVideo    ENDP
  1232.  
  1233.  
  1234. ; ------------ Gestor de errores críticos para mejorar presentación.
  1235.  
  1236. _NuevaInt24    PROC
  1237.                MOV   AL,3      ; error en la función DOS invocada.
  1238.                IRET
  1239. _NuevaInt24    ENDP
  1240.  
  1241.  
  1242. ; ------------ Indicar con gran rapidez si no hay una tecla pulsada.
  1243. ;              Declaración: int NoHayTecla (void);
  1244.  
  1245. _NoHayTecla    PROC  FAR
  1246.                PUSH  DS
  1247.                MOV   AX,40h
  1248.                MOV   DS,AX
  1249.                MOV   AX,DS:[1Ah]
  1250.                CMP   AX,DS:[1Ch]
  1251.                MOV   AX,1
  1252.                JE    condtec_ok
  1253.                MOV   AX,0
  1254. condtec_ok:    POP   DS
  1255.                RET
  1256. _NoHayTecla    ENDP
  1257.  
  1258.  
  1259. _TEXT          ENDS
  1260.  
  1261.  
  1262. _DATA          SEGMENT WORD PUBLIC 'DATA'
  1263.  
  1264. _segvideo      DW    0A000h            ; puede variar con la página
  1265.  
  1266. _fuente8x16    LABEL DWORD             ; puntero a fuente VGA 8x16
  1267. f8x16_off      DW    0
  1268. f8x16_seg      DW    0
  1269.  
  1270. _fix9x16       LABEL DWORD             ; puntero a caracteres VGA 9x16
  1271. fix9x16_off    DW    0
  1272. fix9x16_seg    DW    0
  1273.  
  1274. ; ------------ Juego de caracteres 8x16 con estilo informático.
  1275.  
  1276. _FuenteInfo    EQU   THIS BYTE
  1277.                DB      0,   0,   0,   0,   0,   0,   0,   0
  1278.                DB      0,   0,   0,   0,   0,   0,   0,   0
  1279.                DB      0,   0,   0,  60,  66, 129, 165, 129
  1280.                DB    189, 153, 129,  66,  60,   0,   0,   0
  1281.                DB      0,   0,   0,  60, 126, 255, 219, 255
  1282.                DB    195, 231, 255, 126,  60,   0,   0,   0
  1283.                DB      0,   0,   0,   0, 108, 254, 254, 254
  1284.                DB    254, 124,  56,  16,   0,   0,   0,   0
  1285.                DB      0,   0,   0,   0,  16,  56, 124, 254
  1286.                DB    124,  56,  16,   0,   0,   0,   0,   0
  1287.                DB      0,   0,   0,  24,  60,  24, 102, 255
  1288.                DB    102,  24,  24,  60,   0,   0,   0,   0
  1289.                DB      0,   0,   0,  24,  60, 126, 255, 255
  1290.                DB    126,  24,  24,  60,   0,   0,   0,   0
  1291.                DB      0,   0,   0,   0,   0,   0,  24,  60
  1292.                DB     60,  24,   0,   0,   0,   0,   0,   0
  1293.                DB    255, 255, 255, 255, 255, 255, 231, 195
  1294.                DB    195, 231, 255, 255, 255, 255, 255, 255
  1295.                DB      0,   0,   0,   0,   0,  60, 102,  66
  1296.                DB     66, 102,  60,   0,   0,   0,   0,   0
  1297.                DB    255, 255, 255, 255, 255, 195, 153, 189
  1298.                DB    189, 153, 195, 255, 255, 255, 255, 255
  1299.                DB      0,   0,  30,  14,  26,  50, 120, 204
  1300.                DB    204, 204, 204, 120,   0,   0,   0,   0
  1301.                DB      0,   0,  60, 102, 102, 102, 102,  60
  1302.                DB     24, 126,  24,  24,   0,   0,   0,   0
  1303.                DB      0,   0,   0,  62,  51,  62,  51,  48
  1304.                DB     48, 112, 240, 224,   0,   0,   0,   0
  1305.                DB      0,   0,   0,  63,  51,  63,  51,  51
  1306.                DB     51, 119, 255, 238,   0,   0,   0,   0
  1307.                DB      0,   0,  24,  24,  24, 219,  60, 231
  1308.                DB     60, 219,  24,  24,  24,   0,   0,   0
  1309.                DB      0, 128, 192, 224, 240, 248, 254, 248
  1310.                DB    240, 224, 192, 128,   0,   0,   0,   0
  1311.                DB      0,   2,   6,  14,  30,  62, 254,  62
  1312.                DB     30,  14,   6,   2,   0,   0,   0,   0
  1313.                DB      0,   0,  24,  60, 126,  24,  24,  24
  1314.                DB    126,  60,  24,   0,   0,   0,   0,   0
  1315.                DB      0,   0, 102, 102, 102, 102, 102, 102
  1316.                DB    102,   0, 102, 102,   0,   0,   0,   0
  1317.                DB      0,   0, 127, 219, 219, 219, 123,  27
  1318.                DB     27,  27,  27,  27,   0,   0,   0,   0
  1319.                DB      0, 124, 198,  96,  56, 108, 198, 198
  1320.                DB    108,  56,  12, 198, 124,   0,   0,   0
  1321.                DB      0,   0,   0,   0,   0,   0,   0,   0
  1322.                DB    254, 254, 254, 254,   0,   0,   0,   0
  1323.                DB      0,   0,  24,  60, 126,  24,  24,  24
  1324.                DB    126,  60,  24, 126,   0,   0,   0,   0
  1325.                DB      0,   0,  24,  60, 126,  24,  24,  24
  1326.                DB     24,  24,  24,  24,   0,   0,   0,   0
  1327.                DB      0,   0,  24,  24,  24,  24,  24,  24
  1328.                DB     24, 126,  60,  24,   0,   0,   0,   0
  1329.                DB      0,   0,   0,   0,   0,  24,  12, 254
  1330.                DB     12,  24,   0,   0,   0,   0,   0,   0
  1331.                DB      0,   0,   0,   0,   0,  48,  96, 254
  1332.                DB     96,  48,   0,   0,   0,   0,   0,   0
  1333.                DB      0,   0,   0,   0,   0,   0, 192, 192
  1334.                DB    192, 254,   0,   0,   0,   0,   0,   0
  1335.                DB      0,   0,   0,   0,   0,  36, 102, 255
  1336.                DB    102,  36,   0,   0,   0,   0,   0,   0
  1337.                DB      0,   0,   0,  16,  16,  16,  16,  56
  1338.                DB     56,  56, 124, 124, 124, 254, 254,   0
  1339.                DB      0, 254, 254, 124, 124, 124,  56,  56
  1340.                DB     56,  16,  16,  16,  16,   0,   0,   0
  1341.                DB      0,   0,   0,   0,   0,   0,   0,   0
  1342.                DB      0,   0,   0,   0,   0,   0,   0,   0
  1343.                DB      0,   0,   0,  48,  48,  48,  48,  56
  1344.                DB     56,  56,   0,  56,   0,   0,   0,   0
  1345.                DB      0,   0,   0, 238, 238,  34,  34,   0
  1346.                DB      0,   0,   0,   0,   0,   0,   0,   0
  1347.                DB      0,   0,   0,  36,  36, 126,  36,  36
  1348.                DB    126,  36,  36,   0,   0,   0,   0,   0
  1349.                DB      0,   0,   0,  24, 126,  98,  96, 126
  1350.                DB     14,  78, 126,  24,   0,   0,   0,   0
  1351.                DB      0,   0,   0, 226, 226,   2,   2, 254
  1352.                DB    224, 224, 238, 238,   0,   0,   0,   0
  1353.                DB      0,   0,   0, 120,  96, 100, 254, 228
  1354.                DB    228, 228, 228, 252,   0,   0,   0,   0
  1355.                DB      0,   0,   0,  56,  56,   8,   0,   0
  1356.                DB      0,   0,   0,   0,   0,   0,   0,   0
  1357.                DB      0,   0,  14,  24,  24,  24,  24,  28
  1358.                DB     28,  28,  28,  28,  14,   0,   0,   0
  1359.                DB      0,   0, 112,  24,  24,  24,  24,  56
  1360.                DB     56,  56,  56,  56, 112,   0,   0,   0
  1361.                DB      0,   0,   0,   0,   0, 214, 214, 124
  1362.                DB    214, 214,   0,   0,   0,   0,   0,   0
  1363.                DB      0,   0,   0,   0,   0,   0,  24,  24
  1364.                DB    126,  24,  24,   0,   0,   0,   0,   0
  1365.                DB      0,   0,   0,   0,   0,   0,   0,   0
  1366.                DB      0,   0,  56,  56,   8,   8,   0,   0
  1367.                DB      0,   0,   0,   0,   0,   0,   0,   0
  1368.                DB    126,   0,   0,   0,   0,   0,   0,   0
  1369.                DB      0,   0,   0,   0,   0,   0,   0,   0
  1370.                DB      0,   0,  56,  56,   0,   0,   0,   0
  1371. ;               DB      0,   0,   0,   2,   2,   2,   2, 254  ; / orig.
  1372. ;               DB    224, 224, 224, 224,   0,   0,   0,   0
  1373.                DB      0,   0,   0,   0,   2,   6,  12,  24   ; / modif.
  1374.                DB     48,  96,  64,   0,   0,   0,   0,   0
  1375.                DB      0,   0,   0, 254, 134, 134, 142, 142
  1376.                DB    142, 142, 142, 254,   0,   0,   0,   0
  1377.                DB      0,   0,   0,  24,  24,  24,  56,  56
  1378.                DB     56,  56,  56,  56,   0,   0,   0,   0
  1379.                DB      0,   0,   0, 254, 134,   6,   6,   6
  1380.                DB    254, 224, 226, 254,   0,   0,   0,   0
  1381.                DB      0,   0,   0, 252, 140,  12,  14,  62
  1382.                DB     14,  14, 142, 254,   0,   0,   0,   0
  1383.                DB      0,   0,   0, 140, 140, 140, 140, 140
  1384.                DB    254,  28,  28,  28,   0,   0,   0,   0
  1385.                DB      0,   0,   0, 254, 192, 192, 254,  14
  1386.                DB     14,  14, 142, 254,   0,   0,   0,   0
  1387.                DB      0,   0,   0, 254, 134, 128, 254, 142
  1388.                DB    142, 142, 142, 254,   0,   0,   0,   0
  1389.                DB      0,   0,   0, 254, 134,   6,  14,  14
  1390.                DB     14,  14,  14,  14,   0,   0,   0,   0
  1391.                DB      0,   0,   0, 124,  76,  76, 254, 142
  1392.                DB    142, 142, 142, 254,   0,   0,   0,   0
  1393.                DB      0,   0,   0, 254, 134, 134, 134, 134
  1394.                DB    254,  14,  14,  14,   0,   0,   0,   0
  1395.                DB      0,   0,   0,   0,   0,   0,  56,  56
  1396.                DB      0,   0,  56,  56,   0,   0,   0,   0
  1397.                DB      0,   0,   0,   0,   0,   0,  56,  56
  1398.                DB      0,   0,  56,  56,   8,   8,   0,   0
  1399.                DB      0,   0,   0,   0,   6,  12,  24,  48
  1400.                DB    112,  56,  28,  14,   0,   0,   0,   0
  1401.                DB      0,   0,   0,   0,   0,   0, 126, 126
  1402.                DB      0, 126, 126,   0,   0,   0,   0,   0
  1403.                DB      0,   0,   0,   0,  96,  48,  24,  12
  1404.                DB     14,  28,  56, 112,   0,   0,   0,   0
  1405.                DB      0,   0,   0, 254, 134,   6, 126, 112
  1406.                DB    112,   0, 112, 112,   0,   0,   0,   0
  1407.                DB      0,   0,   0, 254, 130, 186, 170, 170
  1408.                DB    190, 128, 254,   0,   0,   0,   0,   0
  1409.                DB      0,   0,   0, 124, 100, 100, 254, 226
  1410.                DB    226, 226, 226, 226,   0,   0,   0,   0
  1411.                DB      0,   0,   0, 252, 196, 196, 254, 226
  1412.                DB    226, 226, 226, 254,   0,   0,   0,   0
  1413.                DB      0,   0,   0, 254, 194, 192, 192, 224
  1414.                DB    224, 224, 226, 254,   0,   0,   0,   0
  1415.                DB      0,   0,   0, 254, 194, 194, 226, 226
  1416.                DB    226, 226, 226, 254,   0,   0,   0,   0
  1417.                DB      0,   0,   0, 254, 192, 192, 192, 254
  1418.                DB    224, 224, 224, 254,   0,   0,   0,   0
  1419.                DB      0,   0,   0, 254, 192, 192, 192, 248
  1420.                DB    224, 224, 224, 224,   0,   0,   0,   0
  1421.                DB      0,   0,   0, 254, 194, 192, 192, 238
  1422.                DB    226, 226, 226, 254,   0,   0,   0,   0
  1423.                DB      0,   0,   0, 194, 194, 194, 194, 254
  1424.                DB    226, 226, 226, 226,   0,   0,   0,   0
  1425.                DB      0,   0,   0,  48,  48,  48,  48,  56
  1426.                DB     56,  56,  56,  56,   0,   0,   0,   0
  1427.                DB      0,   0,   0,  12,  12,  12,  14,  14
  1428.                DB     14, 142, 142, 254,   0,   0,   0,   0
  1429.                DB      0,   0,   0, 196, 196, 196, 254, 226
  1430.                DB    226, 226, 226, 226,   0,   0,   0,   0
  1431.                DB      0,   0,   0, 192, 192, 192, 224, 224
  1432.                DB    224, 224, 224, 254,   0,   0,   0,   0
  1433. ;               DB      0,   0,   0, 238, 214, 214, 214, 214  ; M orig.
  1434. ;               DB    230, 230, 230, 226,   0,   0,   0,   0
  1435.                DB      0,   0,   0, 198, 238, 254, 254, 214   ; M modif.
  1436.                DB    198, 198, 198, 198,   0,   0,   0,   0
  1437.                DB      0,   0,   0, 254, 194, 194, 226, 226
  1438.                DB    226, 226, 226, 226,   0,   0,   0,   0
  1439.                DB      0,   0,   0, 254, 142, 134, 134, 134
  1440.                DB    134, 134, 134, 254,   0,   0,   0,   0
  1441.                DB      0,   0,   0, 254, 194, 194, 254, 224
  1442.                DB    224, 224, 224, 224,   0,   0,   0,   0
  1443.                DB      0,   0,   0, 254, 134, 134, 134, 134
  1444.                DB    134, 158, 158, 254,   0,   0,   0,   0
  1445.                DB      0,   0,   0, 252, 196, 196, 254, 226
  1446.                DB    226, 226, 226, 226,   0,   0,   0,   0
  1447.                DB      0,   0,   0, 254, 194, 192, 254,  14
  1448.                DB     14,  14, 142, 254,   0,   0,   0,   0
  1449.                DB      0,   0,   0, 254,  48,  48,  56,  56
  1450.                DB     56,  56,  56,  56,   0,   0,   0,   0
  1451.                DB      0,   0,   0, 194, 194, 194, 226, 226
  1452.                DB    226, 226, 226, 254,   0,   0,   0,   0
  1453.                DB      0,   0,   0, 226, 226, 226, 226, 226
  1454.                DB    226, 102, 100, 124,   0,   0,   0,   0
  1455. ;               DB      0,   0,   0, 230, 230, 230, 214, 214  ; W orig.
  1456. ;               DB    214, 214, 214, 238,   0,   0,   0,   0
  1457.                DB      0,   0,   0, 198, 198, 198, 214, 214   ; W modif.
  1458.                DB    214, 214, 214, 238,   0,   0,   0,   0
  1459.                DB      0,   0,   0, 194, 194, 194, 124, 226
  1460.                DB    226, 226, 226, 226,   0,   0,   0,   0
  1461.                DB      0,   0,   0, 130, 130, 130, 254,  56
  1462.                DB     56,  56,  56,  56,   0,   0,   0,   0
  1463.                DB      0,   0,   0, 254, 134,   6, 254, 224
  1464.                DB    224, 224, 226, 254,   0,   0,   0,   0
  1465.                DB      0,   0,  14,   8,   8,   8,   8,   8
  1466.                DB      8,   8,   8,   8,  14,   0,   0,   0
  1467.                DB      0,   0,   0, 128, 128, 128, 128, 254
  1468.                DB     14,  14,  14,  14,   0,   0,   0,   0
  1469.                DB      0,   0, 112,  16,  16,  16,  16,  16
  1470.                DB     16,  16,  16,  16, 112,   0,   0,   0
  1471.                DB      0,   0,  60,  36,  36,   0,   0,   0
  1472.                DB      0,   0,   0,   0,   0,   0,   0,   0
  1473.                DB      0,   0,   0,   0,   0,   0,   0,   0
  1474.                DB      0,   0,   0,   0,   0, 255,   0,   0
  1475.                DB      0,   0,  32,  56,  56,   0,   0,   0
  1476.                DB      0,   0,   0,   0,   0,   0,   0,   0
  1477.                DB      0,   0,   0,   0,   0, 124,  68,   4
  1478.                DB    126, 102, 102, 126,   0,   0,   0,   0
  1479.                DB      0,   0,   0,  96,  96, 126,  98,  98
  1480.                DB     98, 114, 114, 126,   0,   0,   0,   0
  1481.                DB      0,   0,   0,   0,   0, 126,  98,  96
  1482.                DB    112, 112, 114, 126,   0,   0,   0,   0
  1483.                DB      0,   0,   0,   6,   6, 126,  70,  70
  1484.                DB     78,  78,  78, 126,   0,   0,   0,   0
  1485.                DB      0,   0,   0,   0,   0, 126,  98,  98
  1486.                DB    126, 112, 114, 126,   0,   0,   0,   0
  1487.                DB      0,   0,   0,  28,  16,  60,  24,  24
  1488.                DB     28,  28,  28,  28,   0,   0,   0,   0
  1489.                DB      0,   0,   0,   0,   0, 126,  98,  98
  1490.                DB    114, 114, 114, 126,   2,   2, 126,   0
  1491.                DB      0,   0,   0,  96,  96, 126,  98,  98
  1492.                DB    114, 114, 114, 114,   0,   0,   0,   0
  1493.                DB      0,   0,   0,  24,  24,   0,  16,  16
  1494.                DB     24,  24,  24,  24,   0,   0,   0,   0
  1495.                DB      0,   0,   0,  24,  24,   0,  16,  16
  1496.                DB     24,  24,  24,  24,   8,   8,  24,   0
  1497.                DB      0,   0,   0,  96,  96, 100, 100, 100
  1498.                DB    126, 114, 114, 114,   0,   0,   0,   0
  1499.                DB      0,   0,   0,  48,  48,  48,  48,  48
  1500.                DB     56,  56,  56,  56,   0,   0,   0,   0
  1501.                DB      0,   0,   0,   0,   0, 254, 146, 146
  1502.                DB    218, 218, 218, 218,   0,   0,   0,   0
  1503.                DB      0,   0,   0,   0,   0, 126,  98,  98
  1504.                DB    114, 114, 114, 114,   0,   0,   0,   0
  1505.                DB      0,   0,   0,   0,   0, 126,  98,  98
  1506.                DB    114, 114, 114, 126,   0,   0,   0,   0
  1507.                DB      0,   0,   0,   0,   0, 126,  98,  98
  1508.                DB    114, 114, 114, 126,  64,  64,  64,   0
  1509.                DB      0,   0,   0,   0,   0, 126,  98,  98
  1510.                DB    114, 114, 114, 126,   2,   2,   2,   0
  1511.                DB      0,   0,   0,   0,   0, 126,  96,  96
  1512.                DB    112, 112, 112, 112,   0,   0,   0,   0
  1513.                DB      0,   0,   0,   0,   0, 126,  98,  96
  1514.                DB    126,  14,  78, 126,   0,   0,   0,   0
  1515.                DB      0,   0,   0,  16,  16,  60,  24,  24
  1516.                DB     28,  28,  28,  28,   0,   0,   0,   0
  1517.                DB      0,   0,   0,   0,   0,  98,  98,  98
  1518.                DB    114, 114, 114, 126,   0,   0,   0,   0
  1519.                DB      0,   0,   0,   0,   0, 114, 114, 114
  1520.                DB    114,  54,  52,  60,   0,   0,   0,   0
  1521.                DB      0,   0,   0,   0,   0, 146, 146, 146
  1522.                DB    218, 218, 218, 238,   0,   0,   0,   0
  1523.                DB      0,   0,   0,   0,   0,  98,  98,  98
  1524.                DB     60, 114, 114, 114,   0,   0,   0,   0
  1525.                DB      0,   0,   0,   0,   0, 114, 114, 114
  1526.                DB    114,  98,  98, 126,   2,   2, 126,   0
  1527.                DB      0,   0,   0,   0,   0, 126,  70,   6
  1528.                DB    126, 112, 114, 126,   0,   0,   0,   0
  1529.                DB      0,   0,  30,  24,  24,  12,   8,  48
  1530.                DB      8,  12,  24,  24,  30,   0,   0,   0
  1531.                DB      0,   0,  24,  24,  24,  24,  24,   0
  1532.                DB     24,  24,  24,  24,  24,   0,   0,   0
  1533.                DB      0,   0, 120,  24,  24,  48,  16,  12
  1534.                DB     16,  48,  24,  24, 120,   0,   0,   0
  1535.                DB      0,   0,   0,   0,   0, 118, 220,   0
  1536.                DB      0,   0,   0,   0,   0,   0,   0,   0
  1537.                DB      0,   0,   0,   0,   0,  16,  56, 108
  1538.                DB    198, 198, 254,   0,   0,   0,   0,   0
  1539.                DB      0,   0,   0, 254, 194, 192, 192, 224
  1540.                DB    224, 224, 226, 254,   8,  14,  98, 126
  1541.                DB      0,   0, 102,   0,   0,  98,  98,  98
  1542.                DB    114, 114, 114, 126,   0,   0,   0,   0
  1543.                DB      0,  12,   8,  16,   0, 126,  98,  98
  1544.                DB    126, 112, 114, 126,   0,   0,   0,   0
  1545.                DB      0,  16,  56, 100,   0, 124,  68,   4
  1546.                DB    126, 102, 102, 126,   0,   0,   0,   0
  1547.                DB      0,   0, 102,   0,   0, 124,  68,   4
  1548.                DB    126, 102, 102, 126,   0,   0,   0,   0
  1549.                DB      0,  48,  16,   8,   0, 124,  68,   4
  1550.                DB    126, 102, 102, 126,   0,   0,   0,   0
  1551.                DB      0, 124, 100, 124,   0, 124,  68,   4
  1552.                DB    126, 102, 102, 126,   0,   0,   0,   0
  1553.                DB      0,   0,   0,   0,   0, 126,  98,  96
  1554.                DB    112, 112, 114, 126,   8,  14,  98, 126
  1555.                DB      0,  16,  56, 100,   0, 126,  98,  98
  1556.                DB    126, 112, 114, 126,   0,   0,   0,   0
  1557.                DB      0,   0, 102,   0,   0, 126,  98,  98
  1558.                DB    126, 112, 114, 126,   0,   0,   0,   0
  1559.                DB      0,  48,  16,   8,   0, 126,  98,  98
  1560.                DB    126, 112, 114, 126,   0,   0,   0,   0
  1561.                DB      0,   0, 102,   0,   0,   0,  16,  16
  1562.                DB     24,  24,  24,  24,   0,   0,   0,   0
  1563.                DB      0,  16,  56, 100,   0,   0,  16,  16
  1564.                DB     24,  24,  24,  24,   0,   0,   0,   0
  1565.                DB      0,  48,  16,   8,   0,   0,  16,  16
  1566.                DB     24,  24,  24,  24,   0,   0,   0,   0
  1567.                DB      0, 204,   0, 124, 100, 100, 254, 226
  1568.                DB    226, 226, 226, 226,   0,   0,   0,   0
  1569.                DB    124, 100, 124,   0, 124, 100, 100, 254
  1570.                DB    226, 226, 226, 226,   0,   0,   0,   0
  1571.                DB     12,   8,  16, 254, 192, 192, 192, 254
  1572.                DB    224, 224, 224, 254,   0,   0,   0,   0
  1573.                DB      0,   0,   0,   0,   0, 255, 153,  25
  1574.                DB    255, 220, 221, 255,   0,   0,   0,   0
  1575.                DB      0,   0,   0, 127,  72,  72, 252, 207
  1576.                DB    204, 204, 204, 207,   0,   0,   0,   0
  1577.                DB      0,  16,  56, 100,   0, 126,  98,  98
  1578.                DB    114, 114, 114, 126,   0,   0,   0,   0
  1579.                DB      0,   0, 102,   0,   0, 126,  98,  98
  1580.                DB    114, 114, 114, 126,   0,   0,   0,   0
  1581.                DB      0,  48,  16,   8,   0, 126,  98,  98
  1582.                DB    114, 114, 114, 126,   0,   0,   0,   0
  1583.                DB      0,  16,  56, 100,   0,  98,  98,  98
  1584.                DB    114, 114, 114, 126,   0,   0,   0,   0
  1585.                DB      0,  48,  16,   8,   0,  98,  98,  98
  1586.                DB    114, 114, 114, 126,   0,   0,   0,   0
  1587.                DB      0,   0, 102,   0,   0, 114, 114, 114
  1588.                DB    114,  98,  98, 126,   2,   2, 126,   0
  1589.                DB      0, 204,   0, 254, 142, 134, 134, 134
  1590.                DB    134, 134, 134, 254,   0,   0,   0,   0
  1591.                DB      0, 102,   0, 194, 194, 194, 226, 226
  1592.                DB    226, 226, 226, 254,   0,   0,   0,   0
  1593.                DB      0,   0,  24,  24,  24, 126,  98, 112
  1594.                DB    114, 126,  24,  24,  24,   0,   0,   0
  1595.                DB      0,   0,   0,  28,  54,  48,  48, 124
  1596.                DB     48,  48, 102, 252,   0,   0,   0,   0
  1597.                DB      0,   0,   0, 102, 102,  60,  24, 126
  1598.                DB     24, 126,  24,  24,   0,   0,   0,   0
  1599.                DB      0,   0,   0, 252, 196, 196, 252, 228
  1600.                DB    238, 228, 230, 230,   0,   0,   0,   0
  1601.                DB      0,  14,  27,  24,  24,  24,  24, 126
  1602.                DB     24,  24,  24,  24,  24, 216, 112,   0
  1603.                DB      0,  12,   8,  16,   0, 124,  68,   4
  1604.                DB    126, 102, 102, 126,   0,   0,   0,   0
  1605.                DB      0,  12,   8,  16,   0,   0,  16,  16
  1606.                DB     24,  24,  24,  24,   0,   0,   0,   0
  1607.                DB      0,  12,   8,  16,   0, 126,  98,  98
  1608.                DB    114, 114, 114, 126,   0,   0,   0,   0
  1609.                DB      0,  12,   8,  16,   0,  98,  98,  98
  1610.                DB    114, 114, 114, 126,   0,   0,   0,   0
  1611.                DB      0,   0, 118, 220,   0, 126,  98,  98
  1612.                DB    114, 114, 114, 114,   0,   0,   0,   0
  1613.                DB    118, 220,   0, 254, 194, 194, 226, 226
  1614.                DB    226, 226, 226, 226,   0,   0,   0,   0
  1615.                DB      0, 124,  68,   4, 126, 102, 126,   0
  1616.                DB    126,   0,   0,   0,   0,   0,   0,   0
  1617.                DB      0, 126,  98,  98, 114, 114, 126,   0
  1618.                DB    126,   0,   0,   0,   0,   0,   0,   0
  1619.                DB      0,   0,   0,  28,  28,   0,  28,  28
  1620.                DB    252, 192, 194, 254,   0,   0,   0,   0
  1621.                DB      0,   0,   0,   0,   0,   0,   0, 254
  1622.                DB    192, 192, 192,   0,   0,   0,   0,   0
  1623.                DB      0,   0,   0,   0,   0,   0,   0, 254
  1624.                DB      6,   6,   6,   0,   0,   0,   0,   0
  1625.                DB      0,  48,  49, 113, 113, 113,   1, 255
  1626.                DB    224, 239, 227, 239, 236,  15,   0,   0
  1627.                DB      0,  48,  49, 113, 113, 113,   1, 255
  1628.                DB    224, 235, 235, 235, 239,   3,   0,   0
  1629.                DB      0,   0,   0,  56,   0,  56,  56,  56
  1630.                DB     24,  24,  24,  24,   0,   0,   0,   0
  1631.                DB      0,   0,   0,   0,   0,  51, 102, 204
  1632.                DB    102,  51,   0,   0,   0,   0,   0,   0
  1633.                DB      0,   0,   0,   0,   0, 204, 102,  51
  1634.                DB    102, 204,   0,   0,   0,   0,   0,   0
  1635.                DB     68,  17,  68,  17,  68,  17,  68,  17
  1636.                DB     68,  17,  68,  17,  68,  17,  68,  17
  1637.                DB    170,  85, 170,  85, 170,  85, 170,  85
  1638.                DB    170,  85, 170,  85, 170,  85, 170,  85
  1639.                DB    119, 221, 119, 221, 119, 221, 119, 221
  1640.                DB    119, 221, 119, 221, 119, 221, 119, 221
  1641.                DB     24,  24,  24,  24,  24,  24,  24,  24
  1642.                DB     24,  24,  24,  24,  24,  24,  24,  24
  1643.                DB     24,  24,  24,  24,  24,  24,  24, 248
  1644.                DB     24,  24,  24,  24,  24,  24,  24,  24
  1645.                DB     24,  24,  24,  24,  24,  24, 248,  24
  1646.                DB    248,  24,  24,  24,  24,  24,  24,  24
  1647.                DB     54,  54,  54,  54,  54,  54,  54, 246
  1648.                DB     54,  54,  54,  54,  54,  54,  54,  54
  1649.                DB      0,   0,   0,   0,   0,   0,   0, 254
  1650.                DB     54,  54,  54,  54,  54,  54,  54,  54
  1651.                DB      0,   0,   0,   0,   0,   0, 248,  24
  1652.                DB    248,  24,  24,  24,  24,  24,  24,  24
  1653.                DB     54,  54,  54,  54,  54,  54, 246,   6
  1654.                DB    246,  54,  54,  54,  54,  54,  54,  54
  1655.                DB     54,  54,  54,  54,  54,  54,  54,  54
  1656.                DB     54,  54,  54,  54,  54,  54,  54,  54
  1657.                DB      0,   0,   0,   0,   0,   0, 254,   6
  1658.                DB    246,  54,  54,  54,  54,  54,  54,  54
  1659.                DB     54,  54,  54,  54,  54,  54, 246,   6
  1660.                DB    254,   0,   0,   0,   0,   0,   0,   0
  1661.                DB     54,  54,  54,  54,  54,  54,  54, 254
  1662.                DB      0,   0,   0,   0,   0,   0,   0,   0
  1663.                DB     24,  24,  24,  24,  24,  24, 248,  24
  1664.                DB    248,   0,   0,   0,   0,   0,   0,   0
  1665.                DB      0,   0,   0,   0,   0,   0,   0, 248
  1666.                DB     24,  24,  24,  24,  24,  24,  24,  24
  1667.                DB     24,  24,  24,  24,  24,  24,  24,  31
  1668.                DB      0,   0,   0,   0,   0,   0,   0,   0
  1669.                DB     24,  24,  24,  24,  24,  24,  24, 255
  1670.                DB      0,   0,   0,   0,   0,   0,   0,   0
  1671.                DB      0,   0,   0,   0,   0,   0,   0, 255
  1672.                DB     24,  24,  24,  24,  24,  24,  24,  24
  1673.                DB     24,  24,  24,  24,  24,  24,  24,  31
  1674.                DB     24,  24,  24,  24,  24,  24,  24,  24
  1675.                DB      0,   0,   0,   0,   0,   0,   0, 255
  1676.                DB      0,   0,   0,   0,   0,   0,   0,   0
  1677.                DB     24,  24,  24,  24,  24,  24,  24, 255
  1678.                DB     24,  24,  24,  24,  24,  24,  24,  24
  1679.                DB     24,  24,  24,  24,  24,  24,  31,  24
  1680.                DB     31,  24,  24,  24,  24,  24,  24,  24
  1681.                DB     54,  54,  54,  54,  54,  54,  54,  55
  1682.                DB     54,  54,  54,  54,  54,  54,  54,  54
  1683.                DB     54,  54,  54,  54,  54,  54,  55,  48
  1684.                DB     63,   0,   0,   0,   0,   0,   0,   0
  1685.                DB      0,   0,   0,   0,   0,   0,  63,  48
  1686.                DB     55,  54,  54,  54,  54,  54,  54,  54
  1687.                DB     54,  54,  54,  54,  54,  54, 247,   0
  1688.                DB    255,   0,   0,   0,   0,   0,   0,   0
  1689.                DB      0,   0,   0,   0,   0,   0, 255,   0
  1690.                DB    247,  54,  54,  54,  54,  54,  54,  54
  1691.                DB     54,  54,  54,  54,  54,  54,  55,  48
  1692.                DB     55,  54,  54,  54,  54,  54,  54,  54
  1693.                DB      0,   0,   0,   0,   0,   0, 255,   0
  1694.                DB    255,   0,   0,   0,   0,   0,   0,   0
  1695.                DB     54,  54,  54,  54,  54,  54, 247,   0
  1696.                DB    247,  54,  54,  54,  54,  54,  54,  54
  1697.                DB     24,  24,  24,  24,  24,  24, 255,   0
  1698.                DB    255,   0,   0,   0,   0,   0,   0,   0
  1699.                DB     54,  54,  54,  54,  54,  54,  54, 255
  1700.                DB      0,   0,   0,   0,   0,   0,   0,   0
  1701.                DB      0,   0,   0,   0,   0,   0, 255,   0
  1702.                DB    255,  24,  24,  24,  24,  24,  24,  24
  1703.                DB      0,   0,   0,   0,   0,   0,   0, 255
  1704.                DB     54,  54,  54,  54,  54,  54,  54,  54
  1705.                DB     54,  54,  54,  54,  54,  54,  54,  63
  1706.                DB      0,   0,   0,   0,   0,   0,   0,   0
  1707.                DB     24,  24,  24,  24,  24,  24,  31,  24
  1708.                DB     31,   0,   0,   0,   0,   0,   0,   0
  1709.                DB      0,   0,   0,   0,   0,   0,  31,  24
  1710.                DB     31,  24,  24,  24,  24,  24,  24,  24
  1711.                DB      0,   0,   0,   0,   0,   0,   0,  63
  1712.                DB     54,  54,  54,  54,  54,  54,  54,  54
  1713.                DB     54,  54,  54,  54,  54,  54,  54, 255
  1714.                DB     54,  54,  54,  54,  54,  54,  54,  54
  1715.                DB     24,  24,  24,  24,  24,  24, 255,  24
  1716.                DB    255,  24,  24,  24,  24,  24,  24,  24
  1717.                DB     24,  24,  24,  24,  24,  24,  24, 248
  1718.                DB      0,   0,   0,   0,   0,   0,   0,   0
  1719.                DB      0,   0,   0,   0,   0,   0,   0,  31
  1720.                DB     24,  24,  24,  24,  24,  24,  24,  24
  1721.                DB    255, 255, 255, 255, 255, 255, 255, 255
  1722.                DB    255, 255, 255, 255, 255, 255, 255, 255
  1723.                DB      0,   0,   0,   0,   0,   0,   0,   0
  1724.                DB    255, 255, 255, 255, 255, 255, 255, 255
  1725.                DB    240, 240, 240, 240, 240, 240, 240, 240
  1726.                DB    240, 240, 240, 240, 240, 240, 240, 240
  1727.                DB     15,  15,  15,  15,  15,  15,  15,  15
  1728.                DB     15,  15,  15,  15,  15,  15,  15,  15
  1729.                DB    255, 255, 255, 255, 255, 255, 255, 255
  1730.                DB      0,   0,   0,   0,   0,   0,   0,   0
  1731.                DB      0,   0,   0,   0,   0,   0, 115, 222
  1732.                DB    204, 204, 222, 115,   0,   0,   0,   0
  1733.                DB      0,   0,   0, 252, 196, 196, 206, 226
  1734.                DB    226, 226, 234, 238, 128, 128, 128,   0
  1735.                DB      0,   0,   0, 126, 102,  96,  96,  96
  1736.                DB     96,  96,  96,  96,   0,   0,   0,   0
  1737.                DB      0,   0,   0,   0,   0, 254, 108, 108
  1738.                DB    108, 108, 108, 108,   0,   0,   0,   0
  1739.                DB      0,   0,   0, 126, 102,  48,  24,  12
  1740.                DB     24,  48, 102, 126,   0,   0,   0,   0
  1741.                DB      0,   0,   0,   0,   0,   0, 126, 216
  1742.                DB    216, 216, 216, 112,   0,   0,   0,   0
  1743.                DB      0,   0,   0,   0,   0, 102, 102, 102
  1744.                DB    102, 124,  96,  96,  96, 192,   0,   0
  1745.                DB      0,   0,   0,   0,   0, 118, 220,  24
  1746.                DB     24,  24,  24,  24,   0,   0,   0,   0
  1747.                DB      0,   0,   0, 126,  24,  60, 102, 102
  1748.                DB    102,  60,  24, 126,   0,   0,   0,   0
  1749.                DB      0,   0,   0,  60, 102, 102, 102, 126
  1750.                DB    102, 102, 102,  60,   0,   0,   0,   0
  1751.                DB      0,   0,   0,   0,   0,  56, 108, 198
  1752.                DB    198, 108, 108, 238,   0,   0,   0,   0
  1753.                DB      0,   0,   0,  30,  48,  24,  12,  62
  1754.                DB    102, 102, 102,  60,   0,   0,   0,   0
  1755.                DB      0,   0,   0,   0,   0,   0, 110, 219
  1756.                DB    219, 118,   0,   0,   0,   0,   0,   0
  1757.                DB      0,   0,   0,   0,   0,  12,  56, 108
  1758.                DB    124, 108,  56,  96,   0,   0,   0,   0
  1759.                DB      0,   0,   0,  28,  48,  96,  96, 120
  1760.                DB     96,  96,  48,  28,   0,   0,   0,   0
  1761.                DB      0,   0,   0,   0,  60, 102, 102, 102
  1762.                DB    102, 102, 102, 102,   0,   0,   0,   0
  1763.                DB      0,   0,   0,   0,   0,   0, 126,   0
  1764.                DB    126,   0, 126,   0,   0,   0,   0,   0
  1765.                DB      0,   0,   0,   0,   0,  24,  24, 126
  1766.                DB     24,  24,   0, 126,   0,   0,   0,   0
  1767.                DB      0,   0,   0,  48,  24,  12,   6,  12
  1768.                DB     24,  48,   0, 126,   0,   0,   0,   0
  1769.                DB      0,   0,   0,  12,  24,  48,  96,  48
  1770.                DB     24,  12,   0, 126,   0,   0,   0,   0
  1771.                DB      0,   0,   0,  14,  27,  27,  24,  24
  1772.                DB     24,  24,  24,  24,  24,  24,  24,  24
  1773.                DB     24,  24,  24,  24,  24,  24,  24,  24
  1774.                DB     24, 216, 216, 112,   0,   0,   0,   0
  1775.                DB      0,   0,   0,   0,   0,  24,   0,   0
  1776.                DB    126,   0,   0,  24,   0,   0,   0,   0
  1777.                DB      0,   0,   0,   0,   0,   0, 118, 220
  1778.                DB      0, 118, 220,   0,   0,   0,   0,   0
  1779.                DB      0,   0,  56, 108, 108,  56,   0,   0
  1780.                DB      0,   0,   0,   0,   0,   0,   0,   0
  1781.                DB      0,   0,   0,   0,   0,   0,   0,  24
  1782.                DB     24,   0,   0,   0,   0,   0,   0,   0
  1783.                DB      0,   0,   0,   0,   0,   0,   0,   0
  1784.                DB     24,   0,   0,   0,   0,   0,   0,   0
  1785.                DB      0,  15,  12,  12,  12,  12,  12, 204
  1786.                DB    108,  60,  28,  12,   0,   0,   0,   0
  1787.                DB      0, 126,  98,  98, 114, 114, 114,   0
  1788.                DB      0,   0,   0,   0,   0,   0,   0,   0
  1789.                DB      0, 126,  70,   6, 126, 112, 126,   0
  1790.                DB      0,   0,   0,   0,   0,   0,   0,   0
  1791.                DB      0,   0,   0,   0,   0,   0,  60,  60
  1792.                DB     60,  60,  60,   0,   0,   0,   0,   0
  1793.                DB      0,   0,   0,   0,   0,   0,   0,   0
  1794.                DB      0,   0,   0,   0,   0,   0,   0,   0
  1795. _DATA          ENDS
  1796.  
  1797.                END
  1798.