home *** CD-ROM | disk | FTP | other *** search
/ Graphics Programming Black Book (Special Edition) / BlackBook.bin / disk1 / source / chapter34 / l34-1.asm next >
Assembly Source File  |  1997-06-18  |  7KB  |  254 lines

  1. ;
  2. ; Fills a band across the screen with vertical bars in all 256
  3. ; attributes, then cycles a portion of the palette until a key is
  4. ; pressed.
  5. ;
  6. ; Assembled with TASM 4.0, linked with TLINK 6.10
  7. ; Checked by Jim Mischel 11/21/94
  8. ;
  9. USE_BIOS equ    1      ;set to 1 to use BIOS functions to access the
  10.             ; DAC, 0 to read and write the DAC directly
  11. GUARD_AGAINST_INTS equ 1 ;1 to turn off interrupts and set write index
  12.             ; before loading each DAC location, 0 to rely
  13.             ; on the DAC auto-incrementing
  14. WAIT_VSYNC equ    1    ;set to 1 to wait for the leading edge of
  15.             ; vertical sync before accessing the DAC, 0
  16.             ; not to wait
  17. NOT_8088 equ    0    ;set to 1 to use REP INSB and REP OUTSB when
  18.             ; accessing the  DAC directly, 0 to use
  19.             ; IN/STOSB and LODSB/OUT
  20. CYCLE_SIZE     equ    256    ;# of DAC locations to cycle, 256 max
  21. SCREEN_SEGMENT     equ     0a000h     ;mode 13h display memory segment
  22. SCREEN_WIDTH_IN_BYTES equ 320     ;# of bytes across the screen in mode 13h
  23. INPUT_STATUS_1     equ     03dah     ;input status 1 register port
  24. DAC_READ_INDEX     equ     03c7h      ;DAC Read Index register
  25. DAC_WRITE_INDEX     equ     03c8h     ;DAC Write Index register
  26. DAC_DATA     equ    03c9h    ;DAC Data register
  27.  
  28. if NOT_8088
  29.     .286
  30. endif    ;NOT_8088
  31.  
  32.     .model    small
  33.     .stack    100h
  34.     .data
  35. ;Storage for all 256 DAC locations, organized as one three-byte
  36. ; (actually three 6-bit values; upper two bits of each byte aren't
  37. ; significant) RGB triplet per color.
  38. PaletteTemp    db    256*3 dup(?)
  39.     .code
  40. start:
  41.     mov    ax,@data
  42.     mov    ds,ax
  43.  
  44. ;Select VGA's standard 256-color graphics mode, mode 13h.
  45.     mov    ax,0013h    ;AH = 0: set mode function,
  46.     int    10h        ; AL = 13h: mode # to set
  47.  
  48. ;Read all 256 DAC locations into PaletteTemp (3 6-bit values, one
  49. ; each for red, green, and blue, per DAC location).
  50.  
  51. if WAIT_VSYNC
  52. ;Wait for the leading edge of the vertical sync pulse; this ensures
  53. ; that we read the DAC starting during the vertical non-display
  54. ; period.
  55.     mov    dx,INPUT_STATUS_1
  56. WaitNotVSync:            ;wait to be out of vertical sync
  57.     in    al,dx
  58.     and    al,08h
  59.     jnz    WaitNotVSync
  60. WaitVSync:            ;wait until vertical sync begins
  61.     in    al,dx
  62.     and    al,08h
  63.     jz    WaitVSync
  64. endif    ;WAIT_VSYNC
  65.  
  66. if USE_BIOS
  67.     mov    ax,1017h    ;AH = 10h: set DAC function,
  68.                 ; AL = 17h: read DAC block subfunction
  69.     sub    bx,bx        ;start with DAC location 0
  70.     mov    cx,256        ;read out all 256 locations
  71.     mov    dx,seg PaletteTemp
  72.     mov    es,dx
  73.     mov    dx,offset PaletteTemp ;point ES:DX to array in which
  74.                 ; the DAC values are to be stored
  75.     int    10h        ;read the DAC
  76. else    ;!USE_BIOS
  77.  if GUARD_AGAINST_INTS
  78.     mov    cx,CYCLE_SIZE    ;# of DAC locations to load
  79.     mov    di,seg PaletteTemp
  80.     mov    es,di
  81.     mov    di,offset PaletteTemp ;dump the DAC into this array
  82.     sub    ah,ah        ;start with DAC location 0
  83. DACStoreLoop:
  84.     mov    dx,DAC_READ_INDEX
  85.     mov    al,ah
  86.     cli
  87.     out    dx,al        ;set the DAC location #
  88.     mov    dx,DAC_DATA
  89.     in    al,dx        ;get the red component
  90.     stosb
  91.     in    al,dx        ;get the green component
  92.     stosb
  93.     in    al,dx        ;get the blue component
  94.     stosb
  95.     sti
  96.     inc    ah
  97.     loop    DACStoreLoop
  98.  else    ;!GUARD_AGAINST_INTS
  99.     mov    dx,DAC_READ_INDEX
  100.     sub    al,al
  101.     out    dx,al        ;set the initial DAC location to 0
  102.     mov    di,seg PaletteTemp
  103.     mov    es,di
  104.     mov    di,offset PaletteTemp ;dump the DAC into this array
  105.     mov    dx,DAC_DATA
  106.   if NOT_8088
  107.     mov    cx,CYCLE_SIZE*3
  108.     rep    insb        ;read CYCLE_SIZE DAC locations at once
  109.   else    ;!NOT_8088
  110.     mov    cx,CYCLE_SIZE    ;# of DAC locations to load
  111. DACStoreLoop:
  112.     in    al,dx        ;get the red component
  113.     stosb
  114.     in    al,dx        ;get the green component
  115.     stosb
  116.     in    al,dx        ;get the blue component
  117.     stosb
  118.     loop    DACStoreLoop
  119.   endif    ;NOT_8088
  120.  endif    ;GUARD_AGAINST_INTS
  121. endif    ;USE_BIOS
  122.  
  123. ;Draw a series of 1-pixel-wide vertical bars across the screen in
  124. ; attributes 1 through 255.
  125.     mov    ax,SCREEN_SEGMENT    
  126.     mov    es,ax
  127.     mov    di,50*SCREEN_WIDTH_IN_BYTES ;point ES:DI to the start
  128.                         ; of line 50 on the screen
  129.     cld
  130.     mov    dx,100            ;draw 100 lines high
  131. RowLoop:
  132.     mov    al,1            ;start each line with attr 1
  133.     mov    cx,SCREEN_WIDTH_IN_BYTES ;do a full line across
  134. ColumnLoop:
  135.     stosb                ;draw a pixel
  136.     add    al,1            ;increment the attribute
  137.     adc    al,0            ;if the attribute just turned
  138.                     ; over to 0, increment it to 1
  139.                     ; because we're not going to
  140.                     ; cycle DAC location 0, so
  141.                     ; attribute 0 won't change
  142.     loop    ColumnLoop
  143.     dec    dx
  144.     jnz    RowLoop
  145.  
  146. ;Cycle the specified range of DAC locations until a key is pressed.
  147. CycleLoop:
  148. ;Rotate colors 1-255 one position in the PaletteTemp array;
  149. ; location 0 is always left unchanged so that the background
  150. ; and border don't change.
  151.     push    word ptr PaletteTemp+(1*3)    ;set aside PaletteTemp
  152.     push    word ptr PaletteTemp+(1*3)+2    ; setting for attr 1
  153.     mov    cx,254                
  154.     mov    si,offset PaletteTemp+(2*3)
  155.     mov    di,offset PaletteTemp+(1*3)
  156.     mov    ax,ds
  157.     mov    es,ax
  158.     mov    cx,254*3/2
  159.     rep    movsw            ;rotate PaletteTemp settings
  160.                     ; for attrs 2 through 255 to
  161.                     ; attrs 1 through 254
  162.     pop    bx            ;get back original settings
  163.     pop    ax            ; for attribute 1 and move
  164.     stosw                ; them to the PaletteTemp
  165.     mov    es:[di],bl        ; location for attribute 255
  166.  
  167. if WAIT_VSYNC
  168. ;Wait for the leading edge of the vertical sync pulse; this ensures
  169. ; that we reload the DAC starting during the vertical non-display
  170. ; period.
  171.     mov    dx,INPUT_STATUS_1
  172. WaitNotVSync2:            ;wait to be out of vertical sync
  173.     in    al,dx
  174.     and    al,08h
  175.     jnz    WaitNotVSync2
  176. WaitVSync2:            ;wait until vertical sync begins
  177.     in    al,dx
  178.     and    al,08h
  179.     jz    WaitVSync2
  180. endif    ;WAIT_VSYNC
  181.  
  182. if USE_BIOS
  183. ;Set the new, rotated palette.
  184.     mov    ax,1012h    ;AH = 10h: set DAC function,
  185.                 ; AL = 12h: set DAC block subfunction
  186.     sub    bx,bx        ;start with DAC location 0
  187.     mov    cx,CYCLE_SIZE    ;# of DAC locations to set
  188.     mov    dx,seg PaletteTemp
  189.     mov    es,dx
  190.     mov    dx,offset PaletteTemp ;point ES:DX to array from which
  191.                 ; to load the DAC
  192.     int    10h        ;load the DAC
  193. else    ;!USE_BIOS
  194.  if GUARD_AGAINST_INTS
  195.     mov    cx,CYCLE_SIZE    ;# of DAC locations to load
  196.     mov    si,offset PaletteTemp ;load the DAC from this array
  197.     sub    ah,ah        ;start with DAC location 0
  198. DACLoadLoop:
  199.     mov    dx,DAC_WRITE_INDEX
  200.     mov    al,ah
  201.     cli
  202.     out    dx,al        ;set the DAC location #
  203.     mov    dx,DAC_DATA
  204.     lodsb
  205.     out    dx,al        ;set the red component
  206.     lodsb
  207.     out    dx,al        ;set the green component
  208.     lodsb
  209.     out    dx,al        ;set the blue component
  210.     sti
  211.     inc    ah
  212.     loop    DACLoadLoop
  213.  else    ;!GUARD_AGAINST_INTS
  214.     mov    dx,DAC_WRITE_INDEX
  215.     sub    al,al
  216.     out    dx,al        ;set the initial DAC location to 0
  217.     mov    si,offset PaletteTemp ;load the DAC from this array
  218.     mov    dx,DAC_DATA
  219.   if NOT_8088
  220.     mov    cx,CYCLE_SIZE*3
  221.     rep    outsb        ;load CYCLE_SIZE DAC locations at once
  222.   else    ;!NOT_8088
  223.     mov    cx,CYCLE_SIZE    ;# of DAC locations to load
  224. DACLoadLoop:
  225.     lodsb
  226.     out    dx,al        ;set the red component
  227.     lodsb
  228.     out    dx,al        ;set the green component
  229.     lodsb
  230.     out    dx,al        ;set the blue component
  231.     loop    DACLoadLoop
  232.   endif    ;NOT_8088
  233.  endif    ;GUARD_AGAINST_INTS
  234. endif    ;USE_BIOS
  235.  
  236. ;See if a key has been pressed.
  237.     mov    ah,0bh        ;DOS check standard input status fn
  238.     int    21h
  239.     and    al,al        ;is a key pending?
  240.     jz    CycleLoop    ;no, cycle some more
  241.  
  242. ;Clear the keypress.
  243.     mov    ah,1        ;DOS keyboard input fn
  244.     int    21h
  245.  
  246. ;Restore text mode and done.
  247.     mov    ax,0003h    ;AH = 0: set mode function,
  248.     int    10h        ; AL = 03h: mode # to set
  249.     mov    ah,4ch        ;DOS terminate process fn
  250.     int    21h
  251.  
  252.     end    start
  253.  
  254.