Procedure CGA_CO_Palette(Hdr:PCXHeader); { Set CGA palette for 320x200 mode }
Var Fore,BackGround : Byte;
begin Fore:=Hdr.Palette[4] SHR 5; BackGround:=Hdr.Palette[1] SHR 4; IF Fore > 4 THEN Dec(Fore,4); IF Not (Fore IN [0,2]) THEN BackGround:=BackGround OR $10; IF Fore > 1 THEN Fore:=1 ELSE Fore:=0; asm mov bh,0 mov bl,byte ptr BackGround mov ah,0Bh int 10h mov bh,1 mov bl,byte ptr Fore mov ah,0Bh int 10h end; end;
Procedure CGA_BW_Palette(Hdr:PCXHeader); { Set CGA palette for 640x200 mode }
Var BackGround : Byte;
begin BackGround:=Hdr.Palette[1] SHR 4; asm mov bh,1 mov bl,byte ptr BackGround mov ah,0Bh int 10h end; end;
Procedure EGA_16_Palette(Hdr:PCXHeader); { Set palette for EGA color modes }
Var I : Byte; Pal : Array[0..16] OF Byte; PalPtr : Pointer;
begin PalPtr:=@Pal; With Hdr DO begin FOR i:=0 TO 15 DO begin Pal[i]:=((Palette[i*3+1] AND $48 )+ (Palette[i*3+2] AND $48 ) SHR 1+ (Palette[i*3+3] AND $48 ) SHR 2) SHR 1; end; end; Pal[16]:=0; asm les dx,PalPtr mov ax,1002h int 10h end; end;
Procedure VGA_256_Palette(Hdr:PCXHeader; Var F:File);
{ Set palette for 256-colors VGA mode }
Var I : Word; Pal : Array[0..768] OF Byte; PalPtr : Pointer;
begin PalPtr:=@Pal[1]; Seek(F,FileSize(F)-769); BlockRead(F,Pal,769); IF Pal[0] = $0C THEN FOR i:=1 TO 768 DO Pal[i]:=Pal[i] SHR 2; Seek(F,SizeOF(PCXHeader)); asm les dx,PalPtr mov ax,1012h mov cx,100h mov bx,0 int 10h end; end;
Procedure VGA_16_Palette(Hdr:PCXHeader); { Set palette for 16-colors VGA mode }
Var Pal : Array[1..48] OF Byte; CurrPtr : Pointer; i : Byte;
begin FOR i:=1 TO 48 DO Pal[i]:=Hdr.Palette[i] SHR 2; CurrPtr:=@Pal[1]; FOR i:=0 TO 15 DO begin asm les di,CurrPtr mov ax,1007h mov bl,byte ptr i int 10h mov bl,bh xor bh,bh mov ax,1010h mov dh,byte ptr es:[di] mov ch,byte ptr es:[di+1] mov cl,byte ptr es:[di+2] int 10h end; Inc(LongInt(CurrPtr),3); end;
xor dx,dx mov cx,DiskBufSize mov bx,word ptr FHandle mov ah,3Fh int 21h { jc error_label for dirk error handling } pop cx pop bx end;
{$F-} Procedure Init_Output_1_Planes; Assembler; asm mov bp,word ptr [bp+4] { Initial settings before output string } { to video buffer for 1-bit plane mode } inc word ptr NLines { ( BW EGA,VGA 256 ) }
mov ax,word ptr NLines cmp word ptr YLen,ax je @Finish
mov ax,word ptr BytesPerRow add word ptr ScrOfs,ax
xor ax,ax jmp @Exit
@Finish:
xor ax,ax inc ax
@Exit:
end;
Procedure Init_Output_4_Planes; Assembler; asm mov bp,word ptr [bp+4] { Initial settings before output string } { to video buffer for 4-bit plane mode } cmp bl,10h { ( Color EGA,VGA ) } jne @Not_10
mov bl,1 inc word ptr NLines mov ax,word ptr BytesPerRow add word ptr ScrOfs,ax
mov ax,word ptr NLines cmp word ptr YLen,ax je @Finish
@Not_10:
mov dx,3C4h mov al,2 out dx,al { Select Bit Plane } inc dx mov al,bl out dx,al
shl bl,1
xor ax,ax jmp @Exit
@Finish:
xor ax,ax inc ax
@Exit:
end;
Procedure Init_Output_CGA; Assembler; asm mov bp,word ptr [bp+4] { Initial settings before output string } { to video buffer for CGA mode } inc word ptr NLines
cmp byte ptr VideoBase+1,0B8h je @Even_Line
mov byte ptr VideoBase+1,0B8h mov ax,word ptr NLines cmp word ptr YLen,ax je @Finish
mov ax,word ptr BytesPerRow add word ptr ScrOfs,ax jmp @Not_Finish
@Even_Line:
mov byte ptr VideoBase+1,0BAh
@Not_Finish:
xor ax,ax jmp @Exit
@Finish:
xor ax,ax inc ax
@Exit:
end;
{$F+}
begin IF Pos('.',FName) = 0 THEN FName:= ParamStr(1) +'.PCX'; Assign(F,FName); Reset(F,1); IF IOResult <> 0 THEN begin Writeln('File ',FName,' not found.'); Halt(1); end;
BlockRead(F,Hdr,128); { IF IOResult <> 0 THEN .... } With Hdr DO begin IF PCXid <> $0A THEN begin Writeln('File ',FName,' not PCX file.'); Halt(1); end;
FOR Mode:=ValidMode(0) TO DUMMYMODE DO IF CompStruct(TestMode, MyModes[Mode], 6) = Equal THEN GoTo OurMode;
Writeln('File ',FName,' is not my image.'); Writeln(' XRes=',TestMode.XRes, ' YRes=',TestMode.YRes, ' BitsPerPixel=',TestMode.BitsPerPixel, ' NPlanes=',TestMode.NPlanes); Halt(1);
OurMode:
i:=MyModes[Mode].VideoMode; asm mov ax,word ptr i { Set required mode } int 10h end;
FHandle:=FileRec(F).Handle;
With Hdr DO begin XLen:=BytesPerLine; YLen:=Succ(YH-YL); ByteNum:=Succ(XH-XL) DIV 8 * MyModes[Mode].BitsPerPixel; BytesPerRow:=XRes DIV 8 * MyModes[Mode].BitsPerPixel; GetMem(ScrBuf,XLen+63+16); GetMem(DiskBuf,DiskBufSize+16); end;
ScrOfs:=0; IF Mode IN [EGA320x200x16, EGA640x200x16, EGA640x350x2, EGA640x350x16] THEN ScrOfs:=VideoPage*MemW[0:$44C] ELSE VideoPage:=0; { Only 1 VideoPage Allowed }
{ Set Palette }
CASE Mode OF
CGA320x200x4 : CGA_CO_Palette(Hdr); CGA640x200x2 : CGA_BW_Palette(Hdr); VGA320x200x256: VGA_256_Palette(Hdr,F); VGA640x480x16 : VGA_16_Palette(Hdr); ELSE IF Hdr.NPlanes = 4 THEN EGA_16_Palette(Hdr);
end; { CASE }
IF Hdr.NPlanes = 4 THEN begin NLines:=0; VideoBase:=$A000; InitOutputProc:=Addr(Init_Output_4_Planes) end ELSE begin ScrOfs:=Word(ScrOfs-BytesPerRow); NLines:=Word(-1); VideoBase:=$A000; InitOutputProc:=Addr(Init_Output_1_Planes); end;
IF Mode IN [CGA320x200x4, CGA640x200x2] THEN begin NLines:=Word(-1); VideoBase:=$BA00; InitOutputProc:=Addr(Init_Output_CGA); end;