home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / video / 9 / 9_3.asm < prev    next >
Encoding:
Assembly Source File  |  1988-08-11  |  5.0 KB  |  224 lines

  1.         TITLE    'Listing 9-3'
  2.         NAME    DisplayChar04
  3.         PAGE    55,132
  4.  
  5. ;
  6. ; Name:        DisplayChar04
  7. ;
  8. ; Function:    Display a character in 320x200 4-color graphics mode
  9. ;
  10. ; Caller:    Microsoft C:
  11. ;
  12. ;            void DisplayChar04(c,x,y,fgd,bkgd);
  13. ;
  14. ;            int c;            /* character code */
  15. ;
  16. ;            int x,y;        /* upper left pixel */
  17. ;
  18. ;            int fgd,bkgd;        /* foreground and background
  19. ;                            pixel values */
  20. ;
  21.  
  22. ARGc        EQU    word ptr [bp+4]    ; stack frame addressing
  23. ARGx        EQU    word ptr [bp+6]
  24. ARGy        EQU    word ptr [bp+8]
  25. ARGfgd        EQU             [bp+10]
  26. ARGbkgd        EQU             [bp+12]
  27.  
  28. VARshift    EQU    word ptr [bp-2]
  29. VARincr        EQU    word ptr [bp-4]
  30.  
  31.  
  32. DGROUP        GROUP    _DATA
  33.  
  34. _TEXT        SEGMENT    byte public 'CODE'
  35.         ASSUME    cs:_TEXT,ds:DGROUP
  36.  
  37.         EXTRN    PixelAddr04:near
  38.  
  39.         PUBLIC    _DisplayChar04
  40. _DisplayChar04    PROC    near
  41.  
  42.         push    bp        ; preserve caller registers
  43.         mov    bp,sp
  44.         sub    sp,4        ; stack space for local variables
  45.         push    si
  46.         push    di
  47.         push    ds
  48.  
  49. ; propagate pixel values
  50.  
  51.         mov    bx,offset DGROUP:PropagatedPixel
  52.         mov    al,ARGfgd
  53.         xlat            ; propagate foreground pixel value
  54.         mov    ah,al
  55.         mov    ARGfgd,ax
  56.  
  57.         mov    al,ARGbkgd
  58.         xlat            ; propagate background pixel value
  59.         mov    ah,al
  60.         mov    ARGbkgd,ax 
  61.  
  62. ; calculate first pixel address
  63.  
  64.         mov    ax,ARGy        ; AX := y
  65.         mov    bx,ARGx        ; BX := x
  66.         call    PixelAddr04    ; ES:BX -> buffer
  67.                     ; CL := # bits to shift left
  68.                     ;  to mask pixel
  69.         mov    ch,0FCh
  70.         shl    ch,cl        ; CH := bit mask for right side of char
  71.  
  72.         xor    cl,6        ; CL := 6 - CL (# bits to rotate char
  73.                     ;  into position)
  74.         mov    VARshift,cx
  75.  
  76. ; set up video buffer addressing
  77.  
  78.         mov    di,2000h    ; increment for video buffer interleave
  79.         mov    VARincr,80-2000h ; increment from last to first interleave
  80.  
  81.         test    bx,2000h    ; set zero flag if BX in 1st interleave
  82.         jz    L01
  83.  
  84.         xchg    VARincr,di    ; exchange increment values if 1st pixel
  85.                     ;  lies in 1st interleave
  86.  
  87. ; set up character definition table addressing
  88.  
  89. L01:        push    bx        ; preserve buffer address
  90.  
  91.         mov    ax,40h
  92.         mov    ds,ax        ; DS := segment of BIOS Video
  93.                     ;  Display Data area
  94.         mov    ch,ds:[85h]    ; CH := POINTS (pixel rows in character)
  95.  
  96.         xor    ax,ax
  97.         mov    ds,ax        ; DS := absolute zero
  98.  
  99.         mov    ax,ARGc        ; AL := character code
  100.         cmp    al,80h
  101.         jae    L02
  102.  
  103.         mov    bx,43h*4    ; DS:BX -> int 43h vector if char < 80h
  104.         jmp    short L03
  105.  
  106. L02:        mov    bx,1Fh*4    ; DS:BX -> int 1Fh vector if char >= 80h
  107.         sub    al,80h        ; put character code in range of table 
  108.  
  109. L03:        lds    si,ds:[bx]    ; DS:SI -> start of character table
  110.         mul    ch        ; AX := offset into char def table
  111.                     ;  (POINTS * char code)
  112.         add    si,ax        ; SI := addr of char def
  113.  
  114.         pop    bx        ; restore buffer address
  115.  
  116.         xchg    ch,cl        ; CH := # bits to rotate
  117.                     ; CL := POINTS
  118.         
  119.         test    ch,ch        ; test # bits to rotate
  120.         jnz    L20        ; jump if character is not byte-aligned
  121.  
  122.  
  123. ; routine for byte-aligned characters
  124.  
  125. L10:        lodsb            ; AL := bit pattern for next pixel row
  126.         xor    dx,dx        ; DX := initial value for doubled bits
  127.         mov    ah,8        ; AH := # of bits in pattern
  128.  
  129. L11:        shr    al,1        ; cf := lo-order bit of AL
  130.         rcr    dx,1        ; hi-order bit of CX := cf
  131.         sar    dx,1        ; double hi-order bit of DX
  132.         dec    ah        ; loop 8 times
  133.         jnz    L11
  134.  
  135.         mov    ax,dx        ; AX,DX := doubled bit pattern
  136.         and    ax,ARGfgd    ; AX := foreground pixels
  137.         not    dx
  138.         and    dx,ARGbkgd    ; DX := background pixels
  139.  
  140.         or    ax,dx        ; AX := eight pixels
  141.         xchg    ah,al        ; put bytes in proper order
  142.         mov    es:[bx],ax    ; update video buffer
  143.  
  144.         add    bx,di        ; BX := next row in buffer
  145.         xchg    di,VARincr    ; swap buffer increments
  146.  
  147.         loop    L10
  148.         jmp    short Lexit
  149.  
  150.  
  151. ; routine for non-byte-aligned characters
  152.  
  153. L20:        xor    ch,ch        ; CX := POINTS
  154.  
  155. L21:        push    cx        ; preserve CX
  156.  
  157.         mov    cx,VARshift    ; CH := mask for right side of char
  158.                     ; CL := # bits to rotate
  159.  
  160.         lodsb            ; AL := bit pattern for next pixel row
  161.         xor    dx,dx        ; DX := initial value for doubled bits
  162.         mov    ah,8        ; AH := # of bits in pattern
  163.  
  164. L22:        shr    al,1        ; DX := double bits in AL
  165.         rcr    dx,1        ;  (same as above)
  166.         sar    dx,1
  167.         dec    ah
  168.         jnz    L22
  169.  
  170.         xchg    dh,dl        ; DH := bits for right half of char
  171.                     ; DL := bits for left half of char
  172.         mov    ax,dx
  173.         and    ax,ARGfgd    ; AX := foreground pixels
  174.         not    dx
  175.         and    dx,ARGbkgd    ; DX := background pixels
  176.  
  177.         or    dx,ax        ; DX := eight pixels
  178.         ror    dx,cl        ; DH := left and right side pixels
  179.                     ; DL := middle pixels
  180.         mov    al,ch
  181.         xor    ah,ah        ; AX := mask for left and middle
  182.                     ;  bytes of char
  183.         and    es:[bx],ax    ; zero pixels in video buffer
  184.  
  185.         not    ax
  186.         and    ax,dx
  187.         or    es:[bx],ax    ; update pixels in left and middle bytes
  188.  
  189.         mov    al,ch        ; AL := mask for right-hand byte
  190.         not    al
  191.         and    es:[bx+2],al    ; mask pixels in right-hand byte in buffer
  192.         and    ch,dl
  193.         or    es:[bx+2],ch    ; update pixels in right-hand byte
  194.  
  195.         add    bx,di        ; BX := next row in buffer
  196.         xchg    di,VARincr    ; swap buffer increments
  197.  
  198.         pop    cx        ; restore CX
  199.         loop    L21
  200.  
  201.  
  202. Lexit:        pop    ds        ; restore registers and return
  203.         pop    di
  204.         pop    si
  205.         mov    sp,bp
  206.         pop    bp
  207.         ret
  208.  
  209. _DisplayChar04    ENDP
  210.  
  211. _TEXT        ENDS
  212.  
  213.  
  214. _DATA        SEGMENT    word public 'DATA'
  215.  
  216. PropagatedPixel    DB    00000000b    ; 0
  217.         DB    01010101b    ; 1
  218.         DB    10101010b    ; 2
  219.         DB    11111111b    ; 3
  220.  
  221. _DATA        ENDS
  222.  
  223.         END
  224.