home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 15 / CDACTUAL15.iso / cdactual / program / asm / PJGRAPH.ZIP / CHAP13.1 < prev    next >
Encoding:
Text File  |  1989-09-26  |  7.7 KB  |  220 lines

  1. ; Turbo C tiny/small/medium model-callable assembler
  2. ; subroutines to:
  3. ;       * Set 360x480 256-color VGA mode
  4. ;       * Draw a dot in 360x480 256-color VGA mode
  5. ;       * Read the color of a dot in 360x480 256-color VGA mode
  6. ;
  7. ; Assemble and link with the program of Listing 13.2 with a command
  8. ; line like:
  9. ;
  10. ;       tcc lst13-2 lst13-3.asm
  11. ;
  12. ; (requires Turbo C and either TASM or MASM).
  13. ;
  14. ; Assembled with TASM 1.0.
  15. ;
  16. ; Updated 6/30/89.
  17. ;
  18. ; The 360x480 256-color mode set code and parameters were provided
  19. ; by John Bridges, who has placed them into the public domain.
  20. ;
  21. VGA_SEGMENT     equ     0a000h  ;display memory segment
  22. SC_INDEX        equ     3c4h    ;Sequence Controller Index register
  23. GC_INDEX        equ     3ceh    ;Graphics Controller Index register
  24. MAP_MASK        equ     2       ;Map Mask register index in SC
  25. READ_MAP        equ     4       ;Read Map register index in GC
  26. SCREEN_WIDTH    equ     360     ;# of pixels across screen
  27. WORD_OUTS_OK    equ     1       ;set to 0 to assemble for
  28.                                 ; computers that can't handle
  29.                                 ; word outs to indexed VGA registers
  30. ;
  31. _DATA   segment public byte 'DATA'
  32. ;
  33. ; 360x480 256-color mode CRT Controller register settings.
  34. ; (Courtesy of John Bridges.)
  35. ;
  36. vptbl   dw      06b00h  ; horz total
  37.         dw      05901h  ; horz displayed
  38.         dw      05a02h  ; start horz blanking
  39.         dw      08e03h  ; end horz blanking
  40.         dw      05e04h  ; start h sync
  41.         dw      08a05h  ; end h sync
  42.         dw      00d06h  ; vertical total
  43.         dw      03e07h  ; overflow
  44.         dw      04009h  ; cell height
  45.         dw      0ea10h  ; v sync start
  46.         dw      0ac11h  ; v sync end and protect cr0-cr7
  47.         dw      0df12h  ; vertical displayed
  48.         dw      02d13h  ; offset
  49.         dw      00014h  ; turn off dword mode
  50.         dw      0e715h  ; v blank start
  51.         dw      00616h  ; v blank end
  52.         dw      0e317h  ; turn on byte mode
  53. vpend   label   word
  54. _DATA   ends
  55. ;
  56. ; Macro to output a word value to a port.
  57. ;
  58. OUT_WORD        macro
  59. if WORD_OUTS_OK
  60.         out     dx,ax
  61. else
  62.         out     dx,al
  63.         inc     dx
  64.         xchg    ah,al
  65.         out     dx,al
  66.         dec     dx
  67.         xchg    ah,al
  68. endif
  69.         endm
  70. ;
  71. _TEXT   segment byte public 'CODE'
  72.         assume  cs:_TEXT, ds:_DATA
  73. ;
  74. ; Sets up 360x480 256-color mode.
  75. ; (Courtesy of John Bridges.)
  76. ;
  77. ; Call as: void Set360By480Mode()
  78. ;
  79. ; Returns: nothing
  80. ;
  81.         public _Set360x480Mode
  82. _Set360x480Mode proc    near
  83.         push    si              ;preserve C register vars
  84.         push    di
  85.         mov     ax,12h          ; start with mode 12h
  86.         int     10h             ; let the bios clear the video memory
  87.  
  88.         mov     ax,13h          ; start with standard mode 13h
  89.         int     10h             ; let the bios set the mode
  90.  
  91.         mov     dx,3c4h         ; alter sequencer registers
  92.         mov     ax,0604h        ; disable chain 4
  93.         out     dx,ax
  94.  
  95.         mov     ax,0100h        ; synchronous reset
  96.         out     dx,ax           ; asserted
  97.         mov     dx,3c2h         ; misc output
  98.         mov     al,0e7h         ; use 28 mHz dot clock
  99.         out     dx,al           ; select it
  100.         mov     dx,3c4h         ; sequencer again
  101.         mov     ax,0300h        ; restart sequencer
  102.         out     dx,ax           ; running again
  103.  
  104.         mov     dx,3d4h         ; alter crtc registers
  105.  
  106.         mov     al,11h          ; cr11
  107.         out     dx,al           ; current value
  108.         inc     dx              ; point to data
  109.         in      al,dx           ; get cr11 value
  110.         and     al,7fh          ; remove cr0 -> cr7
  111.         out     dx,al           ;    write protect
  112.         dec     dx              ; point to index
  113.         cld
  114.         mov     si,offset vptbl
  115.         mov     cx,((offset vpend)-(offset vptbl)) shr 1
  116. @b:     lodsw
  117.         out     dx,ax
  118.         loop    @b
  119.         pop     di              ;restore C register vars
  120.         pop     si
  121.         ret
  122. _Set360x480Mode endp
  123. ;
  124. ; Draws a pixel in the specified color at the specified
  125. ; location in 360x480 256-color mode.
  126. ;
  127. ; Call as: void Draw360x480Dot(int X, int Y, int Color)
  128. ;
  129. ; Returns: nothing
  130. ;
  131. DParms  struc
  132.         dw      ?       ;pushed BP
  133.         dw      ?       ;return address
  134. DrawX   dw      ?       ;X coordinate at which to draw
  135. DrawY   dw      ?       ;Y coordinate at which to draw
  136. Color   dw      ?       ;color in which to draw (in the
  137.                         ; range 0-255; upper byte ignored)
  138. DParms  ends
  139. ;
  140.         public _Draw360x480Dot
  141. _Draw360x480Dot proc    near
  142.         push    bp      ;preserve caller's BP
  143.         mov     bp,sp   ;point to stack frame
  144.         push    si      ;preserve C register vars
  145.         push    di
  146.         mov     ax,VGA_SEGMENT
  147.         mov     es,ax   ;point to display memory
  148.         mov     ax,SCREEN_WIDTH/4
  149.                         ;there are 4 pixels at each address, so
  150.                         ; each 360-pixel row is 90 bytes wide
  151.                         ; in each plane
  152.         mul     [bp+DrawY] ;point to start of desired row
  153.         mov     di,[bp+DrawX] ;get the X coordinate
  154.         shr     di,1    ;there are 4 pixels at each address
  155.         shr     di,1    ; so divide the X coordinate by 4
  156.         add     di,ax   ;point to the pixel's address
  157.         mov     cl,byte ptr [bp+DrawX] ;get the X coordinate again
  158.         and     cl,3    ;get the plane # of the pixel
  159.         mov     ah,1
  160.         shl     ah,cl   ;set the bit corresponding to the plane
  161.                         ; the pixel is in
  162.         mov     al,MAP_MASK
  163.         mov     dx,SC_INDEX
  164.         OUT_WORD        ;set to write to the proper plane for
  165.                         ; the pixel
  166.         mov     al,byte ptr [bp+Color]  ;get the color
  167.         stosb           ;draw the pixel
  168.         pop     di      ;restore C register vars
  169.         pop     si
  170.         pop     bp      ;restore caller's BP
  171.         ret
  172. _Draw360x480Dot endp
  173. ;
  174. ; Reads the color of the pixel at the specified
  175. ; location in 360x480 256-color mode.
  176. ;
  177. ; Call as: int Read360x480Dot(int X, int Y)
  178. ;
  179. ; Returns: pixel color
  180. ;
  181. RParms  struc
  182.         dw      ?       ;pushed BP
  183.         dw      ?       ;return address
  184. ReadX   dw      ?       ;X coordinate from which to read
  185. ReadY   dw      ?       ;Y coordinate from which to read
  186. RParms  ends
  187. ;
  188.         public _Read360x480Dot
  189. _Read360x480Dot proc    near
  190.         push    bp      ;preserve caller's BP
  191.         mov     bp,sp   ;point to stack frame
  192.         push    si      ;preserve C register vars
  193.         push    di
  194.         mov     ax,VGA_SEGMENT
  195.         mov     es,ax   ;point to display memory
  196.         mov     ax,SCREEN_WIDTH/4
  197.                         ;there are 4 pixels at each address, so
  198.                         ; each 360-pixel row is 90 bytes wide
  199.                         ; in each plane
  200.         mul     [bp+DrawY] ;point to start of desired row
  201.         mov     si,[bp+DrawX] ;get the X coordinate
  202.         shr     si,1    ;there are 4 pixels at each address
  203.         shr     si,1    ; so divide the X coordinate by 4
  204.         add     si,ax   ;point to the pixel's address
  205.         mov     ah,byte ptr [bp+DrawX]
  206.                         ;get the X coordinate again
  207.         and     ah,3    ;get the plane # of the pixel
  208.         mov     al,READ_MAP
  209.         mov     dx,GC_INDEX
  210.         OUT_WORD        ;set to read from the proper plane for
  211.                         ; the pixel
  212.         lods    byte ptr es:[si] ;read the pixel
  213.         sub     ah,ah   ;make the return value a word for C
  214.         pop     di      ;restore C register vars
  215.         pop     si
  216.         pop     bp      ;restore caller's BP
  217.         ret
  218. _Read360x480Dot endp
  219. _TEXT   ends
  220.         end