[Back to GRAPHICS SWAG index] [Back to Main SWAG index] [Original]
{$F+,O+}
unit Screen_d;
INTERFACE
uses DOS, GRAPH;
type RGBrec = record
redval, greenval, blueval: byte;
end;
var SCRfilename: pathstr;
file_error: boolean;
pal: palettetype;
RGBpal: array[0..15] of RGBrec;
page_addr: word;
bytes_per_line: word;
buff0, buff1: pointer;
{ CGA display memory banks: }
screenbuff0: array[0..7999] of byte absolute $b800:$0000;
screenbuff1: array[0..7999] of byte absolute $b800:$2000;
const page0 = $A000; { EGA/VGA display segment }
procedure READSCR(pfilename: pathstr);
{========================================================================}
IMPLEMENTATION
var scratch, abuff0, abuff1: pointer;
is_VGA: boolean;
repeatcount: byte;
datalength: word;
columncount, plane, video_index: word;
regs: registers;
const buffsize = 65521; { Largest possible }
{ ====================== EGA/VGA 16-color files ========================= }
procedure DECODE_16; assembler;
asm
push bp
{ ----------------- Assembler procedure for 16-color files -------------- }
{ The first section is initialization done on each run through the
input buffer. }
@startproc:
mov bp, plane { plane in BP }
mov es, page_addr { video display segment }
mov di, video_index { index into video segment }
mov ah, byte ptr bytes_per_line { 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 }
push ds { save DS }
lds si, scratch { input buffer pointer in DS:SI }
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 @getbyte { no, so find out what next is }
{ -------------- Procedure to write EGA/VGA image to video -------------- }
@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 @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 but don't reset index }
jmp @setplane
@setindex:
sub di, dx { reset to start of 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 }
@getbyte: { last byte was not a count }
cmp si, bx { end of input buffer? }
je @exit { yes, quit }
lodsb { get a byte from DS:SI into AL, increment SI }
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:
lodsb { get data byte }
jmp @writebyte { write it CL times }
@one_data:
mov cl, 1 { write byte once }
jmp @writebyte
{ ---------------------- Finished with buffer --------------------------- }
@exit:
pop ds { restore Turbo's data segment }
mov plane, bp { save status for next run thru buffer }
mov repeatcount, cl
mov columncount, dx
mov video_index, di
pop bp
end; { asm }
{ ============= Main procedure for CGA and 16-color files =============== }
procedure READSCR(pfilename: pathstr);
type ptrrec = record
segm, offs: word;
end;
var entry, gun, SCRcode, mask, colorID: byte;
palbuf: array[0..66] of byte;
SCRfile: file;
begin { READ_SCR_FILE }
assign(SCRfile, pfilename);
{$I-}
reset(SCRfile, 1);
{$I+}
getmem(scratch, buffsize); { Allocate scratchpad }
blockread(SCRfile, scratch^, 128); { Get header into scratchpad }
move(scratch^, palbuf, 67);
bytes_per_line:= palbuf[66];
begin
video_index:= 0;
port[$3C4]:= 2; { Index to map mask register }
plane:= 1; { Initialize plane }
port[$3C5]:= plane; { Set sequencer to mask out other planes }
for entry:= 0 to 15 do
begin
colorID:= 0;
for gun:= 0 to 2 do
begin
SCRcode:= palbuf[16 + entry * 3 + gun]; { Get primary color value }
begin
with RGBpal[entry] do { Interpret for VGA }
case gun of
0: redval:= SCRcode div 4;
1: greenval:= SCRcode div 4;
2: blueval:= SCRcode div 4;
end;
end; { is_VGA }
end; { gun }
pal.colors[entry]:= entry;
end; { entry }
pal.size:= 16;
end; { not is_CGA }
repeatcount:= 0; { Initialize assembler vars. }
columncount:= 0;
repeat
blockread(SCRfile, scratch^, buffsize, datalength);
decode_16; { Call assembler routine }
until eof(SCRfile);
close(SCRfile);
freemem(scratch,buffsize); { Discard scratchpad }
end; { READ_SCR_FILE }
Begin
Page_addr := Page0;
END.
[Back to GRAPHICS SWAG index] [Back to Main SWAG index] [Original]