在装配中打印bmp后返回正常的BIOS调色板

时间:2015-06-02 06:55:10

标签: assembly colors x86-16 bios

我正在开发8086程序集中的游戏项目(在DOSBOX中)。

我有一个可以在图形模式下工作的蛇形游戏,以及一个可以在屏幕上打印BMP文件的菜单。

我唯一的问题是在打印过程中我将调色板更改为bmp调色板。

变色过程:

(这是将bmp打印到屏幕的代码的一部分)

proc ReadPalette
    ; Read BMP file color palette, 256 colors * 4 bytes (400h)
    mov ah,3fh
    mov cx,400h
    mov dx,offset Palette
    int 21h
    ret
endp ReadPalette

proc CopyPal
    ; Copy the colors palette to the video memory registers
    ; The number of the first color should be sent to port 3C8h
    ; The palette is sent to port 3C9h
    mov si,offset Palette
    mov cx,256
    mov dx,3C8h
    mov al,0
    ; Copy starting color to port 3C8h
    out dx,al
    ; Copy palette itself to port 3C9h
    inc dx
    PalLoop:
        ; Note: Colors in a BMP file are saved as BGR values rather than RGB.
        mov al,[si+2] ; Get red value.
        shr al,2 ; Max. is 255, but video palette maximal
         ; value is 63. Therefore dividing by 4.
        out dx,al ; Send it.
        mov al,[si+1] ; Get green value.
        shr al,2
        out dx,al ; Send it.
        mov al,[si] ; Get blue value.
        shr al,2
        out dx,al ; Send it.
        add si,4 ; Point to next color.
        ; (There is a null chr. after every color.)
        loop PalLoop
    ret
endp CopyPal

此代码不是我的,我所知道的是它改变了整个程序的调色板。

当我在打印图像后使用int 10h打印像素时,它仍在使用此调色板。

但是当我在打印任何图像之前打印一个像素时,该像素具有正常的BIOS颜色。

我想知道如何将调色板更改回BIOS调色板。

bmp调色板我发现:

bmp color palette I've found

2 个答案:

答案 0 :(得分:2)

您必须在更改之前保存BIOS标准调色板,然后在完成后将其存储回来。

执行此操作的示例代码可能是

;WORD Buffer Segment
;WORD Buffer  Offset
;DF = Direction of saving
SavePalette:
push bp
mov bp, sp

push es
push di
push ax
push dx
push cx

mov es, WORD [bp+06h]
mov di, WORD [bp+04h]

xor al, al
mov dx, 3c7h
out dx, al      ;Read from index 0

inc dx
inc dx
mov cx, 300h        ;3x256 reads
rep insb    

pop cx
pop dx
pop ax
pop di
pop es

pop bp
ret 04h


;WORD Buffer Segment
;WORD Buffer  Offset
;DF = Direction of loading
RestorePalette:
push bp
mov bp, sp

push ds
push si
push ax
push dx
push cx

mov ds, WORD [bp+06h]
mov si, WORD [bp+04h]

xor al, al
mov dx, 3c8h
out dx, al      ;Write from index 0

inc dx
mov cx, 300h        ;3x256 writes
rep outsb       

pop cx
pop dx
pop ax
pop si
pop ds

pop bp
ret 04h

要使用此代码,您需要一个300h字节的缓冲区,假设它被称为PaletteBuffer,它位于DS段。

push ds
push WORD PaletteBuffer
call SavePalette

;Change palette for bitmap

push ds
push WORD PaletteBuffer
call RestorePalette

值得注意的是,更改整个调色板的速度很慢,请考虑更改代码以仅保存/恢复所需的颜色(可能是前16个)或仅将位图颜色映射到高索引(如果它们小于256)号。

这也是NASM程序集,我还没有对代码进行测试,只是草拟了它,因为我不想设置DosBox。

答案 1 :(得分:0)

http://www.cs.cmu.edu/~ralf/files.html - > inter61a.zip - > INTERRUP.A

--------V-101017-----------------------------
INT 10 - VIDEO - READ BLOCK OF DAC REGISTERS (VGA/MCGA)
AX = 1017h
BX = starting palette register
CX = number of palette registers to read
ES:DX -> buffer (3 * CX bytes in size) (see also AX=1012h)
Return: buffer filled with CX red, green and blue triples
SeeAlso: AX=1012h,AX=1015h,INT 62/AX=00A4h

--------V-101012-----------------------------
INT 10 - VIDEO - SET BLOCK OF DAC REGISTERS (VGA/MCGA)
AX = 1012h
BX = starting color register
CX = number of registers to set
ES:DX -> table of 3*CX bytes where each 3 byte group represents one
     byte each of red, green and blue (0-63)
Return: nothing
SeeAlso: AX=1010h,AX=1017h,INT 62/AX=00A5h