[Back to EGAVGA SWAG index] [Back to Main SWAG index] [Original]
{
Hi Kai. I read your message about 360x256x256 and saw you were using
Tweak. This is message 1/2 which includes Pascal versions of Twkuser.c
and Tweak2c. Thought they might be helpful to you.
Maurice L. Marvin
maurice@cs.pdx.edu
}
{$I-}
UNIT TWKUSER;
{=========================================================================
TWKUSER.PAS is a Borland Pascal 7.0 compatible unit for using Robert
Schmidt's TWEAK generated files.
Ported to Pascal from Robert Schmidt's original C code.
Donated to public domain.
Maurice L. Marvin
maurice@cs.pdx.edu
==========================================================================}
INTERFACE
CONST
{ xxxxADDR defines the base port number used to access VGA
component xxxx, and is defined for xxxx =
ATTRCON - Attribute Controller
MISC - Miscellaneous Register
VGAENABLE - VGA Enable Register
SEQ - Sequencer
GRACON - Graphics Controller
CRTC - Cathode Ray Tube Controller
STATUS - Status Register }
ATTRCON_ADDR = $3C0;
MISC_ADDR = $3C2;
VGAENABLE_ADDR = $3C3;
SEQ_ADDR = $3C4;
GRACON_ADDR = $3CE;
CRTC_ADDR = $3D4;
STATUS_ADDR = $3DA;
TYPE
Register = RECORD
port : WORD;
index : BYTE;
value : BYTE;
END;
RegisterPtr = ^Register;
PROCEDURE ReadyVgaRegs;
PROCEDURE OutReg(r : Register);
PROCEDURE OutRegArray(r : RegisterPtr;
n : INTEGER);
FUNCTION LoadRegArray(fpath : STRING;
VAR RegArray : RegisterPtr) : INTEGER;
IMPLEMENTATION
{--------------------------------------------------------------------------
ReadyVGARegs does the initialization to make the VGA ready to accept
any combination of configuration register settings.
This involves enabling writes to index 0 to 7 of the CRT controller
(port $3d4), by clearing the most significant bit (bit 7) of index
$11.
--------------------------------------------------------------------------}
PROCEDURE ReadyVGARegs;
VAR
v : BYTE;
BEGIN {*** Begin procedure ReadyVGARegs ***}
Port[$3d4] := $11;
v := Port[$3d5] AND $7f;
Port[$3d4] := $11;
Port[$3d5] := v;
END; {*** End procedure ReadyVGARegs ***}
{--------------------------------------------------------------------------
OutReg sets a single register according to the contents of the passed
Register structure.
--------------------------------------------------------------------------}
PROCEDURE OutReg(r : Register);
VAR
v : BYTE;
BEGIN {*** Begin procedure OutReg ***}
CASE (r.port) OF
ATTRCON_ADDR : BEGIN
v := Port[STATUS_ADDR]; { Reset read/write flip flop
} Port[ATTRCON_ADDR] := r.index OR $20;
{ Ensure VGA output is enabled }
Port[ATTRCON_ADDR] := r.value;
END;
MISC_ADDR,
VGAENABLE_ADDR : BEGIN
Port[r.port] := r.value; { Directly to the port }
END;
ELSE { Default method }
BEGIN
Port[r.port] := r.index; { Index to port }
Port[r.port + 1] := r.value; { Value to port + 1}
END;
END;
END; {*** End procedure OutReg ***}
{--------------------------------------------------------------------------
OutRegArray sets n registers according to the array pointed to by r.
First, indexes 0-7 of the CRT controller are enabled for writing.
--------------------------------------------------------------------------}
PROCEDURE OutRegArray(r : RegisterPtr;
n : INTEGER);
VAR
s : WORD;
BEGIN {*** Begin procedure OutRegArray ***}
s := SizeOf(Register);
ReadyVGARegs;
WHILE (n > 0) DO
BEGIN
OutReg(r^);
ASM { Increment pointer to next record }
MOV DX,s
ADD WORD PTR [r],DX
END;
DEC(n);
END;
END; {*** End procedure OutRegArray ***}
{--------------------------------------------------------------------------
LoadRegArray opens the given file, does some validity checking, then
reads the entire file into an array of Registers, which is returned
via the RegArray parameter.
You will probably want to provide your own error handling code in this
function, as it never aborts the program, rather than just printing
an error message and returning NULL.
The returned value is the number of registers read. The RegArray
parameter is set to the allocated register array.
If you use this function, remember to dispose the returned array pointer,
as it was allocated dynamically using GetMem (unless NULL is returned,
which designates an error).
--------------------------------------------------------------------------}
FUNCTION LoadRegArray(fpath : STRING;
VAR RegArray : RegisterPtr) : INTEGER;
VAR
handle : FILE;
fsize : LONGINT;
BEGIN {*** Begin function LoadRegArray ***}
LoadRegArray := 0;
RegArray := NIL;
ASSIGN(handle,fpath);
RESET(handle,1);
IF (IOResult <> 0) THEN { error opening file ? }
BEGIN
{ include error handling code here }
Exit;
END;
fsize := FileSize(handle);
IF (IOResult <> 0) THEN { error acquiring file size ? }
BEGIN
CLOSE(handle);
Exit;
END;
IF (fsize MOD SizeOf(Register) <> 0) THEN { Is filesize multiple of record
? } BEGIN
WriteLn('Illegal TWEAK file size: ',fpath);
CLOSE(handle);
Exit;
END;
IF (MaxAvail < fsize) THEN { Is there enough memory ? }
BEGIN
WriteLn('Out of memory allocating buffer for ',fpath);
CLOSE(handle);
Exit;
END;
GetMem(RegArray,fsize);
BlockRead(handle,RegArray^,fsize);
IF (IOResult <> 0) THEN { Error reading file ? }
BEGIN
CLOSE(handle);
Dispose(RegArray);
RegArray := NIL;
Exit;
END;
CLOSE(handle);
IF (IOResult <> 0) THEN { Error closing file ? }
BEGIN
Dispose(RegArray);
RegArray := NIL;
Exit;
END;
LoadRegArray := fsize DIV SizeOf(Register);
END; {*** End function LoadRegArray ***}
END.
{$I-}
PROGRAM TWEAK2P;
USES TWKUSER;
{=========================================================================
TWEAK2P version 1.0
Ported to Pascal from Robert Schmidt's original C code.
Converts a TWEAK version 1.0 file to an include-able Pascal file,
defining the equivalent register array, which is passable
to the OutRegArray function defined in the TWKUSER unit.
Maurice L. Marvin
maurice@cs.pdx.edu
=========================================================================}
VAR
table : RegisterPtr;
btable : RegisterPtr;
regsize : INTEGER;
handle : TEXT;
b1 : BYTE;
b2 : BYTE;
s : WORD;
BEGIN {*** Begin program TWEAK2P ***}
{ Check command line arguments. }
IF (ParamCount < 3) THEN
BEGIN
WriteLn;
WriteLn('TWEAK2P version 1.0');
WriteLn('Converts a TWEAK version 1.x file to an include-able Pascal
file.'); WriteLn;
WriteLn('SYNTAX: TWEAK2P <TWEAK-File> <Pascal File to Create> <Array
Name>'); WriteLn('All Parameters are required.');
Halt(1);
END;
{ Load the register file. }
regsize := LoadRegArray(ParamStr(1),table);
{ Save a pointer to the start of the table. The pointer 'table' will
be corrupted due to pointer arithmetic. }
btable := table;
{ Check if we loaded the table successfully. }
IF (Table = NIL) THEN
BEGIN
WriteLn;
WriteLn('ERROR : Unable to load register file.');
Halt(1);
END;
{ Open the destination file. }
ASSIGN(handle,ParamStr(2));
REWRITE(handle);
IF (IOResult <> 0) THEN { Check if error creating file. }
BEGIN
WriteLn;
WriteLn('ERROR : Unable to create destination file.');
Halt(1);
END;
{ Write data structure }
WriteLn(handle,'{ Tweaked include file generated by TWEAK2P } ');
WriteLn(handle,'');
WriteLn(handle,'CONST');
WriteLn(handle);
Write(handle,' ',ParamStr(3),' : ARRAY[1..',RegSize);
WriteLn(handle,'] OF Register = (');
Write(handle,' ');
s := SizeOf(Register);
{ Write register values }
WHILE (RegSize > 0) DO
BEGIN
Write(handle,'(Port : ',table^.port);
Write(handle,'; Index : ',table^.index);
Write(handle,'; Value : ',table^.value,')');
DEC(RegSize);
IF (RegSize = 0) THEN
WriteLn(handle,');')
ELSE
WriteLn(handle,',');
ASM { move to next record }
MOV DX,s
ADD WORD PTR [table],DX
END;
Write(handle,' ');
END;
CLOSE(handle);
Dispose(btable);
END. {*** End program Tweak2P ***}
[Back to EGAVGA SWAG index] [Back to Main SWAG index] [Original]