Previous | Table of Contents | Next

LISTING 32.1 L32-1.ASM

    ; Borland C/C++ tiny/small/medium model-callable assembler
    ; subroutines to:
    ;* Set 360×480 256-color VGA mode
    ;* Draw a dot in 360×480 256-color VGA mode
    ;* Read the color of a dot in 360×480 256-color VGA mode
    ;
    ; Assembled with TASM
    ;
    ; The 360×480 256-color mode set code and parameters were provided
    ; by John Bridges, who has placed them into the public domain.
    ;
    VGA_SEGMENT     equ    0a000h      ;display memory segment
    SC_INDEX        equ    3c4h        ;Sequence Controller Index register
    GC_INDEX        equ    3ceh        ;Graphics Controller Index register
    MAP_MASK        equ    2           ;Map Mask register index in SC
    READ_MAP        equ    4           ;Read Map register index in GC
    SCREEN_WIDTH    equ    360         ;# of pixels across screen
    WORD_OUTS_OK    equ    1           ;set to 0 to assemble for
                                       ; computers that can’t handle
                                       ; word outs to indexed VGA registers
    ;
    _DATAsegmentpublic byte ‘DATA’
    ;
    ; 360×480 256-color mode CRT Controller register settings.
    ; (Courtesy of John Bridges.)
    ;
    vptbl   dw      06b00h  ; horz total
            dw      05901h  ; horz displayed
            dw      05a02h  ; start horz blanking
            dw      08e03h  ; end horz blanking
            dw      05e04h  ; start h sync
            dw      08a05h  ; end h sync
            dw      00d06h  ; vertical total
            dw      03e07h  ; overflow
            dw      04009h  ; cell height
            dw      0ea10h  ; v sync start
            dw      0ac11h  ; v sync end and protect cr0-cr7
            dw      0df12h  ; vertical displayed
            dw      02d13h  ; offset
            dw      00014h  ; turn off dword mode
            dw      0e715h  ; v blank start
            dw      00616h  ; v blank end
            dw      0e317h  ; turn on byte mode
    vpend   label   word
    _DATAends
    ;
    ; Macro to output a word value to a port.
    ;
    OUT_WORDmacro
    if WORD_OUTS_OK
          out   dx,ax
    else
          out   dx,al
          inc   dx
          xchg  ah,al
          out   dx,al
          dec   dx
          xchg  ah,al
    endif
          endm
    ;
    _TEXTsegment byte public ‘CODE’
           assumecs:_TEXT, ds:_DATA
    ;
    ; Sets up 360×480 256-color mode.
    ; (Courtesy of John Bridges.)
    ;
    ; Call as: void Set360By480Mode()
    ;
    ; Returns: nothing
    ;
          public _Set360×480Mode
    _Set360×480Modeprocnear
          push   si                 ;preserve C register vars
          push   di
          mov    ax,12h             ; start with mode 12h
          int    10h                ; let the BIOS clear the video memory

          mov    ax,13h             ; start with standard mode 13h
          int    10h                ; let the BIOS set the mode

          mov    dx,3c4h            ; alter sequencer registers
          mov    ax,0604h           ; disable chain 4
          out    dx,ax

          mov    ax,0100h           ; synchronous reset
          out    dx,ax              ; asserted
          mov    dx,3c2h            ; misc output
          mov    al,0e7h            ; use 28 mHz dot clock
          out    dx,al              ; select it
          mov    dx,3c4h            ; sequencer again
          mov    ax,0300h           ; restart sequencer
          out    dx,ax              ; running again

          mov    dx,3d4h            ; alter crtc registers

          mov     al,11h            ; cr11
          out     dx,al             ; current value
          inc     dx                ; point to data
          in      al,dx             ; get cr11 value
          and     al,7fh            ; remove cr0 -> cr7
          out     dx,al             ; write protect
          dec     dx                ; point to index
          cld
          mov     si,offset vptbl
          mov     cx,((offset vpend)-(offset vptbl)) shr 1
    @b:   lodsw
          out     dx,ax
          loop    @b
          pop     di                ;restore C register vars
          pop     si
          ret
    _Set360x480Modeendp
    ;
    ; Draws a pixel in the specified color at the specified
    ; location in 360×480 256-color mode.
    ;
    ; Call as: void Draw360×480Dot(int X, int Y, int Color)
    ;
    ; Returns: nothing
    ;
    DParms     struc
          dw   ?            ;pushed BP
          dw   ?            ;return address
    DrawX dw   ?            ;X coordinate at which to draw
    DrawY dw   ?            ;Y coordinate at which to draw
    Color dw   ?            ;color in which to draw (in the
                            ; range 0-255; upper byte ignored)
    DParms     ends
    ;
          public _Draw360×480Dot
    _Draw360×480Dotprocnear
          push  bp            ;preserve caller’s BP
          mov   bp,sp         ;point to stack frame
          push  si            ;preserve C register vars
          push  di
          mov   ax,VGA_SEGMENT
          mov   es,ax         ;point to display memory
          mov   ax,SCREEN_WIDTH/4
                              ;there are 4 pixels at each address, so
                               ; each 360-pixel row is 90 bytes wide
                               ; in each plane
          mul   [bp+DrawY] ;point to start of desired row
          mov   di,[bp+DrawX] ;get the X coordinate
          shr   di,1           ;there are 4 pixels at each address
          shr   di,1           ; so divide the X coordinate by 4
          add   di,ax          ;point to the pixel’s address
          mov   cl,byte ptr [bp+DrawX] ;get the X coordinate again
          and   cl,3           ;get the plane # of the pixel
          mov   ah,1
          shl   ah,cl          ;set the bit corresponding to the plane
                               ; the pixel is in
          mov   al,MAP_MASK
          mov   dx,SC_INDEX
          OUT_WORD             ;set to write to the proper plane for
                               ; the pixel
          mov   al,byte ptr [bp+Color] ;get the color
          stosb                ;draw the pixel
          pop   di             ;restore C register vars
          pop   si
          pop   bp             ;restore caller’s BP
          ret
    _Draw360×480Dotendp
    ;
    ; Reads the color of the pixel at the specified
    ; location in 360×480 256-color mode.
    ;
    ; Call as: int Read360×480Dot(int X, int Y)
    ;
    ; Returns: pixel color
    ;
    RParms     struc
          dw   ?                ;pushed BP
          dw   ?                ;return address
    ReadX dw   ?                ;X coordinate from which to read
    ReadY dw   ?                ;Y coordinate from which to read
    RParms     ends
    ;
          public _Read360×480Dot
    _Read360×480Dotprocnear
          push  bp              ;preserve caller’s BP
          mov   bp,sp           ;point to stack frame
          push  si              ;preserve C register vars
          push  di
          mov   ax,VGA_SEGMENT
          mov   es,ax           ;point to display memory
          mov   ax,SCREEN_WIDTH/4 ;there are 4 pixels at each address, so
                                ; each 360-pixel row is 90 bytes wide
                                ; in each plane

           mul  [bp+DrawY] ;point to start of desired row
           mov  si,[bp+DrawX] ;get the X coordinate
           shr  si,1            ;there are 4 pixels at each address
           shr  si,1            ; so divide the X coordinate by 4
           add  si,ax           ;point to the pixel’s address
           mov  ah,byte ptr [bp+DrawX] ;get the X coordinate again
           and  ah,3
                                ;get the plane # of the pixel
           mov  al,READ_MAP
           mov  dx,GC_INDEX
           OUT_WORD             ;set to read from the proper plane for
                                ; the pixel
           lods byte ptr es:[si] ;read the pixel
           sub  ah,ah           ;make the return value a word for C
           pop  di              ;restore C register vars
           pop  si
           pop  bp              ;restore caller’s BP
           ret
    _Read360×480Dot  endp
    _TEX   Tends
           end

Previous | Table of Contents | Next

Graphics Programming Black Book © 2001 Michael Abrash