home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / Samples / CSAPE32.ARJ / SOURCE / OWLSCR / PCVSCAN.ASM < prev    next >
Encoding:
Assembly Source File  |  1990-11-01  |  15.3 KB  |  708 lines

  1. ; pcvscan.asm
  2. ;
  3. ; 5/5/88 by Ted
  4. ;
  5. ; Low Level RAM functions for OWL
  6. ;
  7. ; OWL-PCA 1.2
  8. ; Copyright (c) 1988, 1989, Oakland Group Inc.
  9. ; ALL RIGHTS RESERVED
  10. ;
  11. ;------------------------REVISION HISTORY--------------------------------------;
  12. ; 10/15/89 ted    Changed to capture in only 12 colors in 4-plane modes.
  13. ;  6/06/90 ted    Moved dummyabort to the top to satisfy brain-damaged masm 5.1.
  14. ;------------------------------------------------------------------------------;
  15. include    PCDECL.MAC
  16.  
  17.     PSEG
  18. ;------------------------------------------------------------------------------;
  19. EGA_LINEBYTES    equ 320/8
  20.  
  21. VGA_LINEBYTES    equ 320
  22.  
  23. VIA_LINES        equ    240
  24. VIA_LINEWORDS    equ    320
  25. VIA_LINEBYTES    equ    640
  26. VIA_BANKSIZE    equ 1024
  27.  
  28. VIAQUICKMASK    equ 1111011111011110b    ; knocks out low bits of r, g, and b
  29.  
  30.     tbuf        db 8 dup(0)
  31.     planes        dd 4 dup(0)
  32.     nplanes        dw 0
  33.     abort        dd 0
  34.     progdseg    dw 0
  35.  
  36.     DevLineByteso2        db  0
  37.     DevLineBytesx1        dw  0
  38.     DevLineBytesx2        dw  0
  39.     DevLineBytesx3        dw  0
  40.     DevLineBytesx6        dw  0
  41.     Pix64set            dw  0
  42.     DevLineBytesxLines    dw  0
  43.  
  44. ;;    testpix        dw 0        ;;! debug
  45.  
  46. ;------------------------------------------------------------------------------;
  47. dummyabort proc far
  48.     xor ax, ax
  49.     ret
  50. dummyabort endp
  51. ;------------------------------------------------------------------------------;
  52. ; via_evgacapture(unsigned viaseg, unsigned viareg,
  53. ;                 byte **pmplanes, int pmnplanes,
  54. ;                 boolean (*abortfunc)(void), int lines)
  55. ; write into pixmap planes the grey value of each VIA pixel.
  56. ; NOTE: THE PIXMAP MUST BE 1, 2 OR 4 PLANES,
  57. ; 320 x 240 pixels = 80 x 240 bytes IF lines IS 240, OR
  58. ; 320 x 200 pixels = 80 x 200 bytes IF lines IS 200, OR
  59. ; 320 x 120 pixels = 80 x 120 bytes IF lines IS 120, OR
  60. ; NOTE ALSO: ONLY FAR_PROC MEMORY MODELS SUPPORTED
  61.  
  62. pubproc via_evgacapture <viaseg, viareg, pmplanes, dptr, pmnplanes, abortfunc, cptr, lines>
  63.     push bp
  64.     mov bp, sp
  65.  
  66.     pushm <ds, es, di, si>
  67.  
  68.     mov ax, [bp].pmnplanes
  69.     mov cs:nplanes, ax
  70.  
  71.     les cx, [bp].abortfunc
  72.     mov dx, es
  73.     or dx, cx
  74.     mov dx, es
  75.     jnz saveab
  76.     mov cx, offset dummyabort
  77.     mov dx, seg dummyabort
  78. saveab:
  79.     mov word ptr cs:abort, cx
  80.     mov word ptr cs:abort+2, dx
  81.  
  82.     mov progdseg, ds
  83.  
  84. IF FAR_DATA
  85.     lds bx, [bp].pmplanes
  86. ELSE
  87.     mov bx, [bp].pmplanes
  88. ENDIF
  89.     mov ax, ds
  90.     cmp cs:nplanes, 1
  91.     jne multiplanes
  92.         mov word ptr cs:planes, bx
  93.         mov word ptr cs:planes+2, ax
  94.     jmp short setvia
  95. multiplanes:
  96.         mov es, ax
  97.  
  98. IF FAR_DATA
  99.         lds dx, es:[bx+0*4]
  100. ELSE
  101.         mov dx, es:[bx+0*2]
  102. ENDIF
  103.         mov word ptr cs:planes+0*4, dx
  104.         mov ax, ds
  105.         mov word ptr cs:planes+0*4+2, ax
  106.         
  107. IF FAR_DATA
  108.         lds dx, es:[bx+1*4]
  109. ELSE
  110.         mov dx, es:[bx+1*2]
  111. ENDIF
  112.         mov word ptr cs:planes+1*4, dx
  113.         mov ax, ds
  114.         mov word ptr cs:planes+1*4+2, ax
  115.         
  116. ;it's easier to just load 'em up than to test nplanes and quit
  117.  
  118. IF FAR_DATA
  119.         lds dx, es:[bx+2*4]
  120. ELSE
  121.         mov dx, es:[bx+2*2]
  122. ENDIF
  123.         mov word ptr cs:planes+2*4, dx
  124.         mov ax, ds
  125.         mov word ptr cs:planes+2*4+2, ax
  126.         
  127. IF FAR_DATA
  128.         lds dx, es:[bx+3*4]
  129. ELSE
  130.         mov dx, es:[bx+3*2]
  131. ENDIF
  132.         mov word ptr cs:planes+3*4, dx
  133.         mov ax, ds
  134.         mov word ptr cs:planes+3*4+2, ax
  135. setvia:
  136.     mov ax, [bp].viaseg        ; get via address segment in ds
  137.     mov ds, ax
  138.  
  139.     mov cs:DevLineByteso2, EGA_LINEBYTES/2
  140.     mov cs:DevLineBytesx1, EGA_LINEBYTES
  141.     mov cs:DevLineBytesx2, EGA_LINEBYTES*2
  142.     mov cs:DevLineBytesx3, EGA_LINEBYTES*3
  143.     mov cs:DevLineBytesx6, EGA_LINEBYTES*6
  144.     mov cs:Pix64set, 64/8
  145.  
  146.     mov cs:DevLineBytesxLines, EGA_LINEBYTES*120
  147.     cmp word ptr [bp].lines, 120
  148.     je linesset
  149.         mov cs:DevLineBytesxLines, EGA_LINEBYTES*200
  150.     cmp word ptr [bp].lines, 200
  151.     je linesset
  152.         mov cs:DevLineBytesxLines, EGA_LINEBYTES*240
  153. linesset:
  154.  
  155.     cmp cs:nplanes, 4
  156.     jne not4pl
  157.     mov dx, offset evga4pix    ; pixfunc
  158.     jmp short donepl
  159. not4pl:
  160.     mov dx, offset evgapix    ; pixfunc
  161. donepl:
  162.     call via_domatch
  163.     mov ax, 0
  164.     adc ax, 0                ; return 1 if carry set indicates user abort
  165.  
  166.     popm <si, di, es, ds>
  167.     pop bp
  168.     ret
  169. endproc via_evgacapture
  170. ;------------------------------------------------------------------------------;
  171. ; via_mcgacapture(unsigned viaseg, unsigned viareg,
  172. ;                 byte **pmplanes, int pmnplanes,
  173. ;                 boolean (*abortfunc)(void))
  174. ; write into vga pixmap the grey value of each VIA pixel.
  175. ; NOTE: THE PIXMAP MUST BE 1 PLANE, BYTE PER PIXEL, 320 x 200 pixels/bytes.
  176. ; NOTE ALSO: ONLY FAR_PROC MEMORY MODELS SUPPORTED
  177.  
  178. pubproc via_mcgacapture <viaseg, viareg, pmplanes, dptr, pmnplanes, abortfunc, cptr>
  179.     push bp
  180.     mov bp, sp
  181.  
  182.     pushm <ds, es, di, si>
  183.  
  184.     mov ax, [bp].pmnplanes
  185.     mov cs:nplanes, ax
  186.  
  187.     les cx, [bp].abortfunc
  188.     mov dx, es
  189.     or dx, cx
  190.     mov dx, es
  191.     jnz vsaveab
  192.     mov cx, offset dummyabort
  193.     mov dx, seg dummyabort
  194. vsaveab:
  195.     mov word ptr cs:abort, cx
  196.     mov word ptr cs:abort+2, dx
  197.  
  198.     mov progdseg, ds
  199.  
  200. IF FAR_DATA
  201.     lds bx, [bp].pmplanes
  202. ELSE
  203.     mov bx, [bp].pmplanes
  204. ENDIF
  205.     mov ax, ds
  206.     mov word ptr cs:planes, bx
  207.     mov es, ax
  208.  
  209.     mov ax, [bp].viaseg        ; get via address segment in ds
  210.     mov ds, ax
  211.  
  212.     mov cs:DevLineByteso2, VGA_LINEBYTES/2
  213.     mov cs:DevLineBytesx1, VGA_LINEBYTES
  214.     mov cs:DevLineBytesx2, VGA_LINEBYTES*2
  215.     mov cs:DevLineBytesx3, VGA_LINEBYTES*3
  216.     mov cs:DevLineBytesx6, VGA_LINEBYTES*6
  217.     mov cs:Pix64set, 64
  218.     mov cs:DevLineBytesxLines, VGA_LINEBYTES*200
  219.  
  220.     mov dx, offset mcgapix    ; pixfunc
  221.     call via_domatch
  222.     mov ax, 0
  223.     adc ax, 0                ; return 1 if carry set indicates user abort
  224.  
  225.     popm <si, di, es, ds>
  226.     pop bp
  227.     ret
  228. endproc via_mcgacapture
  229. ;------------------------------------------------------------------------------;
  230.  
  231. igroup    equ BL ; current group of 4 interlaced sets of via lines
  232. bank    equ BH ; currently selected bank of via memory
  233. goffs    equ CX ; offset of current pixel in current group on vga
  234. boffs    equ SI ; offset of current pixel in current bank
  235. ooffs    equ DI ; offset of current pixel in output pixmap
  236. iline    equ AH ; (current line in group + init val) mod 3 (says when to skip a line)
  237. iblock    equ AL ; current block in line out of 5 (from -1 to 4)
  238. ;viaseg    equ DS ; segment address of via registers and memory bank.
  239. ;pmseg    equ ES ; segment address of vga pixbuf.
  240.  
  241. via_domatch proc
  242.  
  243.     cld
  244.     mov igroup, 0
  245. grouploop:
  246.     mov al, cs:DevLineByteso2    ; set up starting VGA group output address;
  247.     mul igroup                    ; starting ooffs = igroup * DevLineBytes
  248.     shl ax, 1
  249.     cmp DevLineByteso2, VGA_LINEBYTES/2    ; if vga, add plane addr to ooffs
  250.     jne novga                    ; because we're going to blast right through
  251.         add ax, word ptr cs:planes    ; start offset of pixbuf in es:
  252. novga:
  253.     mov ooffs, ax
  254.  
  255.     cmp cs:DevLineBytesxLines, EGA_LINEBYTES*120
  256.     jne not120
  257.         shl igroup, 1    ; double the group to skip group 1 for 120 lines
  258. not120:
  259.     cmp igroup, 3
  260.     jbe notdone
  261.     jmp  doneimage        ; note: if we jump here, cf=0
  262. notdone:
  263.  
  264.     mov si, [bp].viareg            ; si is boffs so we can trash it
  265.     mov bank, igroup
  266.     mov ds:[si], bank            ; set bank switch
  267.  
  268.     mov goffs, 0
  269.     mov boffs, 0
  270.  
  271.     mov iline, igroup
  272.     shr iline, 1
  273.     xor iline, 1            ; set iline to 2 in groups 0,1; 1 in groups 2,3
  274.     inc iline
  275.  
  276.     mov iblock, 5
  277.  
  278. offsloop:
  279.         call dx    ;pixfunc        ; Do whatever with 64 pixels in pix
  280.         add goffs, cs:Pix64set    ; boffs and ooffs are done in pixfunc.
  281.  
  282.         dec iblock                ; fall through to lineend when we get to 5
  283.         jnz  midline
  284.     lineend:
  285.             mov iblock, 5
  286.  
  287.             cmp cs:DevLineBytesxLines, EGA_LINEBYTES*240
  288.             je img240
  289.             cmp cs:DevLineBytesxLines, EGA_LINEBYTES*120
  290.             je img120
  291. ;--------------
  292.         img200:
  293.                 inc iline
  294.                 cmp iline, 3
  295.                 jb skip3
  296.             skip4:
  297.                     test igroup, 1
  298.                     jz noskip                ; only skip 3rd via line in groups 1,3
  299.                         mov iline, 1
  300.                         add boffs, VIA_LINEBYTES    ; ignore one via line
  301.                         add ooffs, cs:DevLineBytesx6    ; skip to next-next vga line
  302.                     jmp short doneimgx ;(doneskip4)
  303.                 noskip:
  304.                     mov iline, 0
  305.                     add ooffs, cs:DevLineBytesx3    ; skip 3 vga lines to next line in group
  306.             doneskip4:
  307.                     jmp short doneimgx
  308.             skip3:
  309.                     add ooffs, cs:DevLineBytesx2    ; skip 2 vga lines to next line in group
  310.                 jmp short doneimgx
  311. ;--------------
  312.         img240:
  313.                 add ooffs, cs:DevLineBytesx3    ; skip 3 vga lines to next line in group
  314.                 jmp short doneimgx
  315. ;--------------
  316.         img120:
  317.                 add ooffs, cs:DevLineBytesx1    ; skip 1 vga line to next line in group
  318. ;--------------
  319.     doneimgx:
  320.             cmp ooffs, cs:DevLineBytesxLines    ; test for end of this group
  321.             jb midline
  322.             jmp nextgroup
  323.     midline:
  324.         cmp boffs, VIA_BANKSIZE
  325.         jb samebank
  326.         sub boffs, VIA_BANKSIZE
  327.         add bank, 4
  328.         push si
  329.         mov si, [bp].viareg            ; si is boffs so we can trash it
  330.         mov ds:[si], bank            ; set bank switch
  331.         call checkabort            ; check for user abort (si not preserved)
  332.         pop si
  333.         jc doneimage            ; and quit if abort requested
  334. samebank:
  335.         jmp offsloop
  336. nextgroup:
  337.     inc igroup
  338.     jmp grouploop
  339. doneimage:            ; carry is set for abort; is not set on normal return
  340.     ret
  341. via_domatch endp
  342. ;------------------------------------------------------------------------------;
  343. evgapix proc
  344.     pushm <ax, bx, cx>
  345.  
  346.     mov cx, 64
  347. egaloop:
  348.     lodsw                        ; get via pixel
  349. ;; mov ax, ss:testpix            ;;! debug
  350. ;; inc ss:testpix
  351.  
  352. ; customized version of pixunpack ; Take pix in ax, end with avg grey in al
  353.     mov bh, al
  354.     and bh, 00011111b    ; 5 bit blue in bh
  355.  
  356.     shr ax, 1
  357.     shr ax, 1
  358.     mov bl, ah
  359.     and bl, 00111110b    ; add 6 bit red in bl
  360.  
  361.     add bh, bl
  362.     shr bl, 1            ; add 5 bit red from bl
  363.     add bl, bh            ; bl now has blue + 3*red
  364.  
  365.     shr ax, 1
  366.     shr al, 1
  367.     and al, 01111110b    ; 7 bit green in al
  368.     add al, bl            ; al now has blue/2 + 3*red/2 + 4*green/2 = wtd sum*8/2
  369.                         ; al is 8 bit grey value
  370.  
  371.     ; write ega pixel to buffers
  372.     dec cx
  373.     mov bx, cx
  374.     and bx, 7
  375.     mov cs:tbuf[bx], al    ; stash grey value
  376.     jnz egaloop            ; if not a group of 8, loop again
  377.  
  378.     ; save the 8 saved bytes in ega format 4 planes
  379.  
  380.     shl cs:tbuf[0], 1
  381.     rcr ah, 1
  382.     shl cs:tbuf[1], 1
  383.     rcr ah, 1
  384.     shl cs:tbuf[2], 1
  385.     rcr ah, 1
  386.     shl cs:tbuf[3], 1
  387.     rcr ah, 1
  388.     shl cs:tbuf[4], 1
  389.     rcr ah, 1
  390.     shl cs:tbuf[5], 1
  391.     rcr ah, 1
  392.     shl cs:tbuf[6], 1
  393.     rcr ah, 1
  394.     shl cs:tbuf[7], 1
  395.     rcr ah, 1
  396.  
  397.     cmp cs:nplanes, 1
  398.     ja save2
  399.     
  400.     les bx, cs:planes[0*4]
  401.     mov es:[bx+di], ah
  402.     jmp donesave
  403. save2:
  404.     shl cs:tbuf[0], 1
  405.     rcr al, 1
  406.     shl cs:tbuf[1], 1
  407.     rcr al, 1
  408.     shl cs:tbuf[2], 1
  409.     rcr al, 1
  410.     shl cs:tbuf[3], 1
  411.     rcr al, 1
  412.     shl cs:tbuf[4], 1
  413.     rcr al, 1
  414.     shl cs:tbuf[5], 1
  415.     rcr al, 1
  416.     shl cs:tbuf[6], 1
  417.     rcr al, 1
  418.     shl cs:tbuf[7], 1
  419.     rcr al, 1
  420.  
  421.     cmp cs:nplanes, 2
  422.     ja save3
  423.  
  424.     les bx, cs:planes[1*4]
  425.     mov es:[bx+di], ah
  426.     les bx, cs:planes[0*4]
  427.     mov es:[bx+di], al
  428.     jmp donesave
  429. save3:
  430.     les bx, cs:planes[3*4]
  431.     mov es:[bx+di], ah
  432.     les bx, cs:planes[2*4]
  433.     mov es:[bx+di], al
  434.  
  435.     shl cs:tbuf[0], 1
  436.     rcr ah, 1
  437.     shl cs:tbuf[1], 1
  438.     rcr ah, 1
  439.     shl cs:tbuf[2], 1
  440.     rcr ah, 1
  441.     shl cs:tbuf[3], 1
  442.     rcr ah, 1
  443.     shl cs:tbuf[4], 1
  444.     rcr ah, 1
  445.     shl cs:tbuf[5], 1
  446.     rcr ah, 1
  447.     shl cs:tbuf[6], 1
  448.     rcr ah, 1
  449.     shl cs:tbuf[7], 1
  450.     rcr ah, 1
  451.  
  452.     shl cs:tbuf[0], 1
  453.     rcr al, 1
  454.     shl cs:tbuf[1], 1
  455.     rcr al, 1
  456.     shl cs:tbuf[2], 1
  457.     rcr al, 1
  458.     shl cs:tbuf[3], 1
  459.     rcr al, 1
  460.     shl cs:tbuf[4], 1
  461.     rcr al, 1
  462.     shl cs:tbuf[5], 1
  463.     rcr al, 1
  464.     shl cs:tbuf[6], 1
  465.     rcr al, 1
  466.     shl cs:tbuf[7], 1
  467.     rcr al, 1
  468.  
  469.     les bx, cs:planes[1*4]
  470.     mov es:[bx+di], ah
  471.     les bx, cs:planes[0*4]
  472.     mov es:[bx+di], al
  473.  
  474. donesave:
  475.     inc di
  476.     jcxz done64
  477.     jmp egaloop
  478.  
  479. done64:
  480.     popm <cx, bx, ax>
  481.     ret
  482. evgapix endp
  483. ;------------------------------------------------------------------------------;
  484. evga4pix proc
  485.     pushm <ax, bx, cx>
  486.  
  487.     mov cx, 64
  488. ega4loop:
  489.     lodsw                        ; get via pixel
  490. ;; mov ax, ss:testpix            ;;! debug
  491. ;; inc ss:testpix
  492.  
  493. ; customized version of pixunpack ; Take pix in ax, end with avg grey in al
  494.     mov bh, al
  495.     and bh, 00011111b    ; 5 bit blue in bh
  496.  
  497.     shr ax, 1
  498.     shr ax, 1
  499.     mov bl, ah
  500.     and bl, 00111110b    ; add 6 bit red in bl
  501.  
  502.     add bh, bl
  503.     shr bl, 1            ; add 5 bit red from bl
  504.     add bl, bh            ; bl now has blue + 3*red
  505.  
  506.     shr ax, 1
  507.     shr al, 1
  508.     and al, 01111110b    ; 7 bit green in al
  509.     add al, bl            ; al now has blue/2 + 3*red/2 + 4*green/2 = wtd sum*8/2
  510.                         ; al is 8 bit grey value
  511.  
  512.     ; if 4 planes (16 colors):
  513.     ; multiply by 7/8 to get 14 colors, then
  514.     ;  merge 3 lowest colors into color 0 to get 12
  515.     mov ah, al
  516.     shr ah, 1
  517.     shr ah, 1
  518.     shr ah, 1
  519.     sub al, ah        ; x - x/8 = x * 7/8
  520.     cmp al, 32
  521.     ja sub32
  522.     sub al, al
  523.     jmp short done12
  524. sub32:
  525.     sub al, 32
  526. done12:
  527.  
  528.     ; write ega pixel to buffers
  529.     dec cx
  530.     mov bx, cx
  531.     and bx, 7
  532.     mov cs:tbuf[bx], al    ; stash grey value
  533.     jnz ega4loop        ; if not a group of 8, loop again
  534.  
  535.     ; save the 8 saved bytes in ega format 4 planes
  536.  
  537.     shl cs:tbuf[0], 1
  538.     rcr ah, 1
  539.     shl cs:tbuf[1], 1
  540.     rcr ah, 1
  541.     shl cs:tbuf[2], 1
  542.     rcr ah, 1
  543.     shl cs:tbuf[3], 1
  544.     rcr ah, 1
  545.     shl cs:tbuf[4], 1
  546.     rcr ah, 1
  547.     shl cs:tbuf[5], 1
  548.     rcr ah, 1
  549.     shl cs:tbuf[6], 1
  550.     rcr ah, 1
  551.     shl cs:tbuf[7], 1
  552.     rcr ah, 1
  553.  
  554.     cmp cs:nplanes, 1
  555.     ja save42
  556.     
  557.     les bx, cs:planes[0*4]
  558.     mov es:[bx+di], ah
  559.     jmp done4save
  560. save42:
  561.     shl cs:tbuf[0], 1
  562.     rcr al, 1
  563.     shl cs:tbuf[1], 1
  564.     rcr al, 1
  565.     shl cs:tbuf[2], 1
  566.     rcr al, 1
  567.     shl cs:tbuf[3], 1
  568.     rcr al, 1
  569.     shl cs:tbuf[4], 1
  570.     rcr al, 1
  571.     shl cs:tbuf[5], 1
  572.     rcr al, 1
  573.     shl cs:tbuf[6], 1
  574.     rcr al, 1
  575.     shl cs:tbuf[7], 1
  576.     rcr al, 1
  577.  
  578.     cmp cs:nplanes, 2
  579.     ja save43
  580.  
  581.     les bx, cs:planes[1*4]
  582.     mov es:[bx+di], ah
  583.     les bx, cs:planes[0*4]
  584.     mov es:[bx+di], al
  585.     jmp done4save
  586. save43:
  587.     les bx, cs:planes[3*4]
  588.     mov es:[bx+di], ah
  589.     les bx, cs:planes[2*4]
  590.     mov es:[bx+di], al
  591.  
  592.     shl cs:tbuf[0], 1
  593.     rcr ah, 1
  594.     shl cs:tbuf[1], 1
  595.     rcr ah, 1
  596.     shl cs:tbuf[2], 1
  597.     rcr ah, 1
  598.     shl cs:tbuf[3], 1
  599.     rcr ah, 1
  600.     shl cs:tbuf[4], 1
  601.     rcr ah, 1
  602.     shl cs:tbuf[5], 1
  603.     rcr ah, 1
  604.     shl cs:tbuf[6], 1
  605.     rcr ah, 1
  606.     shl cs:tbuf[7], 1
  607.     rcr ah, 1
  608.  
  609.     shl cs:tbuf[0], 1
  610.     rcr al, 1
  611.     shl cs:tbuf[1], 1
  612.     rcr al, 1
  613.     shl cs:tbuf[2], 1
  614.     rcr al, 1
  615.     shl cs:tbuf[3], 1
  616.     rcr al, 1
  617.     shl cs:tbuf[4], 1
  618.     rcr al, 1
  619.     shl cs:tbuf[5], 1
  620.     rcr al, 1
  621.     shl cs:tbuf[6], 1
  622.     rcr al, 1
  623.     shl cs:tbuf[7], 1
  624.     rcr al, 1
  625.  
  626.     les bx, cs:planes[1*4]
  627.     mov es:[bx+di], ah
  628.     les bx, cs:planes[0*4]
  629.     mov es:[bx+di], al
  630.  
  631. done4save:
  632.     inc di
  633.     jcxz done464
  634.     jmp ega4loop
  635.  
  636. done464:
  637.     popm <cx, bx, ax>
  638.     ret
  639. evga4pix endp
  640. ;------------------------------------------------------------------------------;
  641. mcgapix proc
  642.     pushm <ax, bx, cx>
  643.  
  644.     mov cx, 64
  645. bwloop:
  646.     lodsw                        ; get via pixel
  647. ;; mov ax, ss:testpix            ;;! debug
  648. ;; inc ss:testpix
  649.  
  650. ; customized version of pixunpack ; Take pix in ax, end with avg grey in al
  651.     mov bh, al
  652.     and bh, 00011111b    ; 5 bit blue in bh
  653.  
  654.     shr ax, 1
  655.     shr ax, 1
  656.     mov bl, ah
  657.     and bl, 00111110b    ; add 6 bit red in bl
  658.  
  659.     add bh, bl
  660.     shr bl, 1            ; add 5 bit red from bl
  661.     add bl, bh            ; bl now has blue + 3*red
  662.  
  663.     shr ax, 1
  664.     shr al, 1
  665.     and al, 01111110b    ; 7 bit green in al
  666.     add al, bl            ; al now has blue/2 + 3*red/2 + 4*green/2 = wtd sum*8/2
  667.  
  668.     shr al, 1
  669.     shr al, 1        ; weighted gray average = al/(8/2).
  670.  
  671.     stosb            ; write vga pixel
  672.     loop bwloop
  673.  
  674.     popm <cx, bx, ax>
  675.     ret
  676. mcgapix endp
  677. ;------------------------------------------------------------------------------;
  678. checkabort proc        ; return with carry set if user wants to abort.
  679.     push ax
  680.     push bx
  681.     push cx
  682.     push dx
  683.     push di        ; save all registers (bp is preserved, si already saved)
  684.     push ds
  685.     push es
  686.  
  687.     mov ax, progdseg    ; restore es and ds for abort call
  688.     mov es, ax
  689.     mov ds, ax
  690.  
  691.     call dword ptr cs:abort
  692.     add ax, -1    ; set carry flag if ax is non-zero
  693.  
  694.     pop es
  695.     pop ds
  696.     pop di
  697.     pop dx
  698.     pop cx
  699.     pop bx
  700.     pop ax
  701.     ret
  702. checkabort endp    
  703. ;------------------------------------------------------------------------------;
  704.     ENDPS
  705.     end
  706. ;------------------------------------------------------------------------------;
  707.  
  708.