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

  1. ;==================================================================
  2. ;
  3. ;
  4. ; egabplot(x, y, picture, rule);
  5. ;
  6. ;===================================================================
  7. ;  large parms
  8. pX0    equ     [bp+6]
  9. pY0    equ     [bp+8]
  10. pIoffs equ     [bp+10]
  11. pIseg  equ     [bp+12]
  12. pRule  equ     [bp+14]
  13. ;  local stack storage
  14. lHigh  equ     WORD PTR [bp-2]      ; value from image structure
  15. lWide  equ     WORD PTR [bp-4]      ; value from image structure
  16. lLmask equ     BYTE PTR [bp-6]      ; computed left bit mask
  17. lRmask equ     BYTE PTR [bp-8]      ; computed right bit mask
  18. lPlane equ     BYTE PTR [bp-10]     ; shifted value to indicate plane
  19. lIseg  equ     WORD PTR [bp-12]     ; image segment passed
  20. lLsize equ     BYTE PTR [bp-14]     ; count of bits in left mask
  21. lHwrk equ      WORD PTR [bp-16]     ; working copy as scan line are used
  22. lWwrk equ      WORD PTR [bp-18]     ; working copy across scan line
  23. lBitsLO equ    WORD PTR [bp-20]     ; bit left after alignment shift
  24. lBwide  equ    WORD PTR [bp-22]     ; bytes wide of svan line
  25.  
  26.  
  27. _EgaPlot proc far
  28.         public _EgaPlot
  29.  
  30.         push    bp
  31.         mov     bp,sp
  32.         sub     sp,24           ;space for local storage
  33.         pushf                   ; save the direction flag
  34.         cld                     ; correct string function
  35.         push    si
  36.         push    di
  37.  
  38.         ;  Pick up and strore the local versions of args
  39.  
  40.         mov     cx,pX0          ; get x
  41.         mov     bx,pY0          ; get y
  42.         mov     si,pIoffs       ; get ptr to Images
  43.         ;  We pick up the segment later.
  44.         ;
  45.         ;  compute the offset in the video memory
  46.         ;
  47.         call    emapxy
  48.         ;
  49.         ;  set the segment reg to access the video screen
  50.         ;  and the segment for the image to be plotted
  51.         ;
  52.         mov     ax,_bytes_per_line ;but first save this befor we destroy DS
  53.         mov     lBwide,ax
  54.  
  55.         push    es
  56.         mov     es,_curr_vid_seg
  57.         push    ds
  58.         mov     ds,pIseg
  59.         ;
  60.         ; get the image size from the image struct
  61.         ;  check for a zero size image, if so just quit.
  62.         ;
  63.         lodsw
  64.         cmp     ax,0
  65.         jz      EgaPlotCzero
  66.         mov     lWide,ax
  67.         lodsw
  68.         cmp     ax,0
  69.         jz      EgaPlotCzero
  70.         mov     lHigh,ax
  71.         jmp     EgaPlotCok      ;Both wide & high are > 0
  72. EgaPlotCzero:
  73.         jmp     EgaPlotZero
  74. EgaPlotCok:
  75.         ;
  76.         ;  Compute bit masks for the work on the left and right ends
  77.         ;  that may not be byte aligned in the video memory
  78.         ;
  79.         mov     cx,pX0          ; init shift count
  80.         and     cx,7            ; cl = number of bits into this byte -1
  81.         mov     lBitsLO,cx      ; save # of empty hi bits
  82.         neg     cx              ; number of active bits
  83.         and     cx,7            ; get rid of all but last 3 bits
  84.         jnz     EgaPlotNByte    ; !=0 := NotByte aligned
  85.         mov     cx,8            ; Byte aligned, need 8 bits
  86. EgaPlotNByte:
  87.         mov     ax,0ffh         ; init left/right masks
  88.         shl     ax,cl           ; al 1=bits to be shifted up into AH
  89.         mov     lLmask,ah       ; left bit mask
  90.         ;
  91.         ;  Now compute the mask for the right end since the mask is the
  92.         ;  result of ((start pixel + scan width -1)  mod 8)+1
  93.         ;  A value of 0 implies the leftmost bit ; which is why '+1'
  94.         ;
  95.         push    cx              ; save CX=# of bits in rotation for alignment
  96.  
  97.         mov     cx,pX0          ; Add the width to the start x1
  98.         add     cx,lWide        ; start + width
  99.         dec     cx              ; minus 1
  100.         and     cx,7            ; mod 8
  101.         inc     cx              ; + 1
  102.         mov     bx,0ff00h
  103.         shr     bx,cl
  104.         mov     lRmask,bl       ; Save it
  105.  
  106.         pop     cx              ; get back offset from byte alignment
  107.  
  108.         ;  Now that we have computed both the leading and trailing
  109.         ;  bit masks, we have to check to see if they are both in the
  110.         ;  same byte.  If they are, they must be combined.
  111.  
  112.         mov     ax,pX0          ;start pixel offset
  113.         mov     bx,ax           ;
  114.         add     bx,lWide        ;how many pixels
  115.         dec     bx              ;end = (start + length) -1
  116.         xor     ax,bx           ;if the not same byte, some bits from 3-15
  117.                                 ; will be set
  118.         and     ax,0fff8h       ;keep all but the low 3 bits
  119.         jnz     EgaPlotNotSameByte ;not zero, not the same byte
  120.         ;  same byte - build combined mask
  121.         mov     al,lLmask
  122.         and     al,lRmask       ;keep only bit in both masks
  123.         mov     lLmask,al
  124. EgaPlotNotSameByte:
  125.         ;
  126.         ;  set the logical function
  127.         ;
  128.         mov     ah,pRule        ; default logical function
  129.         shl     ah,1            ; shift up to bit 1,2
  130.         shl     ah,1            ; shift up to bit 2,3
  131.         shl     ah,1            ; shift up to bit 3,4
  132.         ;
  133.         ;  AX = bits read from video memory
  134.         ;  BX = width of scan line
  135.         ;  CX = number of bits (shifts) to align video memory to storage
  136.         ;  DX = work register (used to address Video controller ports)
  137.         ;
  138.  
  139. EgaPlotFunc:
  140.         GR12_FUNCTION   ah
  141.         ;
  142.         ;  set the plane to be worked on (2^ 1..4)
  143.         ;
  144.         mov     lPlane,1         ; init plane counter
  145.         ;
  146. EgaPlotPlane:
  147. EgaPlotLeft:
  148.        ; Do the left partial bits
  149.        ;
  150.         push    di              ; save start of image screen ptr
  151.  
  152.         SEQ_PLANE   lPlane
  153.  
  154.         mov     dx,lHigh
  155.         mov     lHwrk,dx        ; init height counter
  156. EgaPlotScan:
  157.         push    di              ; save start of line screen ptr
  158.         mov     bx,lWide        ; init scan line width
  159.  
  160.         GR12_BITMASK lLmask
  161.  
  162.         xor     ah,ah           ; init upper bits to zeros
  163.  
  164.         lodsb                   ; get first byte of image line in AL (AX=00xx)
  165.  
  166.         shl     ax,cl           ; rotate it      AX = 0xx0
  167.         xchg    al,ah           ; get bits shifted into AH back down to AL
  168.         mov     dl,es:[di]      ; latch current screen data into ega controller
  169.         stosb                   ; write new data (AL) according to rule
  170.  
  171.         sub     bx,cx           ; scan width -= shift amount
  172.         jz      EgaPlotEndScan  ; 0 bits left - on to next scan line
  173.         js      EgaPlotEndScan  ; sign set, went negative
  174.         cmp     bx,8            ; remaining < 8 bits left ?
  175.         jl      EgaPlotRite     ; (signed) YES - right partial end
  176.  
  177.         ;
  178.         ;  Now we are working with byte aligned portion of the scan line
  179.         ;
  180.         GR12_BITMASK  0ffh
  181.  
  182. EgaPlotByte:
  183.         ;  This loop is done for each part of the image line that
  184.         ;  is on a full byte boundry.
  185.         ;
  186.         lodsb                   ; got next byte of image data in AL
  187.         ;                         AX = leftover in that was in AH
  188.         ;                         (xchg from AL) followed by new byte in AL
  189.         shr     ah,cl           ; get leftover bits back in position
  190.         ;                          that shifted them back down to the
  191.         ;                          AH/AL boundry
  192.         shl     ax,cl           ; mix bits with leftovers
  193.         ;                          and now back up again by the shift count
  194.         xchg    al,ah           ; get ms bits
  195.         mov     dl,es:[di]      ; latch previous data
  196.         stosb                   ; update with new data
  197.  
  198.         sub     bx,8            ; last byte?
  199.         jz      EgaPlotEndScan  ; exact match - no more bits
  200.         cmp     bx,8            ; More than 8 bits left ??
  201.         jge     EgaPlotByte     ; jif yes
  202.  
  203. EgaPlotRite:
  204.         ;  Now we handle the bits that were left over in the right
  205.         ;  mask from the original computation
  206.         ;
  207.  
  208.         GR12_BITMASK  lRmask
  209.         ;
  210.         ;  If bx (bits left to plot) is > LBitsLO, (bit left over after shift)
  211.         ;  we need to get that last byte, and mix it in.
  212.         ;  the leftover bit are in the top of AH.
  213.         cmp     bx,lBitsLO
  214.         jle     EgaPlotNoByte   ; enuf bits in AH to finish job
  215.  
  216.         lodsb                   ; get that last byte  into AL
  217.         shr     ah,cl           ; get leftover bits back in position
  218.         ;                         that shifted them back down to the
  219.         ;                         AH/AL boundry
  220.         shl     ax,cl           ; mix bits with leftovers
  221.         ;                         and now back up again by the shift count
  222.  
  223. EgaPlotNoByte:
  224.  
  225.         xchg    al,ah           ; get ms bits
  226.                                 ;  shift and xchg run back down into AL
  227.         mov     dl,es:[di]      ; latch current data
  228.         stosb                   ; update with new
  229. EgaPlotEndScan:
  230.         pop     di              ; mov  back to start of screen line
  231.         add     di,lBwide       ; move to next line
  232.         dec     lHwrk           ; last line?
  233.         jnz     EgaPlotScan     ; jif no, do next line
  234.         ;
  235.         ;  Now we have completed one plane of the image.
  236.         ;  Reset the DI pointer to the start of the video image,
  237.         ;  but keep going in the memory image to be written.
  238.         ;  Move on to the next plane as needed.
  239.         ;
  240. EgaPlotEndPlane:
  241.         pop     di              ; mov  back to start of screen image
  242.         shl     lPlane,1        ; mov  to next plane
  243.         test    lPlane,16       ; done?
  244.         jnz     EgaPlotDone     ; jif no
  245.         jmp     EgaPlotPlane
  246.  
  247. EgaPlotDone:
  248.         GR12_FUNCTION   0
  249.         GR12_BITMASK  0ffh
  250.         SEQ_PLANE      0fh
  251. EgaPlotZero:
  252.         mov     ax,0            ; return 0
  253.         pop     es
  254.         pop     ds
  255.         pop     di
  256.         pop     si
  257.         popf
  258.         mov     sp,bp
  259.         pop     bp
  260.         ret
  261. _EgaPlot endp
  262.