home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / games / fr386.zip / MAND.A < prev   
Text File  |  1988-05-20  |  24KB  |  616 lines

  1. ; This file is mand.a ... DeSmet asm88 functions for fr386.c,
  2. ; a fixed-pt 386 version of Mandelbrot ....
  3. ; mandwhile.a replaces inner "while" loop of mandelbrot calculation...
  4.  
  5. ;==============386-SPECIFIC FUNCTIONS===================================
  6. ; int  mandwhile(long P, long Q, int nmax) 
  7. ; Performs all calculations for "while" loop in L.Fogg's mandel()
  8. ; function, using fixed pt math with binary pt between bits 23 and 24... 
  9. ;
  10. ; FOR: DeSmet C/asm88 small case...
  11. ;
  12. ; In REAL MODE; uses 32-bit overrides on register length and addressing to 
  13. ; gain performance of 32-bit regs and instructions...
  14. ; Returns # iterations before divergence (16-bit int returned in ax).
  15. ; Note 1/3 rd of instructions are for rounding, to get small amount extra
  16. ; accuracy; if you aren't that picky, dump these instructions for 10% or more
  17. ; extra speed...
  18. ;
  19. ; REGISTERS:            ebp     ...ytemp at top of loop, modulus_sqrd
  20. ;                                  at bottom of loop
  21. ;                   edx:eax     ...multiplication and temporary storage
  22. ;                       edi     ...P
  23. ;                       esi     ...Q
  24. ;                       ebx     ...x
  25. ;                       ecx     ...y
  26. ;
  27. ; RETURNS stopping number of iterations in ax.
  28.  
  29.  dseg
  30.  public    counter 
  31.  counter   dw   0 
  32.  cseg
  33.  public    mandwhile_ 
  34.  mandwhile_:
  35.           db 66h, 55h                      ;push ebp 
  36.          ;---get P ...
  37.           db 67h, 66h, 8Bh, 7Ch, 24h, 06h  ;mov edi,dword  [esp+6]  
  38.          ;---get Q ...
  39.           db 67h, 66h, 8Bh, 74h, 24h, 0Ah  ;mov esi,dword  [esp+10] 
  40.          ;---get nmax...
  41.           db 67h, 8Bh, 44h, 24h, 0Eh       ;mov ax,word  [esp+14]   
  42.          ;---initialize counter ... 
  43.           mov word  counter,ax    
  44.          ;---zero out x and y storage ... 
  45.           db 66h, 33h, 0DBh                ;xor ebx,ebx                
  46.           db 66h, 33h, 0C9h                ;xor ecx,ecx 
  47.           
  48.  looper:  ;---ytemp=x*y--- 
  49.           db 66h, 8Bh, 0C3h                ;mov eax,ebx 
  50.           db 66h, 0F7h, 0E9h               ;imul ecx 
  51.           db 66h, 05h, 00h, 00h, 80h, 00h  ;add eax,800000H   ;for rounding... 
  52.           db 66h, 83h, 0D2h, 00h           ;adc edx,0         ;for rounding... 
  53.           db 66h, 0Fh, 0A4h, 0C2h, 08h     ;shld edx,eax,8    ;div by 2**24...
  54.           db 66h, 8Bh, 0EAh                ;mov ebp,edx 
  55.          ;---x=x*x - y*y + P------ 
  56.           db 66h, 8Bh, 0C3h                ;mov eax,ebx 
  57.           db 66h, 0F7h, 0EBh               ;imul ebx 
  58.           db 66h, 05h, 00h, 00h, 80h, 00h  ;add eax,800000H 
  59.           db 66h, 83h, 0D2h, 00h           ;adc edx,0 
  60.           db 66h, 0Fh, 0A4h, 0C2h, 08h     ;shld edx,eax,8 
  61.           db 66h, 8Bh, 0DAh                ;mov ebx,edx 
  62.           ;--- 
  63.           db 66h, 8Bh, 0C1h                ;mov eax,ecx 
  64.           db 66h, 0F7h, 0E9h               ;imul ecx 
  65.           db 66h, 05h, 00h, 00h, 80h, 00h  ;add eax,800000H 
  66.           db 66h, 83h, 0D2h, 00h           ;adc edx,0 
  67.           db 66h, 0Fh, 0A4h, 0C2h, 08h     ;shld edx,eax,8 
  68.           db 66h, 2Bh, 0DAh                ;sub ebx,edx 
  69.           db 66h, 03h, 0DFh                ;add ebx,edi     ;add P... 
  70.          ;---y=(ytemp<<1) + Q---- 
  71.           db 66h, 0D1h, 0E5h               ;shl ebp,1 
  72.           db 66h, 03h, 0EEh                ;add ebp,esi     ;add Q... 
  73.           db 66h, 8Bh, 0CDh                ;mov ecx,ebp 
  74.          ;---modsqrd = x*x + y*y--- 
  75.           db 66h, 8Bh, 0C3h                ;mov eax,ebx 
  76.           db 66h, 0F7h, 0EBh               ;imul ebx 
  77.           db 66h, 05h, 00h, 00h, 80h, 00h  ;add eax,800000H 
  78.           db 66h, 83h, 0D2h, 00h           ;adc edx,0 
  79.           db 66h, 0Fh, 0A4h, 0C2h, 08h     ;shld edx,eax,8 
  80.           db 66h, 8Bh, 0EAh                ;mov ebp,edx 
  81.          ;--- 
  82.           db 66h, 8Bh, 0C1h                ;mov eax,ecx 
  83.           db 66h, 0F7h, 0E9h               ;imul ecx 
  84.           db 66h, 05h, 00h, 00h, 80h, 00h  ;add eax,800000H 
  85.           db 66h, 83h, 0D2h, 00h           ;adc edx,0 
  86.           db 66h, 0Fh, 0A4h, 0C2h, 08h     ;shld edx,eax,8 
  87.           db 66h, 03h, 0EAh                ;add ebp,edx 
  88.          ;---test if modsqrd > "4"---(67108864 = 4*(1 << 24))--- 
  89.           db 66h, 81h, 0FDh, 00h,00h,00h,04h  ;cmp ebp,67108864   
  90.           jae home 
  91.           dec word  counter          
  92.           jnz looper 
  93.  home:    mov ax,word  counter 
  94.           neg ax 
  95.           db 67h, 03h, 44h, 24h, 0Eh       ;add ax, word  [esp+14] 
  96.           db 66h, 5Dh                      ;pop ebp 
  97.           ret 
  98.  
  99.  
  100. ; long  muldiv(long A, int b, int c)
  101. ; Multiplies 32-bit "a" by 16-bit "b", then divides by 
  102. ; 16-bit "c" such that abs(c) >= abs(b)...NO CHECK FOR 0 DIVISOR...
  103. ;
  104. ; NOTE how DeSmet figures stack upon entry:
  105. ; 16-bit return address at sp, "A" at sp+2, b at sp+6, c at sp+8 ... 
  106. ;
  107. ; REGISTERS:            eax     ...initially holds "A"
  108. ;                       ebx     ...holds b
  109. ;                       ecx     ...holds c
  110. ;                   edx:eax     ...product A*b (before idiv)
  111. ;                    
  112. ; RETURNS long result in dx:ax.
  113.  
  114. cseg
  115. public    muldiv_
  116. muldiv_: 
  117.      db 67h,66h,8bh,44h,24h,02h        ;mov eax,dword ptr [esp+2]
  118.      db 67h,66h,0fh,0bfh,5ch,24h,06h   ;movsx ebx,word ptr [esp+6]
  119.      db 67h,66h,0fh,0bfh,4ch,24h,08h   ;movsx ecx,word ptr [esp+8]   
  120.      db 66h,0f7h,0ebh                  ;imul ebx                      
  121.      db 66h,0f7h,0f9h                  ;idiv ecx                 
  122.      db 66h,0fh,0a4h,0c2h,10h          ;shld edx,eax,16  
  123.      ret                               ;short return...
  124.  
  125.  
  126.  
  127. ;==============HERCULES GRAPHICS ROUTINES=========================
  128. ; void tmode(), gmode() 
  129. ; For hercules graphics; set text and graphics modes...
  130. ; 2-17-88 attempt to translate hercules asm to DeSmet... 
  131. dseg
  132. index     equ       03b4h
  133. cntrl     equ       03b8h
  134. scrn_on   equ       8
  135. grph      equ       2
  136. text      equ       20h
  137.  
  138. public    gtable
  139. public    ttable
  140. gtable    db        35h,2dh,2eh,07h,5bh,02h,57h,57h,02h,03h,00h,00h
  141. ttable    db        61h,50h,52h,0fh,19h,06h,19h,19h,02h,0dh,0bh,0ch
  142.  
  143. cseg
  144. public    gmode_
  145. gmode_:             push es
  146.                     push ds
  147.  
  148.                     mov al,grph
  149.                     lea si,gtable
  150.                     xor bx,bx
  151.                     mov cx,4000h
  152.                     call setmd
  153.  
  154.                     pop ds
  155.                     pop es
  156.                     ret
  157.  
  158. public    tmode_
  159. tmode_:             push es
  160.                     push ds
  161.  
  162.                     mov al,text
  163.                     lea si,ttable
  164.                     mov bx,720h
  165.                     mov cx,2000
  166.                     call setmd
  167.  
  168.                     pop ds
  169.                     pop es
  170.                     ret
  171.  
  172. public    setmd
  173. setmd:              push ds
  174.                     push es
  175.                     push ax
  176.                     push bx
  177.                     push cx
  178.  
  179.                     mov dx,cntrl
  180.                     out dx,al
  181.  
  182.                     mov ax,ds
  183.                     mov es,ax
  184.  
  185.                     mov dx,index
  186.                     mov cx,12
  187.  
  188.                     xor ah,ah
  189.  
  190.                     ;---------
  191.           parms:    mov al,ah
  192.                     out dx,al
  193.  
  194.                     inc dx
  195.                     lodsb
  196.                     out dx,al
  197.  
  198.                     inc ah
  199.                     dec dx
  200.                     loop parms
  201.                     ;---------
  202.  
  203.                     pop cx
  204.                     mov ax,0b000h
  205.                     cld
  206.  
  207.                     mov es,ax
  208.                     xor di,di
  209.                     pop ax
  210.                     rep stosw
  211.  
  212.                     mov dx,cntrl
  213.                     pop ax
  214.                     add al,scrn_on
  215.                     out dx,al
  216.  
  217.                     pop es
  218.                     pop ds
  219.                     ret
  220.  
  221. ; void hplotpt(int column, int row, int color)
  222. ; Hercules point plot routine for general 80x86...
  223. ; FOR: DeSmet c88/asm88 small case... 
  224. ; ...if(color>0) fill point; else if (color==0) blank pt; else xor pt;
  225. ; 2-16-88 quick hercules card driver to plot a point ...
  226. ; REGISTER USAGE:   AX  for mul, mask
  227. ;                   CX  for column = x
  228. ;                   DX  for row = y
  229. ;                   SI  for offset of byte to alter
  230. ;                   BX  for color
  231. ;                   DI  return address
  232. ; Asm translation of MicroC article in Dec 87/Jan 88, cf for explanation of 
  233. ; comments...
  234. ; NOTE since we only plan on running this on 386, we could turn repeated
  235. ; shr ax,1 ... etc., into shr ax,n ...though DeSmet asm88 would require
  236. ; db encoding ...
  237. ; NOTE fast return via jmp di instead of ret !!!
  238.  
  239. cseg
  240. public    hplotpt_
  241. hplotpt_:           pop di         ;return address...
  242.                     pop cx         ;column = x...
  243.                     pop dx         ;row = y...
  244.                     pop bx         ;color ...
  245.                     sub sp,6       ; DeSmet requires 
  246.  
  247.                     ;===set up segment===============
  248.                     mov ax,0B000H
  249.                     mov es,ax
  250.                     ;===end segment setup============
  251.  
  252.                     ;===calc byte_ofs================
  253.                     ;---1st calc 90*(row / 4)--------
  254.                     mov ax,dx      ;copy y...
  255.                     shr ax,1
  256.                     shr ax,1
  257.                     mov ah,90
  258.                     mul ah         ;result now in ax
  259.                     ;---2nd calc 0x2000*(row % 4)----
  260.                     mov si,dx      ;copy y...
  261.                     and si,3       ;clear all but lowest 2 bits...
  262.                     ror si,1       ;mul by 0x2000...
  263.                     ror si,1
  264.                     ror si,1       ;(mul finished)...
  265.                     ;---add results of above two calcs
  266.                     add si,ax      ;ax now free...
  267.                     ;---calc (col / 8)---------------
  268.                     mov ax,cx
  269.                     shr ax,1
  270.                     shr ax,1
  271.                     shr ax,1
  272.                     ;---sum for final byte_ofs in si
  273.                     add si,ax
  274.                     ;===end calc of byte_ofs=========
  275.  
  276.                     ;===calc mask====================
  277.                     ;---cx has col = x---------------
  278.                     not cx
  279.                     and cx,7       ;now cx = (7-(col % 8))...
  280.                     mov ax,1
  281.                     shl ax,cl      ;now al = mask ....
  282.                     ;===end mask calc================
  283.  
  284.                     ;===get and alter byte @ byte_ofs
  285.                     ;---check for color--------------
  286.                     or bx,bx
  287.                     jz blank
  288.                     js xorit
  289.                     ;---we're filling point----------
  290.                     or byte es:[si],al
  291.                     jmp di         ;short return...
  292.                     ;---we're blanking point---------
  293.           blank:    not al
  294.                     and byte es:[si],al
  295.                     jmp di         ;short return...
  296.                     ;---we're xoring pt--------------
  297.           xorit:    xor byte es:[si],al
  298.                     jmp di         ;short return...
  299.                     ;===end get and alter============
  300.  
  301. ; void is_herc()
  302. ; 2-20-88 check for presence of Hercules 720*348 card ...
  303. ; REF: L. Fogg, Jan/Feb 1988 MicroC ...
  304.  
  305. cseg
  306. public    is_herc_
  307. is_herc_:           pop di         ;return address ...
  308.                     int 11h        ;equipment check ...
  309.                     and ax,30h     ;check for mono text or herc ...
  310.                     sub ax,30h
  311.                     jnz not_there
  312.                     ;-----
  313.                     mov cx,1000h   ;test for scan result 1000h times ...
  314.                     mov dx,3bah    ;address status reg on MC6845 ...
  315.                     ;-----
  316.      test_status:   in al,dx
  317.                     and al,80h
  318.                     jnz there
  319.                     loop test_status
  320.                     ;-----
  321.      not_there:     xor ax,ax
  322.      there:         jmp di
  323.  
  324.  
  325. ;==============TEST FOR 386===============================
  326. ; int is_386()
  327. ; 2-20-88 checks for presence of 386 -- returns 0 if not found, else
  328. ; returns non-zero ...
  329. ; note short return for DeSmet asm88 small case ...
  330. ; REF: Juan E. Jimenez, Turbo Technix Jan/Feb 88, p. 55 ...
  331.  
  332. cseg
  333. public    is_386_
  334. is_386_:            pop di         ;return address ...
  335.                     pushf
  336.                     xor ax,ax
  337.                     push ax
  338.                     popf
  339.                     pushf
  340.                     pop ax
  341.                     and ax,8000h
  342.                     sub ax,8000h
  343.                     jz home2
  344.                     ;------
  345.                     mov ax,7000h   ;if here, either 286 or 386 ...
  346.                     push ax
  347.                     popf
  348.                     pushf
  349.                     pop ax
  350.                     and ax,7000h
  351.           home2:    jmp di
  352.  
  353.  
  354. ;==============DESMET KEYBOARD POLLING ROUTINES===========
  355. ; int scr_ci() and int scr_csts() 
  356. ; These functions read the keyboard; scr_ci() waits until
  357. ; a key is typed, and returns the key; scr_csts() does not wait and returns
  358. ; 0 if no key is available. Unlike DeSmet functions ci() and csts(), these
  359. ; functions can read and translate extended keyboard codes (e.g., cursors
  360. ; and function keys). NOTE these are slightly faster than scr_ci() and 
  361. ; scr_csts() given in DeSmet's optional PCIO.a file .
  362. ;
  363. ; FOR TURBO C: replace with combination of kbhit() and getch()...
  364.  
  365. dseg
  366. ; TABLES to convert (scan_code - 59) to char code...
  367. table1:               db      210          ;F1   scan= 59
  368.                       db      211          ;F2         60
  369.                       db      212          ;F3         61
  370.                       db      213          ;F4         62
  371.                       db      214          ;F5         63
  372.                       db      215          ;F6         64
  373.                       db      216          ;F7         65
  374.                       db      217          ;F8         66
  375.                       db      218          ;F9         67
  376.                       db      219          ;F10        68
  377.                       db      0            ;NumLock    69   ...not used
  378.                       db      0            ;ScrollL    70   ...not used
  379.                       db      200          ;bol_char   71
  380.                       db      30           ;up_arrow   72
  381.                       db      202          ;page_up    73
  382.                       db      0            ;grey(-)    74   ...not used
  383.                       db      29           ;left_arrow 75
  384.                       db      0            ;NumPad5    76   ...not used
  385.                       db      28           ;right_arrow77   
  386.                       db      0            ;           78   ...not used
  387.                       db      201          ;eol_char   79
  388.                       db      31           ;down_arrow 80
  389.                       db      203          ;page_down  81
  390.                       db      206          ;Insert     82
  391.                       db      207          ;Delete     83
  392. public table2
  393. table2:               db      209          ;left_word  115
  394.                       db      208          ;right_word 116
  395.                       db      205          ;end_of_file117
  396.                       db      0            ;           118   ..not used
  397.                       db      204          ;begin_file 119
  398. cseg
  399. public scr_ci_
  400. scr_ci_:                      push bp
  401.                               mov ah,0
  402.                               int 16H
  403.                               cmp al,0
  404.                               jne not_special
  405.                               mov bl,ah
  406.                               xor bh,bh
  407.                               cmp bx,114
  408.                               ja  use_table2
  409.                               sub bx,59
  410.                               mov al,byte table1[bx]
  411.                               jmp not_special
  412.         use_table2:           sub bx,115
  413.                               mov al,byte table2[bx]
  414.         not_special:          xor ah,ah
  415.                               pop bp
  416.                               ret
  417.  
  418.  
  419. public scr_csts_
  420. scr_csts_:                    push bp
  421.                               mov ah,1
  422.                               int 16H
  423.                               mov ax,0
  424.                               jz csts_over
  425.                               call scr_ci_
  426.         csts_over:            pop bp
  427.                               ret
  428.  
  429. ;==============LOG COLOR TRANSFORM===================================
  430. ; 2-20-88 transform(int iter, int switchpt) ... DeSmet asm88 ...
  431. ; for frac386.c ...
  432. ; ...returns the "color" then anded with (maxcolors-1)...
  433. ; converts the iterations returned by mand() to a log scaling, starting at 
  434. ; the switchpt. Equiv. to C coding:
  435. ; if(iter < switchpt) color = iter;
  436. ; else for(color=i=switchpt,inc=1; i<iter; i=switchpt+(inc<<=1),color++);
  437. ; ...However, 386 is so fast we need to translate to asm to get full benefit!
  438.  
  439. cseg
  440. public    transform_
  441. transform_:         pop di         ;return address...
  442.                     pop cx         ;iter...
  443.                     pop bx         ;switchpt...
  444.                     sub sp,4       ;required by DeSmet for short return...
  445.                     cmp cx,bx
  446.                     ja do_loop
  447.                     mov ax,cx
  448.                     jmp di         ;short return...
  449.                     ;------
  450.           do_loop:  mov ax,bx      ;init color (ax) with switchpt...
  451.                     mov si,1       ;si = inc...
  452.                     mov dx,bx      ;init i (dx) with switchpt...
  453.                     ;------
  454.           loopit:   cmp dx,cx      ;compare i (dx) to iter (cx)...
  455.                     jge done
  456.                     shl si,1       ;inc <<= 1...
  457.                     mov dx,bx
  458.                     add dx,si      ;i = switchpt + inc...
  459.                     inc ax
  460.                     jmp loopit 
  461.                     ;------
  462.           done:     jmp di         ;short return, color in ax...
  463.  
  464.  
  465. ;==============EGA ROUTINES==========================================
  466. ; void egapt(int x, int y, int color)
  467. ;
  468. ; EGA point plot in general 80x86 assembly language; from
  469. ; G.Entsminger's Tidbits article, Jan 88 MicroC, translated from C...
  470. ; See below for functions to turn on/off mode 16, text mode, etc...
  471. ;
  472. ; FOR: DeSmet small case c88/asm88...
  473. ;
  474. ; NOTE this is really a point XOR routine !!!
  475. ; NOTE we are using jmp di in place of ret !!!
  476. ;
  477. dseg
  478. ; define table to translate EGA default palette into pleasing sequence...
  479. trans     dw        0,8,7,15,11,3,9,1,2,10,14,6,4,12,13,5
  480. cseg
  481. public    egapt_
  482. egapt_:             mov ax,0a000h
  483.                     mov es,ax
  484.                     pop di                   ;return address...
  485.                     pop cx                   ;x...
  486.                     pop bx                   ;y...
  487.                     pop si                   ;color...
  488.                     sub sp,6                 ;DeSmet requires for jmp return...
  489.                     and si,15                ;allow only 16 colors...
  490.                     shl si,1                 ;adjust to word length...
  491.                     mov si,trans[si]         ;translate to pleasant order...
  492.                     ;---offset = y*80 + x/8---------------------
  493.                     mov ax,80
  494.                     mul bx                   ;ax=80*y, dx still empty...
  495.                     mov bx,cx                ;y into bx...
  496.                     shr bx,1
  497.                     shr bx,1
  498.                     shr bx,1
  499.                     add bx,ax                ;bx = offset = y*80 + x/8...
  500.                     ;---calc mask------------------------------
  501.                     and cx,7
  502.                     xor cx,7
  503.                     mov ch,1
  504.                     shl ch,cl               ;mask now in ch...
  505.                     ;---latch bit planes-----------------------
  506.                     mov al,es:[bx]          ;phony read...
  507.                     ;---1st four "OUTINDEXes"------------------
  508.                     mov dx,3ceh
  509.                     mov al,0
  510.                     out dx,al
  511.                     mov dx,3cfh
  512.                     mov ax,si               ;color into al...
  513.                     out dx,al
  514.  
  515.                     mov dx,3ceh
  516.                     mov al,1
  517.                     out dx,al
  518.                     mov dx,3cfh
  519.                     mov al,0fh              ;enable...
  520.                     out dx,al
  521.  
  522.                     mov dx,3ceh
  523.                     mov al,8 
  524.                     out dx,al
  525.                     mov dx,3cfh
  526.                     mov al,ch               ;mask in ch...
  527.                     out dx,al
  528.  
  529.                     mov dx,3ceh
  530.                     mov al,3
  531.                     out dx,al
  532.                     mov dx,3cfh    ;This sets xor mode...
  533.                     mov al,18h
  534.                     out dx,al
  535.  
  536.                     ;---*base &= -1;---set all bits------------
  537.                     and byte es:[bx],-1     ;set all bits...
  538.                     jmp di                  ;fast return...
  539.  
  540.  
  541. ; void egatext()
  542. ; restore write mode 0 and text mode...
  543. public    egatext_
  544. egatext_:           
  545.                     mov dx,3ceh              ;reset write mode 0...
  546.                     mov al,0 
  547.                     out dx,al
  548.                     mov dx,3cfh
  549.                     mov al,0 
  550.                     out dx,al
  551.  
  552.                     mov dx,3ceh
  553.                     mov al,1 
  554.                     out dx,al
  555.                     mov dx,3cfh
  556.                     mov al,0
  557.                     out dx,al
  558.  
  559.                     mov dx,3ceh             ;this appears to be reset 
  560.                     mov al,8                ;of write mode 1; I'm still
  561.                     out dx,al               ;not sure if this junk is needed...
  562.                     mov dx,3cfh
  563.                     mov al,-1
  564.                     out dx,al
  565.  
  566.                     mov dx,3ceh
  567.                     mov al,3
  568.                     out dx,al
  569.                     mov dx,3cfh
  570.                     mov al,0 
  571.                     out dx,al
  572.  
  573.                     mov ax,3
  574.                     int 10h
  575.                     ret
  576.  
  577. ; void mode16()
  578. ; turn on 640*350 16 color mode...
  579. public    mode16_
  580. mode16_:            mov ax,16
  581.                     int 10h
  582.                     ret
  583.  
  584.  
  585. ; is_ega()
  586. ; Test if EGA is in system; this basically stupid routine is from 
  587. ; DDJ Nov 87 p 34-35; it tests the "EGA byte", and is NOT a fool-proof
  588. ; method, since it depends on vagaries of IBM BIOS...unfortunately,
  589. ; methods that look for "IBM" characters in BIOS don't work with VGA...
  590. public    is_ega_
  591. is_ega_:            mov ax,40h
  592.                     mov es,ax
  593.                     mov bx,87h
  594.                     xor ax,ax
  595.                     mov al,byte es:[bx]
  596.                     cmp al,240              ;check for AT&T (kludge)...
  597.                     je clear
  598.                     cmp al,16               ;check for Compaq (kludge)...
  599.                     je clear
  600.                     ret
  601.      clear:         mov al,0                ;clear AT&T/Compaq byte...
  602.                     ret                     ;ax not 0 if EGA present...
  603.  
  604.  
  605.  
  606.  
  607.  
  608.  
  609.  
  610.  
  611.  
  612.  
  613.  
  614.  
  615.