Announcement

Collapse
No announcement yet.

Palette changes via Interrupt: Incompatible color numbers

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Palette changes via Interrupt: Incompatible color numbers

    In SCREEN 12, I tried to modify the RGB values of the displayed colors
    using Interrupt &H10, as such modifications seem not to be possible
    with the PALETTE statement. But I discovered that the color numbers
    used by the Interrupt services were not identical with the color numbers
    used by PowerBasic. To verify this, I wrote a small test program which
    is reproduced below. I found that color numbers 0 to 5 and 7 were
    identical, but in order to change the color no.6, I had to input 20
    (decimal), and for changing colors 8 to 15, I had to input numbers
    from 56 to 63.
    This anomaly occurred only when setting the screen mode with the SCREEN
    statement, but not in a similar program which sets the screen mode via
    Interrupt &H10, (In that case, of course, the graphics statements like
    LINE, PAINT, etc. are not available.) Neither did it occur in QuickBasic,
    only in PowerBasic.
    Now my question: Is this anomaly inherent to PowerBasic, so that it
    will produce the same results on all VGA systems, or might it depend on
    the BIOS type, the video card, or some other factor beyond my control?
    I would like to implement palette changes in a program, but I need to
    be sure it will not produce unexpected results on different systems.

    Hans Ruegg

    '=========== TEST PROGRAM "BLINK" ================
    'Lets the user input a color index and lets the corresponding
    'color blink for half a second.
    'Input of a negative index will terminate the program.

    SCREEN 12
    GOSUB displayColors
    DO
    GOSUB changeColor
    LOOP UNTIL indx%<0
    SCREEN 0
    END

    displayColors: 'display squares in all 16 colors
    FOR row%=0 TO 3: FOR colu%=0 TO 3
    cl% = 4*row%+colu%
    LINE (48*colu%, 48*row%)-(48*colu%+45, 48*row%+45), cl%, BF
    LOCATE 3*row%+2, 6*colu%+3: PRINT TRIM$(STR$(cl%));
    NEXT colu%: NEXT row%
    RETURN

    changeColor:
    LOCATE 25,1: PRINT "No. to change: "
    LOCATE 25,15: INPUT indx%
    IF indx%<0 THEN RETURN
    blink indx%
    RETURN

    '=============================================================

    SUB blink (ind%)
    'Lets the color no. ind% blink for half a second in its opposite color

    getDAC ind%, red%, green%, blue%
    putDAC ind%, red% XOR 63, green% XOR 63, blue% XOR 63
    t!=TIMER
    DO: LOOP UNTIL TIMER>t!+0.5
    putDAC ind%, red%, green%, blue%
    END SUB

    SUB putDAC (ind%, red%, green%, blue%)
    'Sets new RGB values in the VGA palette for color no. ind%

    REG 1, &H1010
    REG 2, ind%
    REG 3, 256*green% + blue%
    REG 4, 256*red%
    CALL INTERRUPT &H10
    END SUB

    SUB getDAC (ind%, red%, green%, blue%)
    'Retrieves the RGB values of the current VGA palette for color no. ind%

    REG 1, &H1015
    REG 2, ind%
    CALL INTERRUPT &H10
    gb% = REG(3)
    green% = gb%\256: blue% = gb% AND 255
    red% = REG(4)\256
    END SUB

    '============================================================


  • #2
    Hans,

    We covered this topic in some detail a few years ago in BASICally Speaking. You might wish to take a look at our back issue list ( http://www.infoms.com/backiss.htm ) and download some source code from the online archives ( http://www.infoms.com/archives.htm ). Back issues cost $4.00 each, but you cam download the code for free.

    Alan

    ------------------
    Alan C. Earnshaw
    Information Management Systems, Inc.
    http://www.infoms.com
    Alan C. Earnshaw
    Information Management Systems, Inc.
    http://www.infoms.com

    Comment


    • #3
      Hans Ruegg.


      Thank you, Alan, for your hints! I found the corresponding source code
      which covered the gap in my knowledge: Interrupt 10h, function 1007h
      to retrieve the DAC register numbers associated with the palette
      indices. Besides, I found that there is also a function 1000h which
      allows to associate the register numbers with new palette indices.
      So I prefer to set all 15 color indices to their corresponding register
      numbers during my program. (Example code below, using part of your
      source code.) This works in SCREEN 12, and I suppose it should work
      also in a DOS mode text screen.
      However, it does NOT work in a DOS Text window under Windows (neither
      does the Fade routine on your site). It seems that Windows has a
      different way of definig the colors in a DOS box. Maybe somebody has
      investigated this point?

      Hans Ruegg.

      Code:
      '=================================================================
      'Code to set DAC Register Numbers to corresponding Palette indices
      '=================================================================
      DIM Regis?(0 TO 15)
      DIM Settings?(0 TO 15, 0 TO 2)
      
      SCREEN 12
      
      FOR c? = 0 TO 15
        Regis?(c?) = WhichRegister?(c?)
        getDAC Regis?(c?), Settings?(c?,0), Settings?(c?,1), Settings?(c?,2)
        SetRegister c?, c?
      NEXT c?
      
      '===============================================================
      'Modify here the palette settings as you like.
      'Register numbers 0 to 15 correspond now to color indices 0 to 15.
      'Following code is an example.
      
      CLS
      FOR c? = 0 TO 15
        COLOR c?
        PRINT "COLOR "; c?
        LINE (320,16*c?)-(400,16*c?+14),c?,BF
      NEXT c?
      PRINT "Press any key to modify palette:"
      DO: LOOP WHILE INKEY$=""
      
      'Set a palette shifting gradually from blue to orange:
      FOR c? = 0 TO 15   
        putDAC c?, 4*c?, 16+c?, 63-4*c?
      NEXT c?
      
      PRINT "Press any key to restore palette:"
      DO: LOOP WHILE INKEY$=""
      
      '==============================================================
      ' Restore original settings
      '==============================================================
      FOR c? = 0 TO 15
        SetRegister c?, Regis?(c?)
        putDAC Regis?(c?), Settings?(c?, 0), Settings?(c?, 1), Settings?(c?, 2)
      NEXT c?
      
      DO: LOOP WHILE INKEY$=""
      SCREEN 0
      END
      
      '======================================================================
      SUB SetRegister(BYVAL Attribute?, BYVAL Register?)
      
        ASM mov ax, &H1000       ; function 10h, subfunction 00h
        ASM mov bh, Register?    ; register to set
        ASM mov bl, Attribute?   ; attribute to set
        ASM int &H10             ; call BIOS services
      
      END SUB
      
      
      ' Which DAC Register Is Used for each Attribute
      FUNCTION WhichRegister?(BYVAL Register?)
      
        ASM mov ax, &H1007       ; function 10h, subfunction 07h
        ASM mov bl, Register?    ; register to check
        ASM int &H10             ; call BIOS services
        ASM mov FUNCTION, bh     ; set return value of function
      
      END FUNCTION
      
      SUB putDAC (ind?, red?, green?, blue?)
      'Sets new RGB values in the VGA palette for color no. ind%
      
      REG 1, &H1010
      REG 2, ind?
      REG 3, 256*green? + blue?
      REG 4, 256*red?
      CALL INTERRUPT &H10
      END SUB
      
      SUB getDAC (ind?, red?, green?, blue?)
      'Retrieves the RGB values of the current VGA palette for color no. ind%
      
      REG 1, &H1015
      REG 2, ind?
      CALL INTERRUPT &H10
      gb% = REG(3)
      green? = gb%\256: blue? = gb% AND 255
      red? = REG(4)\256
      END SUB
      
      '============================================================
      * UUB tags added by administrator

      Comment

      Working...
      X