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

  1. ; Program to demonstrate pixel drawing in 320x400 256-color
  2. ; mode on the VGA. Draws 8 lines to form an octagon, a pixel
  3. ; at a time. Draws 8 octagons in all, one on top of the other,
  4. ; each in a different color set. Although it's not used, a
  5. ; pixel read function is also provided.
  6. ;
  7. ; Updated 6/29/89.
  8. ;
  9. VGA_SEGMENT     equ     0a000h
  10. SC_INDEX        equ     3c4h    ;Sequence Controller Index register
  11. GC_INDEX        equ     3ceh    ;Graphics Controller Index register
  12. CRTC_INDEX      equ     3d4h    ;CRT Controller Index register
  13. MAP_MASK        equ     2       ;Map Mask register index in SC
  14. MEMORY_MODE     equ     4       ;Memory Mode register index in SC
  15. MAX_SCAN_LINE   equ     9       ;Maximum Scan Line reg index in CRTC
  16. START_ADDRESS_HIGH equ  0ch     ;Start Address High reg index in CRTC
  17. UNDERLINE       equ     14h     ;Underline Location reg index in CRTC
  18. MODE_CONTROL    equ     17h     ;Mode Control register index in CRTC
  19. READ_MAP        equ     4       ;Read Map register index in GC
  20. GRAPHICS_MODE   equ     5       ;Graphics Mode register index in GC
  21. MISCELLANEOUS   equ     6       ;Miscellaneous register index in GC
  22. SCREEN_WIDTH    equ     320     ;# of pixels across screen
  23. SCREEN_HEIGHT   equ     400     ;# of scan lines on screen
  24. WORD_OUTS_OK    equ     1       ;set to 0 to assemble for
  25.                                 ; computers that can't handle
  26.                                 ; word outs to indexed VGA registers
  27. ;
  28. stackseg        segment para stack 'STACK'
  29.         db      512 dup (?)
  30. stackseg        ends
  31. ;
  32. Data    segment word 'DATA'
  33. ;
  34. BaseColor       db      0
  35. ;
  36. ; Structure used to control drawing of a line.
  37. ;
  38. LineControl     struc
  39. StartX          dw      ?
  40. StartY          dw      ?
  41. LineXInc        dw      ?
  42. LineYInc        dw      ?
  43. BaseLength      dw      ?
  44. LineColor       db      ?
  45. LineControl     ends
  46. ;
  47. ; List of descriptors for lines to draw.
  48. ;
  49. LineList        label   LineControl
  50.         LineControl     <130,110,1,0,60,0>
  51.         LineControl     <190,110,1,1,60,1>
  52.         LineControl     <250,170,0,1,60,2>
  53.         LineControl     <250,230,-1,1,60,3>
  54.         LineControl     <190,290,-1,0,60,4>
  55.         LineControl     <130,290,-1,-1,60,5>
  56.         LineControl     <70,230,0,-1,60,6>
  57.         LineControl     <70,170,1,-1,60,7>
  58.         LineControl     <-1,0,0,0,0,0>
  59. Data    ends
  60. ;
  61. ; Macro to output a word value to a port.
  62. ;
  63. OUT_WORD        macro
  64. if WORD_OUTS_OK
  65.         out     dx,ax
  66. else
  67.         out     dx,al
  68.         inc     dx
  69.         xchg    ah,al
  70.         out     dx,al
  71.         dec     dx
  72.         xchg    ah,al
  73. endif
  74.         endm
  75. ;
  76. ; Macro to output a constant value to an indexed VGA register.
  77. ;
  78. CONSTANT_TO_INDEXED_REGISTER    macro   ADDRESS, INDEX, VALUE
  79.         mov     dx,ADDRESS
  80.         mov     ax,(VALUE shl 8) + INDEX
  81.         OUT_WORD
  82.         endm
  83. ;
  84. Code    segment
  85.         assume  cs:Code, ds:Data
  86. Start   proc    near
  87.         mov     ax,Data
  88.         mov     ds,ax
  89. ;
  90. ; Set 320x400 256-color mode.
  91. ;
  92.         call    Set320By400Mode
  93. ;
  94. ; We're in 320x400 256-color mode. Draw each line in turn.
  95. ;
  96. ColorLoop:
  97.         mov     si,offset LineList ;point to the start of the
  98.                                    ; line descriptor list
  99. LineLoop:
  100.         mov     cx,[si+StartX]  ;set the initial X coordinate
  101.         cmp     cx,-1
  102.         jz      LinesDone       ;a descriptor with a -1 X
  103.                                 ; coordinate marks the end
  104.                                 ; of the list
  105.         mov     dx,[si+StartY]     ;set the initial Y coordinate,
  106.         mov     bl,[si+LineColor]  ; line color,
  107.         mov     bp,[si+BaseLength] ; and pixel count
  108.         add     bl,[BaseColor]  ;adjust the line color according
  109.                                 ; to BaseColor
  110. PixelLoop:
  111.         push    cx              ;save the coordinates
  112.         push    dx
  113.         call    WritePixel      ;draw this pixel
  114.         pop     dx              ;retrieve the coordinates
  115.         pop     cx
  116.         add     cx,[si+LineXInc] ;set the coordinates of the
  117.         add     dx,[si+LineYInc] ; next point of the line
  118.         dec     bp              ;any more points?
  119.         jnz     PixelLoop       ;yes, draw the next
  120.         add     si,size LineControl ;point to the next line descriptor
  121.         jmp     LineLoop        ; and draw the next line
  122. LinesDone:
  123.         call    GetNextKey      ;wait for a key, then
  124.         inc     [BaseColor]     ; bump the color selection and
  125.         cmp     [BaseColor],8   ; see if we're done
  126.         jb      ColorLoop       ;not done yet
  127. ;
  128. ; Return to text mode.
  129. ;
  130.         mov     ax,0003h
  131.         int     10h     ;text mode
  132.         mov     ah,4ch
  133.         int     21h     ;done
  134. ;
  135. Start   endp
  136. ;
  137. ; Sets up 320x400 256-color modes.
  138. ;
  139. ; Input: none
  140. ;
  141. ; Output: none
  142. ;
  143. Set320By400Mode proc    near
  144. ;
  145. ; First, go to normal 320x200 256-color mode, which is really a
  146. ; 320x400 256-color mode with each line scanned twice.
  147. ;
  148.         mov     ax,0013h  ;AH = 0 means mode set, AL = 13h selects
  149.                           ; 256-color graphics mode
  150.         int     10h       ;BIOS video interrupt
  151. ;
  152. ; Change CPU addressing of video memory to linear (not odd/even,
  153. ; chain, or chain 4), to allow us to access all 256K of display
  154. ; memory. When this is done, VGA memory will look just like memory
  155. ; in modes 10h and 12h, except that each byte of display memory will
  156. ; control one 256-color pixel, with 4 adjacent pixels at any given
  157. ; address, one pixel per plane.
  158. ;
  159.         mov     dx,SC_INDEX
  160.         mov     al,MEMORY_MODE
  161.         out     dx,al
  162.         inc     dx
  163.         in      al,dx
  164.         and     al,not 08h      ;turn off chain 4
  165.         or      al,04h          ;turn off odd/even
  166.         out     dx,al
  167.         mov     dx,GC_INDEX
  168.         mov     al,GRAPHICS_MODE
  169.         out     dx,al
  170.         inc     dx
  171.         in      al,dx
  172.         and     al,not 10h      ;turn off odd/even
  173.         out     dx,al
  174.         dec     dx
  175.         mov     al,MISCELLANEOUS
  176.         out     dx,al
  177.         inc     dx
  178.         in      al,dx
  179.         and     al,not 02h      ;turn off chain
  180.         out     dx,al
  181. ;
  182. ; Now clear the whole screen, since the mode 13h mode set only
  183. ; cleared 64K out of the 256K of display memory. Do this before
  184. ; we switch the CRTC out of mode 13h, so we don't see garbage
  185. ; on the screen when we make the switch.
  186. ;
  187.         CONSTANT_TO_INDEXED_REGISTER SC_INDEX,MAP_MASK,0fh
  188.                                 ;enable writes to all planes, so
  189.                                 ; we can clear 4 pixels at a time
  190.         mov     ax,VGA_SEGMENT
  191.         mov     es,ax
  192.         sub     di,di
  193.         mov     ax,di
  194.         mov     cx,8000h        ;# of words in 64K
  195.         cld
  196.         rep     stosw           ;clear all of display memory
  197. ;
  198. ; Tweak the mode to 320x400 256-color mode by not scanning each
  199. ; line twice.
  200. ;
  201.         mov     dx,CRTC_INDEX
  202.         mov     al,MAX_SCAN_LINE
  203.         out     dx,al
  204.         inc     dx
  205.         in      al,dx
  206.         and     al,not 1fh      ;set maximum scan line = 0
  207.         out     dx,al
  208.         dec     dx
  209. ;
  210. ; Change CRTC scanning from doubleword mode to byte mode, allowing
  211. ; the CRTC to scan more than 64K of video data.
  212. ;
  213.         mov     al,UNDERLINE
  214.         out     dx,al
  215.         inc     dx
  216.         in      al,dx
  217.         and     al,not 40h      ;turn off doubleword
  218.         out     dx,al
  219.         dec     dx
  220.         mov     al,MODE_CONTROL
  221.         out     dx,al
  222.         inc     dx
  223.         in      al,dx
  224.         or      al,40h  ;turn on the byte mode bit, so memory is
  225.                         ; scanned for video data in a purely
  226.                         ; linear way, just as in modes 10h and 12h
  227.         out     dx,al
  228.         ret
  229. Set320By400Mode endp
  230. ;
  231. ; Draws a pixel in the specified color at the specified
  232. ; location in 320x400 256-color mode.
  233. ;
  234. ; Input:
  235. ;       CX = X coordinate of pixel
  236. ;       DX = Y coordinate of pixel
  237. ;       BL = pixel color
  238. ;
  239. ; Output: none
  240. ;
  241. ; Registers altered: AX, CL, DX, DI, ES
  242. ;
  243. WritePixel      proc    near
  244.         mov     ax,VGA_SEGMENT
  245.         mov     es,ax   ;point to display memory
  246.         mov     ax,SCREEN_WIDTH/4
  247.                         ;there are 4 pixels at each address, so
  248.                         ; each 320-pixel row is 80 bytes wide
  249.                         ; in each plane
  250.         mul     dx      ;point to start of desired row
  251.         push    cx      ;set aside the X coordinate
  252.         shr     cx,1    ;there are 4 pixels at each address
  253.         shr     cx,1    ; so divide the X coordinate by 4
  254.         add     ax,cx   ;point to the pixel's address
  255.         mov     di,ax
  256.         pop     cx      ;get back the X coordinate
  257.         and     cl,3    ;get the plane # of the pixel
  258.         mov     ah,1
  259.         shl     ah,cl   ;set the bit corresponding to the plane
  260.                         ; the pixel is in
  261.         mov     al,MAP_MASK
  262.         mov     dx,SC_INDEX
  263.         OUT_WORD        ;set to write to the proper plane for
  264.                         ; the pixel
  265.         mov     es:[di],bl      ;draw the pixel
  266.         ret
  267. WritePixel      endp
  268. ;
  269. ; Reads the color of the pixel at the specified location in 320x400
  270. ; 256-color mode.
  271. ;
  272. ; Input:
  273. ;       CX = X coordinate of pixel to read
  274. ;       DX = Y coordinate of pixel to read
  275. ;
  276. ; Output:
  277. ;       AL = pixel color
  278. ;
  279. ; Registers altered: AX, CX, DX, SI, ES
  280. ;
  281. ReadPixel       proc    near
  282.         mov     ax,VGA_SEGMENT
  283.         mov     es,ax   ;point to display memory
  284.         mov     ax,SCREEN_WIDTH/4
  285.                         ;there are 4 pixels at each address, so
  286.                         ; each 320-pixel row is 80 bytes wide
  287.                         ; in each plane
  288.         mul     dx      ;point to start of desired row
  289.         push    cx      ;set aside the X coordinate
  290.         shr     cx,1    ;there are 4 pixels at each address
  291.         shr     cx,1    ; so divide the X coordinate by 4
  292.         add     ax,cx   ;point to the pixel's address
  293.         mov     si,ax
  294.         pop     ax      ;get back the X coordinate
  295.         and     al,3    ;get the plane # of the pixel
  296.         mov     ah,al
  297.         mov     al,READ_MAP
  298.         mov     dx,GC_INDEX
  299.         OUT_WORD        ;set to read from the proper plane for
  300.                         ; the pixel
  301.         lods    byte ptr es:[si] ;read the pixel
  302.         ret
  303. ReadPixel       endp
  304. ;
  305. ; Waits for the next key and returns it in AX.
  306. ;
  307. ; Input: none
  308. ;
  309. ; Output:
  310. ;       AX = full 16-bit code for key pressed
  311. ;
  312. GetNextKey      proc    near
  313. WaitKey:
  314.         mov     ah,1
  315.         int     16h
  316.         jz      WaitKey ;wait for a key to become available
  317.         sub     ah,ah
  318.         int     16h     ;read the key
  319.         ret
  320. GetNextKey      endp
  321. ;
  322. Code    ends
  323. ;
  324.         end     Start