home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / video / 12 / 12_4.asm < prev   
Encoding:
Assembly Source File  |  1988-08-11  |  4.4 KB  |  184 lines

  1.         TITLE    'Listing 12-4'
  2.         NAME    ScreenOrigin
  3.         PAGE    55,132
  4.  
  5. ;
  6. ; Name:        ScreenOrigin
  7. ;
  8. ; Function:    Set screen origin on EGA and VGA
  9. ;
  10. ; Caller:    Microsoft C:
  11. ;
  12. ;            void ScreenOrigin(x,y);
  13. ;
  14. ;                int    x,y;    /* pixel x,y coordinates */
  15. ;
  16.  
  17. ARGx        EQU    [bp+4]
  18. ARGy        EQU    [bp+6]
  19.  
  20.  
  21. CRT_MODE    EQU    49h        ; addresses in video BIOS data area
  22. ADDR_6845    EQU    63h
  23. POINTS        EQU    85h
  24. BIOS_FLAGS    EQU    89h
  25.  
  26. DGROUP        GROUP    _DATA
  27.  
  28. _TEXT        SEGMENT    byte public 'CODE'
  29.         ASSUME    cs:_TEXT,ds:DGROUP
  30.  
  31.         PUBLIC    _ScreenOrigin
  32. _ScreenOrigin    PROC    near
  33.  
  34.         push    bp        ; preserve caller registers
  35.         mov    bp,sp
  36.         push    si
  37.         push    di
  38.  
  39.         mov    ax,40h
  40.         mov    es,ax        ; ES -> video BIOS data area
  41.         mov    cl,es:[CRT_MODE]
  42.  
  43.         mov    ax,ARGx        ; AX := pixel x-coordinate
  44.         mov    bx,ARGy        ; BX := pixel y-coordinate
  45.  
  46.         cmp    cl,7
  47.         ja    L01        ; jump if graphics mode
  48.  
  49.         je    L02        ; jump if monochrome alpha
  50.  
  51.         test    byte ptr es:[BIOS_FLAGS],1
  52.         jnz    L02        ; jump if VGA
  53.  
  54.         jmp    short L03
  55.  
  56. ; setup for graphics modes (8 pixels per byte)
  57.  
  58. L01:        mov    cx,8        ; CL := 8 (displayed pixels per byte)
  59.                     ; CH := 0 (value for Preset Row Scan)
  60.         div    cl        ; AH := bit offset in byte
  61.                     ; AL := byte offset in pixel row
  62.         mov    cl,ah        ; CL := bit offset (for Horiz Pel Pan)
  63.         xor    ah,ah
  64.         xchg    ax,bx        ; AX := y
  65.                     ; BX := byte offset in pixel row
  66.  
  67.         mul    word ptr _BytesPerRow
  68.                     ; AX := byte offset of start of row
  69.         jmp    short L05
  70.  
  71. ; setup for VGA alphanumeric modes and EGA monochrome alphanumeric mode
  72. ;  (9 pixels per byte)
  73.  
  74. L02:                    ; routine for alpha modes
  75.         mov    cx,9        ; CL := 9 (displayed pixels per byte)
  76.                                         ; CH := 0
  77.         div    cl        ; AH := bit offset in byte
  78.                     ; AL := byte offset in pixel row
  79.         dec    ah        ; AH := -1, 0-7
  80.         jns    L04        ; jump if bit offset 0-7
  81.         mov    ah,8        ; AH := 8
  82.         jmp    short L04
  83.  
  84. ; setup for EGA color alphanumeric modes (8 pixels per byte)
  85.  
  86. L03:        mov    cx,8        ; CL := 8 (displayed pixels per byte)
  87.                     ; CH := 0
  88.         div    cl        ; AH := bit offset in byte
  89.                     ; AL := byte offset in pixel row
  90.  
  91. L04:        mov    cl,ah        ; CL := value for Horiz Pel Pan reg
  92.         xor    ah,ah
  93.         xchg    ax,bx        ; AX := y
  94.                     ; BX := byte offset in row
  95.         div    byte ptr es:[POINTS]  ; AL := character row
  96.                           ; AH := scan line in char matrix
  97.         xchg    ah,ch        ; AX := character row
  98.                     ; CH := scan line (value for Preset
  99.                     ;        Row Scan register)
  100.         mul    word ptr _BytesPerRow    ; AX := byte offset of char row
  101.         shr    ax,1        ; AX := word offset of character row
  102.  
  103. L05:        call    SetOrigin
  104.  
  105.         pop    di        ; restore registers and exit
  106.         pop    si
  107.         mov    sp,bp
  108.         pop    bp
  109.         ret
  110.  
  111. _ScreenOrigin    ENDP
  112.  
  113.  
  114. SetOrigin    PROC    near        ; Caller:  AX = offset of character row
  115.                     ;       BX = byte offset within row
  116.                     ;       CH = Preset Row Scan value
  117.                     ;       CL = Horizontal Pel Pan value
  118.  
  119.         add    bx,ax        ; BX := buffer offset
  120.  
  121.         mov    dx,es:[ADDR_6845]  ; CRTC I/O port (3B4H or 3D4H)
  122.         add    dl,6        ; video status port (3BAH or 3DAH)
  123.  
  124. ; update Start Address High and Low registers
  125.  
  126. L20:        in    al,dx        ; wait for start of vertical retrace
  127.         test    al,8
  128.         jz    L20
  129.  
  130. L21:        in    al,dx        ; wait for end of vertical retrace
  131.         test    al,8
  132.         jnz    L21
  133.  
  134.         cli            ; disable interrupts
  135.         sub    dl,6        ; DX := 3B4H or 3D4H
  136.  
  137.         mov    ah,bh        ; AH := value for Start Address High
  138.         mov    al,0Ch        ; AL := Start Address High reg number
  139.         out    dx,ax        ; update this register
  140.  
  141.         mov    ah,bl        ; AH := value for Start Address Low
  142.         inc    al        ; AL := Start Address Low reg number
  143.         out    dx,ax        ; update this register
  144.         sti            ; enable interrupts
  145.  
  146.         add    dl,6        ; DX := video status port
  147.  
  148. L22:        in    al,dx        ; wait for start of vertical retrace
  149.         test    al,8
  150.         jz    L22
  151.  
  152.         cli            ; disable interrupts
  153.  
  154.         sub    dl,6        ; DX := 3B4H or 3D4H
  155.         mov    ah,ch        ; AH := value for Preset Row Scan reg
  156.         mov    al,8        ; AL := Preset Row Scan reg number
  157.         out    dx,ax        ; update this register
  158.  
  159.         mov    dl,0C0h        ; DX := 3C0h (Attribute Controller port)
  160.         mov    al,13h OR 20h    ; AL bit 0-4 := Horiz Pel Pan reg number
  161.                     ; AL bit 5 := 1
  162.         out    dx,al        ; write Attribute Controller Address reg
  163.                                         ;  (Attribute Controller address
  164.                                         ;    flip-flop has been reset by
  165.                                         ;    the IN at L22.)
  166.         mov    al,cl        ; AL := value for Horiz Pel Pan reg
  167.         out    dx,al        ; update this register
  168.  
  169.         sti            ; re-enable interrupts
  170.         ret
  171.  
  172. SetOrigin    ENDP
  173.  
  174. _TEXT        ENDS
  175.  
  176.  
  177. _DATA        SEGMENT    word public 'DATA'
  178.  
  179.         EXTRN    _BytesPerRow:word    ; bytes per pixel row
  180.  
  181. _DATA        ENDS
  182.  
  183.         END
  184.