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

  1.         TITLE    'Listing 9-3'
  2.         NAME    DisplayChar06
  3.         PAGE    55,132
  4.  
  5. ;
  6. ; Name:        DisplayChar06
  7. ;
  8. ; Function:    Display a character in 640x200 2-color mode
  9. ;
  10. ; Caller:    Microsoft C:
  11. ;
  12. ;            void DisplayChar06(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    byte ptr [bp+10]
  26. ARGbkgd        EQU    byte ptr [bp+12]
  27.  
  28. VARmask        EQU    [bp-2]
  29. VARtoggle    EQU    [bp-4]
  30.  
  31.  
  32. _TEXT        SEGMENT    byte public 'CODE'
  33.         ASSUME    cs:_TEXT
  34.  
  35.         EXTRN    PixelAddr06:near
  36.  
  37.         PUBLIC    _DisplayChar06
  38. _DisplayChar06    PROC    near
  39.  
  40.         push    bp        ; preserve caller registers
  41.         mov    bp,sp
  42.         sub    sp,4        ; stack space for local variables
  43.         push    si
  44.         push    di
  45.         push    ds
  46.  
  47. ; set up foreground pixel toggle mask
  48.  
  49.         mov    ah,ARGfgd    ; AH := 0 or 1 (foreground pixel value)
  50.         ror    ah,1        ; high-order bit of AH := 0 or 1
  51.         cwd            ; propagate high-order bit through DX
  52.         not    dx        ; DX :=     0 if foreground = 1
  53.                     ;    or FFFFh if foreground = 0
  54.         mov    VARtoggle,dx
  55.  
  56. ; calculate first pixel address
  57.  
  58.         mov    ax,ARGy        ; AX := y
  59.         mov    bx,ARGx        ; BX := x
  60.         call    PixelAddr06    ; ES:BX -> buffer
  61.                     ; CL := # bits to shift left
  62.  
  63.         xor    cl,7        ; CL := # bits to rotate right
  64.  
  65.         mov    ax,0FF00h
  66.         ror    ax,cl        ; AX := bit mask in proper position
  67.         mov    VARmask,ax
  68.  
  69. ; set up video buffer addressing
  70.  
  71.         mov    dx,2000h    ; increment for video buffer interleave
  72.         mov    di,80-2000h    ; increment from last to first interleave
  73.  
  74.         test    bx,2000h    ; set zero flag if BX in 1st interleave
  75.         jz    L01
  76.  
  77.         xchg    di,dx        ; exchange increment values if 1st pixel
  78.                     ;  lies in 1st interleave
  79.  
  80. ; set up character definition table addressing
  81.  
  82. L01:        push    bx        ; preserve buffer address
  83.  
  84.         mov    ax,40h
  85.         mov    ds,ax        ; DS := segment of BIOS Video
  86.                     ;  Display Data area
  87.         mov    ch,ds:[85h]    ; CH := POINTS (pixel rows in character)
  88.  
  89.         xor    ax,ax
  90.         mov    ds,ax        ; DS := absolute zero
  91.  
  92.         mov    ax,ARGc        ; AL := character code
  93.         cmp    al,80h
  94.         jae    L02
  95.  
  96.         mov    bx,43h*4    ; DS:BX -> int 43h vector if char < 80h
  97.         jmp    short L03
  98.  
  99. L02:        mov    bx,1Fh*4    ; DS:BX -> int 1Fh vector if char >= 80h
  100.         sub    al,80h        ; put character code in range of table 
  101.  
  102. L03:        lds    si,ds:[bx]    ; DS:SI -> start of character table
  103.         mul    ch        ; AX := offset into char def table
  104.                     ;  (POINTS * char code)
  105.         add    si,ax        ; SI := addr of char def
  106.  
  107.         pop    bx        ; restore buffer address
  108.  
  109.         test    cl,cl        ; test # bits to rotate
  110.         jnz    L20        ; jump if character is not byte-aligned
  111.  
  112.  
  113. ; routine for byte-aligned characters
  114.  
  115.         mov    ah,VARtoggle    ; AH := foreground toggle mask
  116.         xchg    ch,cl        ; CX := POINTS
  117.         
  118. L10:        lodsb            ; AL := bit pattern for next pixel row
  119.         xor    al,ah        ; toggle pixels if foreground = 0
  120.         mov    es:[bx],al    ; store pixels in buffer
  121.  
  122.         add    bx,dx        ; BX := next row in buffer
  123.         xchg    di,dx        ; swap buffer increments
  124.         loop    L10
  125.         jmp    short Lexit
  126.  
  127.  
  128. ; routine for non-byte-aligned characters
  129.  
  130. L20:        mov    ax,VARmask
  131.         and    es:[bx],ax    ; mask character pixels in buffer
  132.  
  133.         xor    ah,ah
  134.         lodsb            ; AX := bit pattern for next pixel row
  135.         xor    al,VARtoggle    ; toggle pixels if foreground = 0
  136.  
  137.         ror    ax,cl        ; rotate pixels into position
  138.         or    es:[bx],ax    ; store pixels in buffer
  139.  
  140.         add    bx,dx        ; BX := next row in buffer
  141.         xchg    di,dx        ; swap buffer increments
  142.         dec    ch
  143.         jnz    L20
  144.  
  145.  
  146. Lexit:        pop    ds        ; restore registers and return
  147.         pop    di
  148.         pop    si
  149.         mov    sp,bp
  150.         pop    bp
  151.         ret
  152.  
  153. _DisplayChar06    ENDP
  154.  
  155. _TEXT        ENDS
  156.  
  157.         END
  158.