1222 lines
38 KiB
Plaintext
1222 lines
38 KiB
Plaintext
![]() |
;
|
||
|
; Command & Conquer Red Alert(tm)
|
||
|
; Copyright 2025 Electronic Arts Inc.
|
||
|
;
|
||
|
; This program is free software: you can redistribute it and/or modify
|
||
|
; it under the terms of the GNU General Public License as published by
|
||
|
; the Free Software Foundation, either version 3 of the License, or
|
||
|
; (at your option) any later version.
|
||
|
;
|
||
|
; This program is distributed in the hope that it will be useful,
|
||
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
; GNU General Public License for more details.
|
||
|
;
|
||
|
; You should have received a copy of the GNU General Public License
|
||
|
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
;
|
||
|
|
||
|
;****************************************************************************
|
||
|
;*
|
||
|
;* C O N F I D E N T I A L -- W E S T W O O D S T U D I O S
|
||
|
;*
|
||
|
;*---------------------------------------------------------------------------
|
||
|
;*
|
||
|
;* PROJECT
|
||
|
;* VQA player library.
|
||
|
;*
|
||
|
;* FILE
|
||
|
;* UnVQ4x2.asm
|
||
|
;*
|
||
|
;* DESCRIPTION
|
||
|
;* 4x2 VQ decompress/draw routines.
|
||
|
;*
|
||
|
;* PROGRAMMER
|
||
|
;* Denzil E. Long, Jr.
|
||
|
;*
|
||
|
;*---------------------------------------------------------------------------
|
||
|
;*
|
||
|
;* PUBLIC
|
||
|
;* UnVQ_4x2_Xmode - Draw 4x2 VQ frame directly to Xmode.
|
||
|
;* UnVQ_4x2_XmodeCB - Draw 4x2 VQ frame to Xmode from VRAM codebook.
|
||
|
;* Upload_4x2CB - Upload 4x2 codebook into XMode VRAM.
|
||
|
;* UnVQ_4x2_VESA320_32K - Draw 4x2 VQ frame to VESA320 32k color.
|
||
|
;* XlatePointers - Translate pointer to optimal XMode format.
|
||
|
;*
|
||
|
;****************************************************************************
|
||
|
|
||
|
IDEAL
|
||
|
MODEL LARGE
|
||
|
P386N
|
||
|
LOCALS ??
|
||
|
INCLUDE "vga.i"
|
||
|
INCLUDE "vesavid.i"
|
||
|
INCLUDE "vqaplay.i"
|
||
|
CODESEG
|
||
|
|
||
|
IF VQAXMODE_ON
|
||
|
|
||
|
SKIP_PTR EQU 8000h
|
||
|
CBOOK_SEG EQU (0B000h - 270h)
|
||
|
|
||
|
IF VQABLOCK_4X2
|
||
|
;****************************************************************************
|
||
|
;*
|
||
|
;* NAME
|
||
|
;* UnVQ_4x2_Xmode - Draw 4x2 VQ frame directly to Xmode.
|
||
|
;*
|
||
|
;* SYNOPSIS
|
||
|
;* UnVQ_4x2_Xmode(Codebook, Pointers, Buffer, BPR, Rows, Dummy)
|
||
|
;*
|
||
|
;* void UnVQ_4x2_Xmode(unsigned char *, unsigned char *, unsigned char *,
|
||
|
;* unsigned short, unsigned short, unsigned short);
|
||
|
;*
|
||
|
;* FUNCTION
|
||
|
;* This function draws an image to the Xmode display from the pointers
|
||
|
;* and codebook provided. This routine has been optimized for a 320x200
|
||
|
;* image.
|
||
|
;*
|
||
|
;* INPUTS
|
||
|
;* Codebook - Pointer to codebook used to draw image.
|
||
|
;* Pointers - Pointer to vector pointer data.
|
||
|
;* Buffer - Pointer to buffer to draw image into.
|
||
|
;* BPR - Number of blocks per row.
|
||
|
;* Rows - Number of rows.
|
||
|
;* Dummy - Not used (prototype placeholder)
|
||
|
;*
|
||
|
;* RESULT
|
||
|
;* NONE
|
||
|
;*
|
||
|
;****************************************************************************
|
||
|
|
||
|
PUBLIC C UnVQ_4x2_Xmode
|
||
|
PROC C UnVQ_4x2_Xmode FAR USES
|
||
|
|
||
|
ARG codebook:FAR PTR
|
||
|
ARG pointers:FAR PTR
|
||
|
ARG buffer:FAR PTR
|
||
|
ARG blocksperrow:WORD
|
||
|
ARG numrows:WORD
|
||
|
ARG dummy:WORD
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Local variables:
|
||
|
;-------------------------------------------------------------------
|
||
|
LOCAL data_end:WORD ; end of pointer data
|
||
|
LOCAL si_startval:WORD ; init value for SI, for new plane
|
||
|
LOCAL es_startval:WORD ; init value for ES, for new plane
|
||
|
LOCAL di_startval:WORD ; init value for DI, for new row
|
||
|
LOCAL cb_offset:WORD ; codebook offset
|
||
|
|
||
|
;===================================================================
|
||
|
; Initialization
|
||
|
;===================================================================
|
||
|
;-------------------------------------------------------------------
|
||
|
; Save our registers
|
||
|
;-------------------------------------------------------------------
|
||
|
push ds
|
||
|
push es
|
||
|
push fs
|
||
|
pushad
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Save codebook's address in FS:[cb_offset]:
|
||
|
; - load it into DS:SI, and normalize it
|
||
|
; - save it into FS:[cb_offset], and subtract 4 from it, so the
|
||
|
; pointer offsets will point directly at the correct codeword
|
||
|
;-------------------------------------------------------------------
|
||
|
lds si,[codebook] ; DS:SI = codebook
|
||
|
cmp si, 16 ; SI < 16 ?
|
||
|
jb short ??Decrement_codebook ; yes - don't normalize it
|
||
|
mov ax, si ; AX = SI
|
||
|
shr ax, 4 ; AX = SI / 16
|
||
|
mov bx, ds ; BX = DS
|
||
|
add ax, bx ; AX = (SI / 16) + DS
|
||
|
mov ds, ax ; adjust DS upward
|
||
|
and si, 000Fh ; save only low nybble
|
||
|
??Decrement_codebook:
|
||
|
mov ax,ds ; AX = cb segment
|
||
|
sub ax,1 ; subtract 16 bytes
|
||
|
mov fs,ax ; save in FS
|
||
|
mov [cb_offset],si
|
||
|
add [cb_offset],12
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Load pointers into DS:SI, then normalize DS:SI to minimize offset
|
||
|
;-------------------------------------------------------------------
|
||
|
??Normalize_pointers:
|
||
|
lds si, [pointers] ; DS:SI = pointers
|
||
|
cmp si, 16 ; SI < 16 ?
|
||
|
jb short ??Set_Data_End ; yes - don't normalize it
|
||
|
mov ax, si ; AX = SI
|
||
|
shr ax, 4 ; AX = SI / 16
|
||
|
mov bx, ds ; BX = DS
|
||
|
add ax, bx ; AX = (SI / 16) + DS
|
||
|
mov ds, ax ; adjust DS upward
|
||
|
and si, 000Fh ; save only low nybble
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Set [data_end] to [pointers] + size of ptr data
|
||
|
;-------------------------------------------------------------------
|
||
|
??Set_Data_End:
|
||
|
mov ax,[numrows]
|
||
|
mul [blocksperrow] ; AX = total # blocks
|
||
|
shl ax,1 ; mult by 2 for word size
|
||
|
add ax,si ; compute end of data
|
||
|
mov [data_end],ax ; store it
|
||
|
mov [si_startval],si ; save SI
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Load buffer into ES:DI, then normalize ES:DI to minimize offset
|
||
|
;-------------------------------------------------------------------
|
||
|
les di, [buffer] ; point ES:DI to dest
|
||
|
mov [es_startval],es ; save ES's start value
|
||
|
mov [di_startval],di ; store it
|
||
|
cmp di, 16 ; DI < 16 ?
|
||
|
jb short ??Set_XPlane1 ; yes - don't normalize it
|
||
|
mov ax, di ; AX = DI
|
||
|
shr ax, 4 ; AX = DI / 16
|
||
|
mov bx, es ; BX = ES
|
||
|
add ax, bx ; AX = (DI / 16) + ES
|
||
|
mov es, ax ; adjust ES upward
|
||
|
and di, 000Fh ; save only low nybble
|
||
|
mov [es_startval],es ; save ES's start value
|
||
|
mov [di_startval],di ; save DI's start value
|
||
|
|
||
|
|
||
|
;===================================================================
|
||
|
; The drawing loop:
|
||
|
; DS:SI = pointer data
|
||
|
; ES:DI = drawing buffer
|
||
|
; FS:[cb_offset] = codebook
|
||
|
;===================================================================
|
||
|
;===================================================================
|
||
|
; Set X-Mode Plane 1
|
||
|
; Plane 1 is the left half of even-numbered blocks on a row.
|
||
|
; (left pixel = low byte of codebook word)
|
||
|
;===================================================================
|
||
|
??Set_XPlane1:
|
||
|
SET_PLANE XPLANE_1
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Start a new row of drawing
|
||
|
;-------------------------------------------------------------------
|
||
|
??Start_row_1:
|
||
|
mov cx,[blocksperrow] ; # blocks to fill a line
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Start a new block
|
||
|
;-------------------------------------------------------------------
|
||
|
??Not_finished_a_line_1:
|
||
|
;
|
||
|
;..................... get next pointer word .......................
|
||
|
;
|
||
|
mov bx,[WORD PTR DS:SI] ; AX = pointer word
|
||
|
add si,2 ; SI = next pointer
|
||
|
;
|
||
|
;.................... check for a 1-color block ....................
|
||
|
;
|
||
|
or bx,bx ; check to see if high bit set
|
||
|
js short ??One_color_1
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Draw a multi-color block
|
||
|
; (AX = pointer byte)
|
||
|
; (ES:DI = buffer position to draw at)
|
||
|
; (FS:[cb_offset] = codebook address)
|
||
|
;-------------------------------------------------------------------
|
||
|
add bx,[cb_offset] ; get codebook offset
|
||
|
;
|
||
|
;................ transfer bytes from FS:BX to ES:DI ...............
|
||
|
;
|
||
|
mov ax,[fs:bx] ; get 1st codeword
|
||
|
mov dx,[fs:bx+4] ; get 2nd codeword
|
||
|
mov [es:di],al ; draw 1st
|
||
|
mov [es:di+80],dl ; draw 2nd
|
||
|
inc di ; next pixel
|
||
|
;
|
||
|
;..................... check block count ...........................
|
||
|
;
|
||
|
dec cx ; decrement block count
|
||
|
jnz short ??Not_finished_a_line_1
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Go to the next block row:
|
||
|
; - Add new offset to ES, and set DI to its start-row value
|
||
|
; (Incrementing the segment allows us to unpack up to 1MB of data)
|
||
|
; (Divide by 4 because there's 1/4 as many addresses per line
|
||
|
; in XMODE)
|
||
|
;-------------------------------------------------------------------
|
||
|
;
|
||
|
;....................... Add 80*2/16 to ES .........................
|
||
|
;
|
||
|
mov ax,es
|
||
|
add ax,10 ; add 80*2/16
|
||
|
mov es,ax
|
||
|
;
|
||
|
;.................. set DI to its start-row value ..................
|
||
|
;
|
||
|
mov di,[di_startval]
|
||
|
;
|
||
|
;............ see if we're past the end of the ptr data ............
|
||
|
;
|
||
|
cmp si,[data_end]
|
||
|
jnb short ??End_of_data_1 ; no - goto end
|
||
|
jmp ??Start_row_1 ; start new block row
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Draw 1-color block
|
||
|
; (AX = pointer byte)
|
||
|
; (ES:DI = buffer position to draw at)
|
||
|
; (FS:[cb_offset] = codebook address)
|
||
|
;-------------------------------------------------------------------
|
||
|
??One_color_1:
|
||
|
;
|
||
|
;................... skip ptr value SKIP_PTR .......................
|
||
|
;
|
||
|
cmp bx,SKIP_PTR
|
||
|
jne ??Draw_One_Color_1
|
||
|
inc di
|
||
|
dec cx
|
||
|
jnz short ??Not_finished_a_line_1
|
||
|
jmp ??Next_row_1
|
||
|
;
|
||
|
;................. transfer bytes from AX to DS:SI .................
|
||
|
;
|
||
|
??Draw_One_Color_1:
|
||
|
not bx
|
||
|
mov bh,bl ; dup al in al&ah
|
||
|
mov [es:di],bl ; set pixel
|
||
|
mov [es:di+80],bl ; set pixel
|
||
|
inc di ; next pixel
|
||
|
;
|
||
|
;..................... check block count ...........................
|
||
|
;
|
||
|
dec cx ; decrement block count
|
||
|
jnz short ??Not_finished_a_line_1
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Go to the next block row:
|
||
|
; - Add new offset to ES, and set DI to its start-row value
|
||
|
; (Incrementing the segment allows us to unpack up to 1MB of data)
|
||
|
; (Divide by 4 because there's 1/4 as many addresses per line
|
||
|
; in XMODE)
|
||
|
;-------------------------------------------------------------------
|
||
|
;
|
||
|
;....................... Add 80*2/16 to ES .........................
|
||
|
;
|
||
|
??Next_row_1:
|
||
|
mov ax,es
|
||
|
add ax,10 ; add 80*2/16
|
||
|
mov es,ax
|
||
|
;
|
||
|
;.................. set DI to its start-row value ..................
|
||
|
;
|
||
|
mov di,[di_startval]
|
||
|
;
|
||
|
;............ see if we're past the end of the ptr data ............
|
||
|
;
|
||
|
cmp si,[data_end]
|
||
|
jnb short ??End_of_data_1 ; no - goto end
|
||
|
jmp ??Start_row_1 ; start new block row
|
||
|
|
||
|
??End_of_data_1:
|
||
|
;-------------------------------------------------------------------
|
||
|
; Restore DS:SI to start of pointer data, and ES:DI to Xmode page
|
||
|
;-------------------------------------------------------------------
|
||
|
mov si,[si_startval]
|
||
|
mov es,[es_startval]
|
||
|
mov di,[di_startval]
|
||
|
|
||
|
;===================================================================
|
||
|
; Set X-Mode Plane 2
|
||
|
; Plane 2 is the right half of even-numbered blocks on a row.
|
||
|
; (right pixel = high byte of codebook word)
|
||
|
;===================================================================
|
||
|
SET_PLANE XPLANE_2
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Start a new row of drawing
|
||
|
;-------------------------------------------------------------------
|
||
|
??Start_row_2:
|
||
|
mov cx,[blocksperrow] ; # blocks to fill a line
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Start a new block
|
||
|
;-------------------------------------------------------------------
|
||
|
??Not_finished_a_line_2:
|
||
|
;
|
||
|
;..................... get next pointer word .......................
|
||
|
;
|
||
|
mov bx,[WORD PTR DS:SI] ; AX = pointer word
|
||
|
add si,2 ; SI = next pointer
|
||
|
;
|
||
|
;.................... check for a 1-color block ....................
|
||
|
;
|
||
|
or bx,bx ; check to see if high bit set
|
||
|
js short ??One_color_2
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Draw a multi-color block
|
||
|
; (AX = pointer byte)
|
||
|
; (ES:DI = buffer position to draw at)
|
||
|
; (FS:[cb_offset] = codebook address)
|
||
|
;-------------------------------------------------------------------
|
||
|
add bx,[cb_offset] ; get codebook offset
|
||
|
;
|
||
|
;................ transfer bytes from FS:BX to ES:DI ...............
|
||
|
;
|
||
|
mov ax,[fs:bx] ; get 1st codeword
|
||
|
mov dx,[fs:bx+4] ; get 2nd codeword
|
||
|
mov [es:di],ah ; draw 1st
|
||
|
mov [es:di+80],dh ; draw 2nd
|
||
|
inc di ; next pixel
|
||
|
;
|
||
|
;..................... check block count ...........................
|
||
|
;
|
||
|
dec cx ; decrement block count
|
||
|
jnz short ??Not_finished_a_line_2
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Go to the next block row:
|
||
|
; - Add new offset to ES, and set DI to its start-row value
|
||
|
; (Incrementing the segment allows us to unpack up to 1MB of data)
|
||
|
; (Divide by 4 because there's 1/4 as many addresses per line
|
||
|
; in XMODE)
|
||
|
;-------------------------------------------------------------------
|
||
|
;
|
||
|
;....................... Add 80*2/16 to ES .........................
|
||
|
;
|
||
|
mov ax,es
|
||
|
add ax,10 ; add 80*2/16
|
||
|
mov es,ax
|
||
|
;
|
||
|
;.................. set DI to its start-row value ..................
|
||
|
;
|
||
|
mov di,[di_startval]
|
||
|
;
|
||
|
;............ see if we're past the end of the ptr data ............
|
||
|
;
|
||
|
cmp si,[data_end]
|
||
|
jnb short ??End_of_data_2 ; no - goto end
|
||
|
jmp ??Start_row_2 ; start new block row
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Draw 1-color block
|
||
|
; (AX = pointer byte)
|
||
|
; (ES:DI = buffer position to draw at)
|
||
|
; (FS:[cb_offset] = codebook address)
|
||
|
;-------------------------------------------------------------------
|
||
|
??One_color_2:
|
||
|
;
|
||
|
;................... skip ptr value SKIP_PTR .......................
|
||
|
;
|
||
|
cmp bx,SKIP_PTR
|
||
|
jne ??Draw_One_Color_2
|
||
|
inc di
|
||
|
dec cx
|
||
|
jnz short ??Not_finished_a_line_2
|
||
|
jmp ??Next_row_2
|
||
|
;
|
||
|
;................. transfer bytes from AX to DS:SI .................
|
||
|
;
|
||
|
??Draw_One_Color_2:
|
||
|
not bx
|
||
|
mov bh,bl ; dup al in al&ah
|
||
|
mov [es:di],bh ; store 2 colors
|
||
|
mov [es:di+80],bh ; store 2 colors
|
||
|
inc di ; next pixel
|
||
|
;
|
||
|
;..................... check block count ...........................
|
||
|
;
|
||
|
dec cx ; decrement block count
|
||
|
jnz short ??Not_finished_a_line_2
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Go to the next block row:
|
||
|
; - Add new offset to ES, and set DI to its start-row value
|
||
|
; (Incrementing the segment allows us to unpack up to 1MB of data)
|
||
|
; (Divide by 4 because there's 1/4 as many addresses per line
|
||
|
; in XMODE)
|
||
|
;-------------------------------------------------------------------
|
||
|
;
|
||
|
;....................... Add 80*2/16 to ES .........................
|
||
|
;
|
||
|
??Next_row_2:
|
||
|
mov ax,es
|
||
|
add ax,10 ; add 80*2/16
|
||
|
mov es,ax
|
||
|
;
|
||
|
;.................. set DI to its start-row value ..................
|
||
|
;
|
||
|
mov di,[di_startval]
|
||
|
;
|
||
|
;............ see if we're past the end of the ptr data ............
|
||
|
;
|
||
|
cmp si,[data_end]
|
||
|
jnb short ??End_of_data_2 ; no - goto end
|
||
|
jmp ??Start_row_2 ; start new block row
|
||
|
|
||
|
??End_of_data_2:
|
||
|
;-------------------------------------------------------------------
|
||
|
; Restore DS:SI to start of pointer data, and ES:DI to Xmode page
|
||
|
;-------------------------------------------------------------------
|
||
|
mov si,[si_startval]
|
||
|
mov es,[es_startval]
|
||
|
mov di,[di_startval]
|
||
|
|
||
|
;===================================================================
|
||
|
; Set X-Mode Plane 3
|
||
|
; Plane 3 is the left half of odd-numbered blocks on a row.
|
||
|
; (left pixel = low byte of codebook word)
|
||
|
;===================================================================
|
||
|
SET_PLANE XPLANE_3
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Start a new row of drawing
|
||
|
;-------------------------------------------------------------------
|
||
|
??Start_row_3:
|
||
|
mov cx,[blocksperrow] ; # blocks to fill a line
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Start a new block
|
||
|
;-------------------------------------------------------------------
|
||
|
??Not_finished_a_line_3:
|
||
|
;
|
||
|
;..................... get next pointer word .......................
|
||
|
;
|
||
|
mov bx,[WORD PTR DS:SI] ; AX = pointer word
|
||
|
add si,2 ; SI = next pointer
|
||
|
;
|
||
|
;.................... check for a 1-color block ....................
|
||
|
;
|
||
|
or bx,bx ; check to see if high bit set
|
||
|
js short ??One_color_3
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Draw a multi-color block
|
||
|
; (AX = pointer byte)
|
||
|
; (ES:DI = buffer position to draw at)
|
||
|
; (FS:[cb_offset] = codebook address)
|
||
|
;-------------------------------------------------------------------
|
||
|
add bx,[cb_offset] ; get codebook offset
|
||
|
;
|
||
|
;................ transfer bytes from FS:BX to ES:DI ...............
|
||
|
;
|
||
|
mov ax,[fs:bx+2] ; get 1st codeword
|
||
|
mov dx,[fs:bx+6] ; get 2nd codeword
|
||
|
mov [es:di],al ; draw 1st
|
||
|
mov [es:di+80],dl ; draw 2nd
|
||
|
inc di ; next pixel
|
||
|
;
|
||
|
;..................... check block count ...........................
|
||
|
;
|
||
|
dec cx ; decrement block count
|
||
|
jnz short ??Not_finished_a_line_3
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Go to the next block row:
|
||
|
; - Add new offset to ES, and set DI to its start-row value
|
||
|
; (Incrementing the segment allows us to unpack up to 1MB of data)
|
||
|
; (Divide by 4 because there's 1/4 as many addresses per line
|
||
|
; in XMODE)
|
||
|
;-------------------------------------------------------------------
|
||
|
;
|
||
|
;....................... Add 80*2/16 to ES .........................
|
||
|
;
|
||
|
mov ax,es
|
||
|
add ax,10 ; add 80*2/16
|
||
|
mov es,ax
|
||
|
;
|
||
|
;.................. set DI to its start-row value ..................
|
||
|
;
|
||
|
mov di,[di_startval]
|
||
|
;
|
||
|
;............ see if we're past the end of the ptr data ............
|
||
|
;
|
||
|
cmp si,[data_end]
|
||
|
jnb short ??End_of_data_3 ; no - goto end
|
||
|
jmp ??Start_row_3 ; start new block row
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Draw 1-color block
|
||
|
; (AX = pointer byte)
|
||
|
; (ES:DI = buffer position to draw at)
|
||
|
; (FS:[cb_offset] = codebook address)
|
||
|
;-------------------------------------------------------------------
|
||
|
??One_color_3:
|
||
|
;
|
||
|
;................... skip ptr value SKIP_PTR .......................
|
||
|
;
|
||
|
cmp bx,SKIP_PTR
|
||
|
jne ??Draw_One_Color_3
|
||
|
inc di
|
||
|
dec cx
|
||
|
jnz short ??Not_finished_a_line_3
|
||
|
jmp ??Next_row_3
|
||
|
;
|
||
|
;................. transfer bytes from AX to DS:SI .................
|
||
|
;
|
||
|
??Draw_One_Color_3:
|
||
|
not bx
|
||
|
mov bh,bl ; dup al in al&ah
|
||
|
mov [es:di],bl ; store 2 colors
|
||
|
mov [es:di+80],bl ; store 2 colors
|
||
|
inc di ; next pixel
|
||
|
;
|
||
|
;..................... check block count ...........................
|
||
|
;
|
||
|
dec cx ; decrement block count
|
||
|
jnz short ??Not_finished_a_line_3
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Go to the next block row:
|
||
|
; - Add new offset to ES, and set DI to its start-row value
|
||
|
; (Incrementing the segment allows us to unpack up to 1MB of data)
|
||
|
; (Divide by 4 because there's 1/4 as many addresses per line
|
||
|
; in XMODE)
|
||
|
;-------------------------------------------------------------------
|
||
|
;
|
||
|
;....................... Add 80*2/16 to ES .........................
|
||
|
;
|
||
|
??Next_row_3:
|
||
|
mov ax,es
|
||
|
add ax,10 ; add 80*2/16
|
||
|
mov es,ax
|
||
|
;
|
||
|
;.................. set DI to its start-row value ..................
|
||
|
;
|
||
|
mov di,[di_startval]
|
||
|
;
|
||
|
;............ see if we're past the end of the ptr data ............
|
||
|
;
|
||
|
cmp si,[data_end]
|
||
|
jnb short ??End_of_data_3 ; no - goto end
|
||
|
jmp ??Start_row_3 ; start new block row
|
||
|
|
||
|
??End_of_data_3:
|
||
|
;-------------------------------------------------------------------
|
||
|
; Restore DS:SI to start of pointer data, and ES:DI to Xmode page
|
||
|
;-------------------------------------------------------------------
|
||
|
mov si,[si_startval]
|
||
|
mov es,[es_startval]
|
||
|
mov di,[di_startval]
|
||
|
|
||
|
;===================================================================
|
||
|
; Set X-Mode Plane 4
|
||
|
; Plane 4 is the right half of odd-numbered blocks on a row.
|
||
|
; (right pixel = high byte of codebook word)
|
||
|
;===================================================================
|
||
|
SET_PLANE XPLANE_4
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Start a new row of drawing
|
||
|
;-------------------------------------------------------------------
|
||
|
??Start_row_4:
|
||
|
mov cx,[blocksperrow] ; # blocks to fill a line
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Start a new block
|
||
|
;-------------------------------------------------------------------
|
||
|
??Not_finished_a_line_4:
|
||
|
;
|
||
|
;..................... get next pointer word .......................
|
||
|
;
|
||
|
mov bx,[WORD PTR DS:SI] ; AX = pointer word
|
||
|
add si,2 ; SI = next pointer
|
||
|
;
|
||
|
;.................... check for a 1-color block ....................
|
||
|
;
|
||
|
or bx,bx ; check to see if high bit set
|
||
|
js short ??One_color_4
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Draw a multi-color block
|
||
|
; (AX = pointer byte)
|
||
|
; (ES:DI = buffer position to draw at)
|
||
|
; (FS:[cb_offset] = codebook address)
|
||
|
;-------------------------------------------------------------------
|
||
|
add bx,[cb_offset] ; get codebook offset
|
||
|
;
|
||
|
;................ transfer bytes from FS:BX to ES:DI ...............
|
||
|
;
|
||
|
mov ax,[fs:bx+2] ; get 1st codeword
|
||
|
mov dx,[fs:bx+6] ; get 2nd codeword
|
||
|
mov [es:di],ah ; draw 1st
|
||
|
mov [es:di+80],dh ; draw 2nd
|
||
|
inc di ; next pixel
|
||
|
;
|
||
|
;..................... check block count ...........................
|
||
|
;
|
||
|
dec cx ; decrement block count
|
||
|
jnz short ??Not_finished_a_line_4
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Go to the next block row:
|
||
|
; - Add new offset to ES, and set DI to its start-row value
|
||
|
; (Incrementing the segment allows us to unpack up to 1MB of data)
|
||
|
; (Divide by 4 because there's 1/4 as many addresses per line
|
||
|
; in XMODE)
|
||
|
;-------------------------------------------------------------------
|
||
|
;
|
||
|
;....................... Add 80*2/16 to ES .........................
|
||
|
;
|
||
|
mov ax,es
|
||
|
add ax,10 ; add 80*2/16
|
||
|
mov es,ax
|
||
|
;
|
||
|
;.................. set DI to its start-row value ..................
|
||
|
;
|
||
|
mov di,[di_startval]
|
||
|
;
|
||
|
;............ see if we're past the end of the ptr data ............
|
||
|
;
|
||
|
cmp si,[data_end]
|
||
|
jnb short ??End_of_data_4 ; no - goto end
|
||
|
jmp ??Start_row_4 ; start new block row
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Draw 1-color block
|
||
|
; (AX = pointer byte)
|
||
|
; (ES:DI = buffer position to draw at)
|
||
|
; (FS:[cb_offset] = codebook address)
|
||
|
;-------------------------------------------------------------------
|
||
|
??One_color_4:
|
||
|
;
|
||
|
;................... skip ptr value SKIP_PTR .......................
|
||
|
;
|
||
|
cmp bx,SKIP_PTR
|
||
|
jne ??Draw_One_Color_4
|
||
|
inc di
|
||
|
dec cx
|
||
|
jnz short ??Not_finished_a_line_4
|
||
|
jmp ??Next_row_4
|
||
|
;
|
||
|
;................. transfer bytes from AX to DS:SI .................
|
||
|
;
|
||
|
??Draw_One_Color_4:
|
||
|
not bx
|
||
|
mov bh,bl ; dup al in al&ah
|
||
|
mov [es:di],bh ; store 2 colors
|
||
|
mov [es:di+80],bh ; store 2 colors
|
||
|
inc di ; next pixel
|
||
|
;
|
||
|
;..................... check block count ...........................
|
||
|
;
|
||
|
dec cx ; decrement block count
|
||
|
jnz short ??Not_finished_a_line_4
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Go to the next block row:
|
||
|
; - Add new offset to ES, and set DI to its start-row value
|
||
|
; (Incrementing the segment allows us to unpack up to 1MB of data)
|
||
|
; (Divide by 4 because there's 1/4 as many addresses per line
|
||
|
; in XMODE)
|
||
|
;-------------------------------------------------------------------
|
||
|
;
|
||
|
;....................... Add 80*2/16 to ES .........................
|
||
|
;
|
||
|
??Next_row_4:
|
||
|
mov ax,es
|
||
|
add ax,10 ; add 80*2/16
|
||
|
mov es,ax
|
||
|
;
|
||
|
;.................. set DI to its start-row value ..................
|
||
|
;
|
||
|
mov di,[di_startval]
|
||
|
;
|
||
|
;............ see if we're past the end of the ptr data ............
|
||
|
;
|
||
|
cmp si,[data_end]
|
||
|
jnb short ??End_of_data_4 ; no - goto end
|
||
|
jmp ??Start_row_4 ; start new block row
|
||
|
|
||
|
??End_of_data_4:
|
||
|
popad
|
||
|
pop fs
|
||
|
pop es
|
||
|
pop ds
|
||
|
ret
|
||
|
|
||
|
ENDP UnVQ_4x2_Xmode
|
||
|
|
||
|
|
||
|
;****************************************************************************
|
||
|
;*
|
||
|
;* NAME
|
||
|
;* UnVQ_4x2_XmodeCB - Draw 4x2 VQ frame to Xmode from VRAM codebook.
|
||
|
;*
|
||
|
;* SYNOPSIS
|
||
|
;* UnVQ_4x2_XmodeCB(Dummy, Pointers, Buffer, BPR, Rows)
|
||
|
;*
|
||
|
;* void UnVQ_4x2_XmodeCB(unsigned char *, unsigned char *,
|
||
|
;* unsigned char *, unsigned short,
|
||
|
;* unsigned short);
|
||
|
;*
|
||
|
;* FUNCTION
|
||
|
;* This routine copies codebook entries from video RAM to video RAM.
|
||
|
;* The procedure for Write Mode 1 is:
|
||
|
;*
|
||
|
;* - Perform a CPU read at the address of the 4-byte codebook entry;
|
||
|
;* this will load each byte at that address from all 4 bitplanes
|
||
|
;* into the VGA's internal latches.
|
||
|
;*
|
||
|
;* - Perform a CPU write at the destination address, with the BitMask
|
||
|
;* register set to 0 (this tells the VGA hardware to only use the
|
||
|
;* data stored in the latches to write with), and the Map Mask
|
||
|
;* register set to 0Fh (all bitplanes enabled).
|
||
|
;*
|
||
|
;* Optimized for 320x200.
|
||
|
;* The codebook must have been downloaded to video RAM before this
|
||
|
;* routine is called. This routine assumes the multicolor block pointers
|
||
|
;* have been pre-divided by 4, and have a total of 512 added to them, so
|
||
|
;* the pointer is an exact offset into the codebook.
|
||
|
;*
|
||
|
;* INPUTS
|
||
|
;* Dummy - Not used (prototype placeholder)
|
||
|
;* Pointers - Pointer to vector pointer data.
|
||
|
;* Buffer - Pointer to Xmode buffer.
|
||
|
;* BPR - Number of blocks per row.
|
||
|
;* Rows - Number of rows.
|
||
|
;*
|
||
|
;* RESULT
|
||
|
;* NONE
|
||
|
;*
|
||
|
;****************************************************************************
|
||
|
|
||
|
PUBLIC C UnVQ_4x2_XmodeCB
|
||
|
PROC C UnVQ_4x2_XmodeCB FAR USES
|
||
|
|
||
|
ARG cbdummy:FAR PTR
|
||
|
ARG pointers:FAR PTR
|
||
|
ARG buffer:FAR PTR
|
||
|
ARG blocksperrow:WORD
|
||
|
ARG numrows:WORD
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Local variables:
|
||
|
;-------------------------------------------------------------------
|
||
|
LOCAL di_startval:WORD ; init value for DI, for new row
|
||
|
|
||
|
;===================================================================
|
||
|
; Initialization
|
||
|
;===================================================================
|
||
|
;-------------------------------------------------------------------
|
||
|
; Save our registers
|
||
|
;-------------------------------------------------------------------
|
||
|
push ds
|
||
|
push es
|
||
|
push fs
|
||
|
pushad
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Save codebook's segment in DS
|
||
|
;-------------------------------------------------------------------
|
||
|
mov ax,CBOOK_SEG
|
||
|
mov ds,ax
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Load pointers into FS:BX
|
||
|
;-------------------------------------------------------------------
|
||
|
les di,[pointers]
|
||
|
mov ax,es
|
||
|
mov fs,ax
|
||
|
mov bx,di
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Load screen address into ES:DI
|
||
|
;-------------------------------------------------------------------
|
||
|
les di, [buffer] ; point ES:DI to dest
|
||
|
mov [di_startval],di ; store it
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Initialize VGA registers:
|
||
|
; - Enable all bitplanes for writing
|
||
|
; - Set the BitMask register to 0, so only the data from the
|
||
|
; VGA latches is written into the bitplanes
|
||
|
;-------------------------------------------------------------------
|
||
|
SET_PLANE 0fh ; enable all planes for write
|
||
|
SET_WRITEMODE 1
|
||
|
|
||
|
;===================================================================
|
||
|
; The drawing loop:
|
||
|
; DS:SI = codebook
|
||
|
; ES:DI = drawing buffer
|
||
|
; FS:BX = pointers
|
||
|
;===================================================================
|
||
|
;-------------------------------------------------------------------
|
||
|
; Start a new row of drawing
|
||
|
;-------------------------------------------------------------------
|
||
|
??Start_row:
|
||
|
mov cx,[blocksperrow] ; # blocks to fill a line
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Start a new block
|
||
|
;-------------------------------------------------------------------
|
||
|
??Not_finished_a_line:
|
||
|
;
|
||
|
;..................... get next pointer word .......................
|
||
|
;
|
||
|
mov si,[WORD PTR fs:bx] ; SI = ptr word (cbook offset)
|
||
|
add bx,2 ; next ptr word
|
||
|
;
|
||
|
;................... skip ptr value SKIP_PTR .......................
|
||
|
;
|
||
|
cmp si,SKIP_PTR
|
||
|
jne ??Draw_Block
|
||
|
inc di
|
||
|
dec cx
|
||
|
jnz short ??Not_finished_a_line
|
||
|
jmp ??Next_row
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Draw a block via the VGA internal latches:
|
||
|
; DS:SI = codebook address
|
||
|
; ES:DI = buffer position to draw at
|
||
|
; - Load the VGA latches from the 1st 4 codebook bytes
|
||
|
; - write 4 pixels with one CPU write
|
||
|
; - If this is a one-color block, skip the next codebook read
|
||
|
; (Video RAM reads are very slow); otherwise, latch the next 4
|
||
|
; codebook bytes
|
||
|
; - write the next 4 pixels
|
||
|
;-------------------------------------------------------------------
|
||
|
;
|
||
|
;..................... draw 1st 4 pixels ...........................
|
||
|
;
|
||
|
??Draw_Block:
|
||
|
mov al,[ds:si] ; latch 1st 4 cbook bytes
|
||
|
mov [es:di],al ; write 4 pixels
|
||
|
;
|
||
|
;.................. check for 1-color block ........................
|
||
|
;
|
||
|
cmp si,512 ; if 1color blk, don't read
|
||
|
jb ??One_Color
|
||
|
;
|
||
|
;..................... draw next 4 pixels ..........................
|
||
|
;
|
||
|
mov al,[ds:si+1] ; latch next 4 cbook bytes
|
||
|
??One_Color:
|
||
|
mov [es:di+80],al ; write next 4 pixels
|
||
|
inc di ; next block position
|
||
|
;
|
||
|
;...................... check block count ..........................
|
||
|
;
|
||
|
dec cx ; decrement block count
|
||
|
jnz short ??Not_finished_a_line
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Go to the next block row:
|
||
|
; - Add (80*2/16) to ES, and set DI to its start-row value
|
||
|
; (Incrementing the segment allows us to unpack up to 1MB of data)
|
||
|
;-------------------------------------------------------------------
|
||
|
;
|
||
|
;...................... add (320*2/16) to ES .......................
|
||
|
;
|
||
|
??Next_row:
|
||
|
mov ax,es
|
||
|
add ax,10 ; add 80*2/16
|
||
|
mov es,ax
|
||
|
;
|
||
|
;.................. set DI to its start-row value ..................
|
||
|
;
|
||
|
mov di,[di_startval]
|
||
|
;
|
||
|
;............ see if we're past the end of the ptr data ............
|
||
|
;
|
||
|
dec [numrows]
|
||
|
jg ??Start_row
|
||
|
|
||
|
??End_of_data:
|
||
|
;-------------------------------------------------------------------
|
||
|
; Restore VGA Write Mode to 0
|
||
|
;-------------------------------------------------------------------
|
||
|
SET_WRITEMODE 0
|
||
|
|
||
|
popad
|
||
|
pop fs
|
||
|
pop es
|
||
|
pop ds
|
||
|
ret
|
||
|
|
||
|
ENDP UnVQ_4x2_XmodeCB
|
||
|
|
||
|
|
||
|
;****************************************************************************
|
||
|
;*
|
||
|
;* NAME
|
||
|
;* Upload_4x2CB - Upload 4x2 codebook into XMode VRAM.
|
||
|
;*
|
||
|
;* SYNOPSIS
|
||
|
;* Upload_4x2CB(Codebook, Entries)
|
||
|
;*
|
||
|
;* void Upload_4x2CB(unsigned char *, unsigned short);
|
||
|
;*
|
||
|
;* FUNCTION
|
||
|
;* This routine copies the given codebook into Xmode VRAM, so that it
|
||
|
;* can be used later for direct video-to-video copies. The address used
|
||
|
;* is the end of video memory minus 02700h (10K). This should be plenty
|
||
|
;* for a 3000-entry codebook; each 4x2 codebook entry will take up 8
|
||
|
;* 8 bytes, or 2 addresses in XMode (6000 addresses).
|
||
|
;*
|
||
|
;* The routine also creates a 1-color-block table in VRAM, so the 1-color
|
||
|
;* blocks can be generated the same way as the multicolor blocks.
|
||
|
;*
|
||
|
;* XMode 320x200 uses 320x200/4 addresses per page, for a total of 32000
|
||
|
;* addresses. XMode 320x240 uses 320x240/4 addresses per page, for a
|
||
|
;* total of 38400 addresses. This leaves 27136 addresses unused.
|
||
|
;*
|
||
|
;* INPUTS
|
||
|
;* Codebook - Pointer to codebook to copy.
|
||
|
;* Entries - Number of codebook entries to copy.
|
||
|
;*
|
||
|
;* RESULT
|
||
|
;* NONE
|
||
|
;*
|
||
|
;****************************************************************************
|
||
|
|
||
|
PUBLIC C Upload_4x2CB
|
||
|
PROC C Upload_4x2CB FAR USES ds si es di cx dx
|
||
|
|
||
|
ARG codebook:FAR PTR
|
||
|
ARG numentries:WORD
|
||
|
|
||
|
;===================================================================
|
||
|
; Generate the 1-color block table by writing each color value from
|
||
|
; 0-255 into all 4 bitplanes, at 256 consecutive addresses:
|
||
|
;===================================================================
|
||
|
SET_PLANE 0fh ; enable all bitplanes for writing
|
||
|
;...................................................................
|
||
|
; Set ES:DI to destination address, set up CX for the loop
|
||
|
;...................................................................
|
||
|
mov ax,CBOOK_SEG
|
||
|
mov es,ax
|
||
|
mov di,0
|
||
|
mov cx,256
|
||
|
mov ax,0
|
||
|
??1_Color_Loop:
|
||
|
mov [es:di],al ; write 4 bytes
|
||
|
inc di ; next 4-byte position
|
||
|
mov [es:di],al ; write 4 bytes
|
||
|
inc di ; next 4-byte position
|
||
|
inc ax ; next color #
|
||
|
dec cx ; decrement loop counter
|
||
|
jnz ??1_Color_Loop
|
||
|
|
||
|
;===================================================================
|
||
|
; Copy the codebook into video RAM, one plane at a time:
|
||
|
;===================================================================
|
||
|
;-------------------------------------------------------------------
|
||
|
; Copy codebook byte 0 into Plane 1
|
||
|
;-------------------------------------------------------------------
|
||
|
;...................................................................
|
||
|
; Set DS:SI to codebook address, ES:DI to screen address
|
||
|
; (Codebook is stored at offset 1, so the pointers will point at
|
||
|
; exactly the right offset.)
|
||
|
;...................................................................
|
||
|
lds si, [codebook] ; DS:SI = codebook
|
||
|
mov ax,CBOOK_SEG
|
||
|
mov es,ax
|
||
|
mov di,512
|
||
|
|
||
|
;...................................................................
|
||
|
; Set up the loop
|
||
|
;...................................................................
|
||
|
SET_PLANE XPLANE_1
|
||
|
mov cx,[numentries] ; set loop counter
|
||
|
shl cx,1 ; do 2 DWORDS per cbook entry
|
||
|
|
||
|
;...................................................................
|
||
|
; Loop through codebook entries
|
||
|
;...................................................................
|
||
|
??CB_Loop_1:
|
||
|
mov al,[ds:si]
|
||
|
mov [es:di],al
|
||
|
add si,4
|
||
|
inc di
|
||
|
dec cx
|
||
|
jnz ??CB_Loop_1
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Copy codebook byte 1 Plane 2
|
||
|
;-------------------------------------------------------------------
|
||
|
;...................................................................
|
||
|
; Set DS:SI to codebook address, ES:DI to screen address
|
||
|
; (Codebook is stored at offset 1, so the pointers will point at
|
||
|
; exactly the right offset.)
|
||
|
;...................................................................
|
||
|
lds si, [codebook] ; DS:SI = codebook
|
||
|
mov ax,CBOOK_SEG
|
||
|
mov es,ax
|
||
|
mov di,512
|
||
|
add si,1 ; use 2nd byte value
|
||
|
|
||
|
;...................................................................
|
||
|
; Set up the loop
|
||
|
;...................................................................
|
||
|
SET_PLANE XPLANE_2
|
||
|
mov cx,[numentries] ; set loop counter
|
||
|
shl cx,1 ; do 2 DWORDS per cbook entry
|
||
|
|
||
|
;...................................................................
|
||
|
; Loop through codebook entries
|
||
|
;...................................................................
|
||
|
??CB_Loop_2:
|
||
|
mov al,[ds:si]
|
||
|
mov [es:di],al
|
||
|
add si,4
|
||
|
inc di
|
||
|
dec cx
|
||
|
jnz ??CB_Loop_2
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Copy codebook byte 2 Plane 3
|
||
|
;-------------------------------------------------------------------
|
||
|
;...................................................................
|
||
|
; Set DS:SI to codebook address, ES:DI to screen address
|
||
|
; (Codebook is stored at offset 1, so the pointers will point at
|
||
|
; exactly the right offset.)
|
||
|
;...................................................................
|
||
|
lds si, [codebook] ; DS:SI = codebook
|
||
|
mov ax,CBOOK_SEG
|
||
|
mov es,ax
|
||
|
mov di,512
|
||
|
add si,2 ; use 3rd byte value
|
||
|
|
||
|
;...................................................................
|
||
|
; Set up the loop
|
||
|
;...................................................................
|
||
|
SET_PLANE XPLANE_3
|
||
|
mov cx,[numentries] ; set loop counter
|
||
|
shl cx,1 ; do 2 DWORDS per cbook entry
|
||
|
|
||
|
;...................................................................
|
||
|
; Loop through codebook entries
|
||
|
;...................................................................
|
||
|
??CB_Loop_3:
|
||
|
mov al,[ds:si]
|
||
|
mov [es:di],al
|
||
|
add si,4
|
||
|
inc di
|
||
|
dec cx
|
||
|
jnz ??CB_Loop_3
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Copy codebook byte 3 Plane 4
|
||
|
;-------------------------------------------------------------------
|
||
|
;...................................................................
|
||
|
; Set DS:SI to codebook address, ES:DI to screen address
|
||
|
; (Codebook is stored at offset 1, so the pointers will point at
|
||
|
; exactly the right offset.)
|
||
|
;...................................................................
|
||
|
lds si, [codebook] ; DS:SI = codebook
|
||
|
mov ax,CBOOK_SEG
|
||
|
mov es,ax
|
||
|
mov di,512
|
||
|
add si,3 ; use 4th byte value
|
||
|
|
||
|
;...................................................................
|
||
|
; Set up the loop
|
||
|
;...................................................................
|
||
|
SET_PLANE XPLANE_4
|
||
|
mov cx,[numentries] ; set loop counter
|
||
|
shl cx,1 ; do 2 DWORDS per cbook entry
|
||
|
|
||
|
;...................................................................
|
||
|
; Loop through codebook entries
|
||
|
;...................................................................
|
||
|
??CB_Loop_4:
|
||
|
mov al,[ds:si]
|
||
|
mov [es:di],al
|
||
|
add si,4
|
||
|
inc di
|
||
|
dec cx
|
||
|
jnz ??CB_Loop_4
|
||
|
|
||
|
ret
|
||
|
|
||
|
ENDP Upload_4x2CB
|
||
|
|
||
|
ENDIF ;VQABLOCK_4X2
|
||
|
|
||
|
;****************************************************************************
|
||
|
;*
|
||
|
;* NAME
|
||
|
;* XlatePointers - Translate pointer to optimal XMode format.
|
||
|
;*
|
||
|
;* SYNOPSIS
|
||
|
;* XlatePointers(Pointers, Entries)
|
||
|
;*
|
||
|
;* void XlatePointers(unsigned char *, unsigned short);
|
||
|
;*
|
||
|
;* FUNCTION
|
||
|
;*
|
||
|
;* INPUTS
|
||
|
;* Pointers - Pointer to vector pointers to translate.
|
||
|
;* Entries - Number of pointer entries.
|
||
|
;*
|
||
|
;* RESULT
|
||
|
;* NONE
|
||
|
;*
|
||
|
;****************************************************************************
|
||
|
|
||
|
PUBLIC C XlatePointers
|
||
|
PROC C XlatePointers FAR USES ds si cx
|
||
|
|
||
|
ARG pointers:FAR PTR
|
||
|
ARG numpointers:WORD
|
||
|
|
||
|
;-------------------------------------------------------------------
|
||
|
; Load pointers into DS:SI
|
||
|
;-------------------------------------------------------------------
|
||
|
lds si,[pointers]
|
||
|
|
||
|
mov cx,[numpointers] ; init to # pointers on scrn
|
||
|
|
||
|
??Process_pointer:
|
||
|
;
|
||
|
;..................... get next pointer word .......................
|
||
|
;
|
||
|
mov ax,[WORD PTR ds:si] ; SI = ptr word (cbook offset)
|
||
|
;
|
||
|
;.................... check for a 1-color block ....................
|
||
|
;
|
||
|
or ax,ax ; check to see if high bit set
|
||
|
js short ??One_color
|
||
|
;
|
||
|
;....................... multi-color pointer .......................
|
||
|
;
|
||
|
sub ax,4 ; subtract 4
|
||
|
shr ax,2 ; divide by 4
|
||
|
add ax,512 ; add 512
|
||
|
mov [WORD PTR ds:si],ax ; save new value
|
||
|
add si,2 ; next ptr word
|
||
|
;
|
||
|
;....................... see if we're done .........................
|
||
|
;
|
||
|
dec cx
|
||
|
jnz ??Process_pointer
|
||
|
jmp ??Done
|
||
|
|
||
|
??One_color:
|
||
|
;
|
||
|
;......................... 1-color pointer .........................
|
||
|
;
|
||
|
not ax ; get actual color value
|
||
|
shl ax,1 ; multiply by 2
|
||
|
mov [WORD PTR ds:si],ax ; save new value
|
||
|
add si,2 ; next ptr word
|
||
|
;
|
||
|
;....................... see if we're done .........................
|
||
|
;
|
||
|
dec cx
|
||
|
jnz ??Process_pointer
|
||
|
|
||
|
??Done:
|
||
|
ret
|
||
|
|
||
|
ENDP XlatePointers
|
||
|
|
||
|
ENDIF ;VQAXMODE_ON
|
||
|
END
|
||
|
|