home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 14 / CDACTUAL.iso / cdactual / demobin / share / program / asm / RTGRAF.ZIP / SOURCE.ZIP / EMPLOT.ASM < prev    next >
Encoding:
Assembly Source File  |  1990-06-30  |  10.3 KB  |  286 lines

  1. ;==================================================================
  2. ;
  3. ;
  4. ; egamplot(int x, int y, far *picture, far *mask, int rule);
  5. ;
  6. ;  In the following code, you will not find the creation of
  7. ;  bit mask for the left and right ends of the image, as in
  8. ;  'eplot'.  This is because the mask you supply will be used
  9. ;  to determine which bits are set.  DON'T get SLOPPY and leave
  10. ;  the right end (padding) of the bitmask as garbage, it will cause
  11. ;  probably black dits at the end of the image. Set the pad to 0s.
  12. ;
  13. ;===================================================================
  14. ;  large parms
  15. pX0    equ     [bp+6]
  16. pY0    equ     [bp+8]
  17. pIoffs equ     [bp+10]
  18. pIseg  equ     [bp+12]
  19. pMoffs equ     [bp+14]
  20. pMseg  equ     [bp+16]
  21. pRule  equ     [bp+18]
  22. ;  local stack storage
  23. lHigh  equ     WORD PTR [bp-2]
  24. lWide  equ     WORD PTR [bp-4]
  25. lPlane equ     BYTE PTR [bp-6]
  26. lIseg  equ     WORD PTR [bp-8]
  27. lMoffs equ     WORD PTR [bp-10]
  28. lMwork  equ    WORD PTR [bp-12]
  29. lWwrk   equ    WORD PTR [bp-14]
  30. lHwrk   equ    WORD PTR [bp-16]
  31. lBitsLO equ    WORD PTR [bp-18]     ; bit left after alignment shift
  32. lBwide  equ    WORD PTR [bp-20]
  33.  
  34.  
  35.  
  36. _EgaMPlot proc far
  37.         public _EgaMPlot
  38.  
  39.         push    bp              ; <1>
  40.         mov     bp,sp
  41.         sub     sp,22           ;space for local storage + fudge
  42.         pushf
  43.         cld                     ; correct string function
  44.         push    si              ; <2>
  45.         push    di              ; <3>
  46.         mov     cx,pX0          ; get x
  47.         mov     bx,pY0          ; get y
  48.         mov     ax,pMoffs
  49.         mov     lMoffs,ax       ; save offset to bitMask
  50.         mov     ax,pIseg        ; get ptr to Images
  51.         mov     lIseg,ax
  52.         mov     si,pIoffs       ; get ptr to Images
  53.         mov     ax,pRule        ; get rule
  54.         ;
  55.         ;  re-map the coordinates to an origin in the
  56.         ;  lower left corner.
  57.         ;
  58.         call    emapxy
  59.         ;
  60.         ;  set the segment reg to access the video screen
  61.         ;  but first set addressability to screen width in bytes
  62.         mov     ax,_bytes_per_line
  63.         mov     lBwide,ax
  64.  
  65.         push    es              ; <4>
  66.         mov     es,_curr_vid_seg
  67.         push    ds              ; <5>
  68.         mov     ds,pIseg
  69.         ;
  70.         ; get the image size from the image struct
  71.         ;  check for a zero size image, if so just quit.
  72.         ;
  73.         lodsw
  74.         cmp     ax,0
  75.         jz      EgaMPlotCzero
  76.         mov     lWide,ax
  77.         lodsw
  78.         cmp     ax,0
  79.         jz      EgaMPlotCzero
  80.         mov     lHigh,ax
  81.         jmp     EgaMPlotCok      ;Both wide & high are > 0
  82. EgaMPlotCzero:
  83.         jmp     EgaMPlotZero
  84. EgaMPlotCok:
  85.         ;
  86.         ;  Compute bit masks for the work on the left and right ends
  87.         ;  that may not be byte aligned in the video memory
  88.         ;
  89.         mov     cx,pX0          ; init shift count
  90.         and     cx,7            ; cl = number of bits to the next byte boundry
  91.         mov     lBitsLO,cx
  92.         neg     cx
  93.         and     cx,7            ; cl = number of bits to the next byte boundry
  94.         jnz     EgaMPlotNotByteAligned
  95.         mov     cl,8            ; using all 8 bits since byte aligned.
  96. EgaMPlotNotByteAligned:
  97.         ;
  98.         ;  We don't need to worry about the right bit mask, since the
  99.         ;  fill at the end should be 0's.
  100.  
  101.         ;
  102.         ;  set the logical function - default is FORCE, otherwise XOR
  103.         mov     ah,pRule        ; default logical function
  104.         shl     ah,1            ; shift up to bit 1,2
  105.         shl     ah,1            ; shift up to bit 2,3
  106.         shl     ah,1            ; shift up to bit 3,4
  107.  
  108. EgaMPlotFunc:
  109.         GR12_FUNCTION   ah
  110.         ;
  111.         ;  set the plane to be worked on (2^ 1..4)
  112.         ;
  113.         mov     lPlane,1         ; init plane counter
  114.         ;
  115. EgaMPlotPlane:
  116. EgaMPlotLeft:
  117.        ; Do the left partial bits
  118.        ;
  119.         push    di              ; <6>save start of image stroreg area for next
  120.  
  121.         SEQ_PLANE   lPlane
  122.  
  123.         mov     dx,lHigh        ; set depth counter
  124.         mov     lHwrk,dx        ; init depth counter
  125.  
  126.         mov     ax,lMoffs       ; and now the bitMask working offset
  127.         mov     lMwork,ax       ; set initial working offset of bitMask
  128.  
  129. EgaMPlotScan:
  130.         push    di              ; <7>save start of line screen image
  131.         mov     dx,lWide        ; set width counter
  132.         mov     lWwrk,dx        ; init width counter
  133.         ;
  134.         ;  The left bit mask must be computed for each row of data
  135.         ;  rather than jus once as with the non-masked approach
  136.         ;
  137.         xor     bx,bx           ; clear BX
  138.         call    EgaMPlotNxtMsk
  139.         shl     bx,cl           ; shift what we need into BH
  140.         xchg    bh,bl           ; swap it down into BL, leftover on BH
  141.  
  142.         ;  Now merge the left mask with the left bit mask portion.
  143.         ;  if the result is 0, there is nothing to plot in this byte
  144.  
  145.         GR12_BITMASK bl         ; use result of 'and' as bit mask
  146.  
  147.         xor     ah,ah           ; init upper bits to zeros
  148.         lodsb                   ; get first byte of image line in AL (AX=00xx)
  149.  
  150.         shl     ax,cl           ; rotate it      AX = 0xx0
  151.         xchg    al,ah           ; get bits shifted into AH back down to AL
  152.  
  153.         mov     dl,es:[di]      ; latch current screen data into ega controller
  154.         stosb                   ; write new data (AL) according to rule
  155.         ;
  156.         ;  Now adjust the bit mask stuff - we will use the BX for this
  157.         ;  The part to be used for the byte aligned is an ?H as we start
  158.         ;  through byte aligned. Fetch the high part from the manual calc.
  159.         ;
  160.         ;  Adjust counter of pixels / scan row
  161.         ;
  162.         sub     lWwrk,cx        ; lWwrk -= CX
  163.         cmp     lWwrk,8         ; lWwrk < 8 bits left ?
  164.         jl      EgaMPlotRite    ; wcount < 8
  165.         ;
  166.         ;  Now we are working with byte aligned portion of the scan line
  167.         ;
  168.  
  169. EgaMPlotByte:
  170.         ;  Compute this bit mask
  171.         ;
  172.         call    EgaMPlotNxtMsk
  173.  
  174.         shr     bh,cl           ; shift old down low in BH
  175.         shl     bx,cl           ; shift all up be count
  176.         xchg    bh,bl           ; swap them around
  177.         ;
  178.         ;  Use this bit mask to determine which pixels are to be maintained
  179.         ;
  180.         GR12_BITMASK  bl        ; use BL as the mitmask for updating screen
  181.  
  182.         ;  This loop is done for each part of the image line that
  183.         ;  is on a full byte boundry.
  184.         ;
  185.         lodsb                   ; got next byte of image data in AL
  186.         ;             AX = leftover in that was in AH (xchg from AL) followed
  187.         ;             by new byte in AL
  188.         shr     ah,cl           ; get leftover bits back in position
  189.         ;                that shifted them back down to the AH/AL boundry
  190.         shl     ax,cl           ; mix bits with leftovers
  191.         ;             and now back up again by the shift count
  192.         xchg    al,ah           ; get ms bits
  193.         mov     dl,es:[di]      ; latch previous data
  194.         stosb                   ; update with new data
  195.  
  196.         sub     lWwrk,8         ; last byte?
  197.         jz      EgaMPlotEndScan  ; exact match - no more bits
  198.         cmp     lWwrk,8         ; More than 8 bits left ??
  199.         jge     EgaMPlotByte    ; jif yes
  200.  
  201. EgaMPlotRite:
  202.         ;  Now we handle the bits that were left over in the right
  203.         ;  mask from the original computation
  204.         ;
  205.         ;
  206.         ;  If dx (bits left to plot) is > LBitsLO, (bit left over after shift)
  207.         ;  we need to get that last byte, and mix it in.
  208.         ;
  209.         mov     dx,lWwrk
  210.         cmp     dx,lBitsLO
  211.         jle     EgaMPlotNoByte  ; enuf bits in AH to finish job
  212.         ;
  213.         ;  pick up last bytes of image and bitmask
  214.         ;
  215.         lodsb                   ; get that last byte (image) into AL
  216.         shr     ah,cl           ; get leftover bits back in position
  217.         shl     ax,cl           ; mix bits with leftovers
  218.  
  219.         call    EgaMPlotNxtMsk  ; get that last byte (bitmask) into BL
  220.         shr     bh,cl           ; get leftover bits back in position
  221.         shl     bx,cl           ; mix bits with leftovers
  222.  
  223. EgaMPlotNoByte:
  224.  
  225.         GR12_BITMASK  bh        ; remaining part of bitmask
  226.  
  227.         xchg    al,ah           ; get the bits left over from the last
  228.                                 ;  shift and xchg run back down into AL
  229.         mov     dl,es:[di]      ; latch current data
  230.         stosb                   ; update with new
  231. EgaMPlotEndScan:
  232.         pop     di              ; <6>mov  back to start of screen line
  233.         add     di,lBwide       ; mov  to next line
  234.         dec     lHwrk           ; last line?
  235.         jz      EgaMPlotEndPlane; jif no, do next line
  236.         jmp     EgaMPlotScan    ; jif no, do next line
  237.         ;
  238.         ;  Now we have completed one plane of the image.
  239.         ;  Reset the DI pointer to the start of the video image,
  240.         ;  but keep going in the memory image to be written.
  241.         ;  Move on to the next plane as needed.
  242.         ;
  243. EgaMPlotEndPlane:
  244.         pop     di              ; <5>mov  back to start of screen image
  245.         shl     lPlane,1        ; mov  to next plane
  246.         test    lPlane,16       ; done?
  247.         jnz     EgaMPlotDone    ; jif no
  248.         jmp     EgaMPlotPlane
  249.  
  250. EgaMPlotDone:
  251.         GR12_FUNCTION   0
  252.         GR12_BITMASK  0ffh
  253.         SEQ_PLANE      0fh
  254. EgaMPlotZero:
  255.         mov     ax,0            ; return 0
  256.         pop     ds              ; <4>
  257.         pop     es              ; <3>
  258.         pop     di              ; <2>
  259.         pop     si              ; <1>
  260.         popf
  261.         mov     sp,bp
  262.         pop     bp              ; <0>
  263.         ret
  264.  
  265. ;==============================================================
  266. ;  This saves the DS:[SI] set, retrieves the next byte
  267. ;  of the bitmask, then resores the pointer to the
  268. ;  image
  269. ;
  270. ;  exit  BL = next byte of bit mask
  271. ;
  272. EgaMPlotNxtMsk proc near
  273.         push    ds              ; <8>addressability
  274.         push    si              ; <9>
  275.         mov     ds,pMseg
  276.         mov     si,lMwork
  277.         mov     bl,[si]         ; AL = initial left mask
  278.         inc     si
  279.         mov     lMwork,si
  280.         pop     si              ; <8)
  281.         pop     ds              ; <7>
  282.         ret
  283. EgaMPlotNxtMsk  endp
  284. _EgaMPlot endp
  285.  
  286.