home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C!T ROM 5
/
ctrom5b.zip
/
ctrom5b
/
PROGRAM
/
DIVERSEN
/
PCXK53
/
VGA.ASM
< prev
next >
Wrap
Assembly Source File
|
1994-11-16
|
9KB
|
244 lines
; ------------------------------------
; Module for PCX.PAS and PCX.CPP
; Copyright (c) 1994 by Peter Donnelly
; ------------------------------------
; To compile for Pascal, put "/dpascal" on the TASM command line.
; To compile for C++, change the .MODEL definition to match your program's
; memory model. Then run TASM with the "/mx" switch on the command line.
IFDEF PASCAL
.MODEL TPASCAL
ELSE
.MODEL LARGE, C ; can be COMPACT, LARGE, or HUGE
ENDIF
.DATA
extrn DataLength: word
extrn Scratch: dword
extrn Plane: word
extrn VideoOffs: word
extrn VideoSeg: word
extrn Margin: word
extrn ScreenWidth: word
extrn LineEnd: word
extrn RepeatCount: byte
extrn ColumnCount: word
extrn BytesPerLine: word
.CODE
PUBLIC Decode16
PUBLIC Decode256
LOCALS
; ----------------------------- 16-COLOR FILES ---------------------------
Decode16 PROC
; Main use of registers:
; AL data byte to be written to video
; AH data bytes per scan line
; BX end of input buffer
; CL number of times data byte is to be written
; DL current column in scan line
; ES output segment
; DI index into output buffer
; SI index into input buffer
; BP current color plane
push si ; save C register variables
push di ; ditto
push bp
; The first section is initialization done on each run through the
; input buffer.
@@startproc:
mov bp, Plane ; plane in BP
mov di, VideoOffs ; index into video segment
mov ah, byte ptr BytesPerLine ; line length in AH
mov dx, ColumnCount ; column counter
mov bx, DataLength ; no. of bytes to read
xor cx, cx ; clean up CX for loop counter
mov cl, RepeatCount ; count in CX
les si, Scratch ; index into input buffer in SI
; ES not significant here - we don't use LDS because we want to
; preserve DS
; We have to adjust datalength for comparison with SI. Pascal pointers
; are normalized, but the offset can still be 0 or 8.
mov es, VideoSeg ; video display segment
add bx, si
cld ; clear DF for stosb
cmp cl, 0 ; was last byte a count?
jne @@multi_data ; yes, so next is data
jmp short @@getbyte ; no, so find out what next is
; The data in the .PCX file is organized by color plane, by line; that is,
; all the data for plane 0 for line 1, then for plane 1, line 1, etc.
; Writing the data to display memory is just a matter of masking out the
; other planes while one plane is being written to. This is done with the
; map mask register in the sequencer. All the other weird and wonderful
; registers in the EGA/VGA do just fine with their default settings, thank
; goodness.
@@writebyte:
stosb ; AL into ES:DI, inc DI
inc dl ; increment column
cmp dl, ah ; reached end of scanline?
je @@doneline ; yes
loop @@writebyte ; no, do another
jmp short @@getbyte ; or get more data
@@doneline:
shl bp, 1 ; shift to next plane
cmp bp, 8 ; done 4 planes?
jle @@setindex ; no
mov bp, 1 ; yes, reset plane to 1
add di, Margin ; skip to start of next scanline
mov dx, ScreenWidth
add LineEnd, dx
jmp short @@setplane
@@setindex:
sub di, dx ; reset index to start of same line
@@setplane:
push ax ; save AX
cli ; no interrupts
mov ax, bp ; plane is 1, 2, 4, or 8
mov dx, 3C5h ; sequencer data register
out dx, al ; mask out 3 planes
sti ; enable interrupts
pop ax ; restore AX
xor dx, dx ; reset column count
loop @@writebyte ; do it again, or fetch more data
; --- Loop through input buffer
; Here's how the data compression system works. Each byte is either image
; data or a count byte that tells how often the next byte is to be
; repeated. The byte is image data if it follows a count byte, or if
; either of the top 2 bits is clear. Otherwise it is a count byte, with
; the count derived from the lower 6 bits.
@@getbyte: ; last byte was not a count
cmp si, bx ; end of input buffer?
je @@exit ; yes, quit
push ds ; save program data
push si
lds si, Scratch ; input segment into DS
pop si
lodsb ; get a byte from DS:SI into AL, increment SI
pop ds ; restore program data
cmp al, 192 ; test high bits
jb @@one_data ; not set, it's data to be written once
; It's a count byte:
xor al, 192 ; get count from 6 low bits
mov cl, al ; store repeat count
cmp si, bx ; end of input buffer?
je @@exit ; yes, quit
@@multi_data:
push ds ; save program data
push si
lds si, Scratch ; segment of input buffer into DS
pop si
lodsb ; get a byte from DS:SI into AL, increment SI
pop ds ; restore program data
jmp @@writebyte ; write it CL times
@@one_data:
mov cl, 1 ; write byte once
jmp @@writebyte
; --- Finished with buffer ---
@@exit:
mov Plane, bp ; save status for next run thru buffer
mov RepeatCount, cl
mov ColumnCount, dx
mov VideoOffs, di
pop bp
pop di ; restore any C register variables
pop si
ret
Decode16 ENDP
; ------------------------- 256-COLOR VGA FILES ---------------------------
Decode256 PROC
; Main use of registers:
; AL data byte to be written to video
; BX end of input buffer
; CL number of times data byte is to be written
; DX temporary storage of EndOfLine
; ES segment of output buffer
; DI index into output buffer
; SI index into input buffer
push si ; save C register variables
push di ; ditto
push bp
les si, Scratch ; index into input buffer in SI
; ES not used here - we don't use LDS because we want to preserve DS
mov bx, DataLength ; end of input buffer
add bx, si ; adjust datalength - SI may not be 0
mov es, VideoSeg ; base address of output window
mov di, VideoOffs ; index into window
xor cx, cx ; clean up loop counter
mov cl, RepeatCount ; restore count from last byte
cld ; clear DF
cmp cl, 0 ; was last byte a count?
jne @@multi_data ; yes, so next is data
; --- Loop through input buffer ---
@@getbyte: ; last byte was not a count
cmp di, LineEnd ; reached end of line?
jb @@NoLineEnd ; no
add di, Margin
mov dx, ScreenWidth
add LineEnd, dx
@@NoLineEnd:
cmp si, bx ; end of input buffer?
je @@exit ; yes, quit
push ds ; save Pascal's data segment
push si ; Get segment of input buffer into DS
lds si, Scratch ; while preserving SI
pop si
lodsb ; get byte from DS:SI into AL, increment SI
pop ds ; restore program data
cmp al, 192 ; test high bits
jb @@one_data ; not set, not a count
; It's a count byte
xor al, 192 ; get count from 6 low bits
mov cl, al ; store repeat count
cmp si, bx ; end of input buffer?
je @@exit ; yes, quit
@@multi_data:
push ds ; save program data
push si
lds si, Scratch
pop si
lodsb ; get byte from DS:SI into AL, increment SI
pop ds ; restore program data
rep stosb ; write byte CX times
jmp @@getbyte
@@one_data:
stosb ; byte into video
jmp @@getbyte
; --- Finished with buffer
@@exit:
mov VideoOffs, di ; save status for next run thru buffer
mov RepeatCount, cl
pop bp
pop di ; restore any C register variables
pop si
ret
Decode256 ENDP
END