If you appreciate the work done within the wiki, please consider supporting The Cutting Room Floor on Patreon. Thanks for all your support!

TNN Motorsports Hardcore 4X4 (Sega Saturn)

From The Cutting Room Floor
Jump to navigation Jump to search

Title Screen

TNN Motorsports Hardcore 4X4

Also known as: Hardcore 4X4 (EU), Deka Yonku: Tough the Truck (JP)
Developer: Gremlin Interactive
Publishers: ASC Games (US), Gremlin Interactive (EU), Human Entertainment (JP)
Platform: Sega Saturn
Released in JP: May 2, 1997
Released in US: 1996
Released in EU: 1997


DevTextIcon.png This game has hidden development-related text.


Build Info

Present at 0x2DFD8 in 0FE.BIN, along with a hidden developer credit.

Ver2.04 96/01/25<< SEGASATURN >>A.Miyazawa 16:54(C) SEGA Enterprises / Digital Media R&D ,Sound Division
(Source: Original TCRF research)

Development Text

All text in this section can be found in 0GG.BIN.

Debug Menu Text

Some text for a possible debug menu.

0x50C:

 SATURATE 
 FOG BLUE 
 FOG GREEN
 FOG RED  
 FOGGING  
  CAR AI  
 VIEW ANG 
 DBG COL  
 PERSPECT 
  OBJECTS 
Z CLIP DST
   LIFT   
PROFILING 
MESH ZONE

0x730:

 12345678 
VERTS
POLYS
T VERTS
T POLYS
O VERTS
O POLYS

0x7F40:

CAR : 
FBEHIND
NBEHIND
CAR-CAM
DASHCAM
FIX-PER
ZONE : 
HGT : 
CLIP : 
DISPLAY ALL  
   MOBILE 
   STATIC 
ANG :  
COL :  
AI :  
FOG :  
RED :  
GREEN : 
BLUE : 
SAT  : 

MS-DOS Leftovers

A bunch of text left over from various DOS programs.

0xE582:

DOS4GPATH
PATH
.exe
dos4gw.exe
Stub exec failed:
Error 0
No such file or directory
Argument list too big
Exec format error
Bad file number
Not enough memory
Permission denied
File exists
Cross-device link
Invalid argument
File table overflow
Too many open files
No space left on device
Argument too large
Result too large
Resource deadlock would occur
unknown error
PATH
.com
.exe
Not enough memory on exec

0x248EC:

ST2PC.EXE by Steve Camber.
Converts PI1 files to BMP
Usage:
        ST2PC Pi1File [options]
Where:
        Pi1File = file to convert
        Options = /?     This help
                  /V     View Bitmaps
 
No bitmaps added to list..
Added %s 
Error - invalid file
Error - could not open file
Error - not 16 or 256 cols
Error - could not read file
Error - bitmap too big
Error - invalid true colour bin
Could not add %s
rb Unable to open PI1 file %s 
 Real   16 colour source.   256 colour source.   Not 16 or 256 colour bitmap.  
Size = %ix%i.   Bodge  15-bit BIN bitmap   X: %3i  Y: %3i   
ab BITMAPS.BIN Unable to open BITMAPS.BIN %s 
rb PALETTES.BIN
wb PALETTES.BIN
Unable to open PALETTES.BIN %s 
ab BITMAPS.INF Unable to open BITMAPS.INF %s 
at BITMAPS.TXT Unable to open BITMAPS.TXT %s 
%30s  Pal:%03i  X: %3i  Y: %3i  Cols:  %3i
32768
Not enough memory to allocate file structures
Floating-point support not loaded
Stack Overflow!

0x250E0:

		}
	else
		use_local_keyboard (_mod_template);

	returns ("");
}

string  .def_template_first (~int, ~int, ~int, ~int)
{
	_mod_indent_block = TRUE;
	_mod_indent_close = FALSE;
	_mod_indent_first = FALSE;
	_mod_min_abbrev = MIN_ABBREV;

	get_parm (0, _mod_indent_block);
	get_parm (1, _mod_indent_close);
	get_parm (2, _mod_indent_first);
	get_parm (3, _mod_min_abbrev);

	if (_mod_min_abbrev == 0)
		{
		use_local_keyboard (_mod_alt_template);
		_mod_min_abbrev = 1;
		}
	else
		use_local_keyboard (_mod_template);

	returns ("");
}
�
/*
**	These definitions are used as Modula-2 "language sensitive" word patterns
*/

int .mod_next_word ()
{
	returns (.c_next_word ());
}

int .mod_previous_word ()
{
	returns (.c_previous_word ());
}
�
/*
**		.mod_indent:
**
**		This macro does syntax-sensitive indenting ("smart indenting") for
**	Modula-2 language files.  It handles most common constructs, except
**	for nested comments.
**
**	Parameters:
**		0 -- if TRUE, the line is reindented if necessary, but the line
**			is never split, no newline is inserted, and the cursor is left
**			at the end of the line.
*/

void .mod_indent (~int)
{
	int	curr_line, 					//	Line cursor is on when called.
			code_line, 					//	Line where last code char is found.
			code_indent_level,		//	Current indent level, in tab stops.
			prev_indent_level,		//	Indent level of previous line.
			code_trail,					//	The last code character.
			prev_trail,					//	Last code char before code_line.
			scratch,						//	Temporary integer.
			match_indented;			//	Was keyword indented extra level?

	string	following_string,		//	Remainder of line being split.
				code_text, 				//	Trimmed text of code line.
				token,					//	Tokenized version of line.
				prev_text; 				//	Trimmed text of previous line.

	/*
	**		Initialize.
	*/

	inq_position (curr_line, NULL);
	code_trail = prev_trail = '\;';

	/*
	**		If we're in overstrike mode, we act as if we were at the
	**	end of the line when the command was invoked.
	**
	**		If we're in insert mode, we may have to split the line.
	*/

	if (!inq_mode ())
		end_of_line ();

	/*
	**		If line is being split, cut text to following_string.
	**	Leave all trailing whitespace except the newline.
	*/

	else if (read (1) != "\n")
		{
		following_string = ltrim (read ());
		following_string = substr (following_string, 1, strlen (following_string) - 1);
		delete_to_eol ();
		}
	/*
	**		Find the last "code" character; skip back over whitespace and
	**	comments until we get something different.  The cursor will be
	**	left on the next character from the "different" one; we do a
	**	(prev_char) to get to the code character.  (If it fails, we're
	**	at the top of the buffer.)
	*/

	search_back (MOD_SKIP_PAT, -2);

	/*
	**		Remember which line we found the code character on.  Classify
	**	the code character by looking it up in a string, and save
	**	a "tokenized" version of the whole line.
	*/

	if (prev_char ())
		{
		/*		
		**		We save the identity of the last code character on
		**	the "code line".
		*/

		inq_position (code_line);
		code_trail = atoi (read (1), 0);

		/*
		**		Find the first non-white character on the line, so
		**	we may determine its indenting level.	Save the
		**	text of the line for later parsing.
		*/

		.mod_first_nonwhite ();
		code_indent_level = .mod_indent_level ();
		code_text = trim (read ());

		/*
		**		Find the last code line before this, and read information
		**	about it.
		*/

		if (up ())
			{
			end_of_line ();

			if (search_back (MOD_SKIP_PAT, -2) && prev_char ())
				{
				prev_trail = atoi (read (1), 0);
				.mod_first_nonwhite ();
				prev_indent_level = .mod_indent_level ();
				prev_text = trim (read ());
				}
			}

		/*
		**		Get the first token on the code line.	This assumes
		**	that tokens are separated by spaces.
		*/

		token = substr (code_text, 1, index (code_text + " ", " ") - 1);
		}
	/*
	**		Move to the beginning of the line the cursor was originally on.
	**	Occasionally, we have to adjust its indent level.	However,
	**	if the line contains no code, we don't need to worry about it.
	*/

	move_abs (curr_line, 1);

	if (code_line == curr_line)

		/*
		**		We align the first BEGIN of a procedure, as well as
		**	declarations, with the procedure declaration above.
		**	If _mod_indent_first is TRUE, we indent one level right
		**	of the declaration.	We leave the positioning of nested
		**	procedures up to the user, since we can't distinguish
		**	them from procedures in the definition module.
		*/

		switch (token)
			{
			case "BEGIN":
			case "VAR":
			case "TYPE":
			case "CONST":
			case "FROM":
			case "IMPORT":
			case "EXPORT":
				{
				/*
				**		By default, we will align this line with the last.
				*/

				code_line = prev_indent_level;

				switch (substr (prev_text, 1, index (prev_text + " ", " ") - 1))
					{
					/*
					**		The default works for PROCEDURE and MODULE
					**	unless _mod_indent_first is TRUE.
					*/

					case "PROCEDURE":
					case "MODULE":
					case "IMPLEMENTATION":
					case "DEFINITION":
						if (_mod_indent_first)
							++code_line;

					/*
					**		VAR, CONST, and TYPE are no problem.
					*/

					case "VAR":
					case "CONST":
					case "TYPE":
					case "FROM":
					case "IMPORT":
					case "EXPORT":
						nothing ();

					/*
					**		Other declarations are probably indented
					**	a level from where we want to be.
					*/

					default:
						--code_line;
					}
				if (code_indent_level != code_line)
					.mod_reindent (code_text, code_indent_level = code_line);

				}
			/*
			**		Outdent an END so it's flush with the last keyword
			**	that could match it.  We put END in the search pattern
			**	so nested blocks work.	ELSE keywords should be indented
			**	one additional level if they matched a CASE.
			*/

			case "END;":
			case "END":
			case "ELSE":
			case "ELSIF":
				{
				match_indented = .mod_outdent_to_match 
					("<|[ \\t]{BEGIN}|{CASE}|{FOR}|{IF}|{LOOP}|{MODULE}|{RECORD}|{WHILE}|{WITH}|{END;@}[ \\t\\n (]", code_indent_level, code_text);
				}
			/*
			**		Outdent an UNTIL until it aligns with a logical REPEAT.
			*/

			case "UNTIL":
				{
				match_indented = .mod_outdent_to_match ("<|[ \\t]{REPEAT}|{UNTIL}[ \\t\\n (]", code_indent_level, code_text);
				code_trail = '\;';
				}
			/*
			**		Outdent modules to column 1.
			*/

			case "MODULE":
			case "IMPLEMENTATION":
			case "DEFINITION":
				if (code_indent_level)
					.mod_reindent (code_text, code_indent_level = 0);
			}

	/*
	**		Don't let the indenting level go negative.
	*/

	if (code_indent_level < 0)
		code_indent_level = 0;

	/*
	**		Check the parameter.  If it's TRUE, we put the line back
	**	together and return.
	*/

	if (get_parm (0, scratch) && scratch)
		{
		end_of_line ();

		if (following_string != "")
			insert (following_string);

		return;
		}
	/*
	**		Move to the next line, inserting a new line below the current
	**	one if in insert mode.
	*/

	if (inq_mode ())
		{
		end_of_line ();
		insert ("\n");
		}
	else
		down ();

	/*
	**		Now we calculate where to put the cursor on the next line.
	**	The actual algorithm for the default indenting style is:
	**
	**		If the code line was a BEGIN, we indent the next line if
	**	_mod_indent_block is TRUE.
	**
	**		If the code line was an END, we check match_indented; if
	**	it's TRUE, we outdent afterwards, but we normally leave
	**	the cursor under the END.
	**
	**		Declarations force an indent, as do procedure declarations
	**	when _mod_indent_first is TRUE.
	**
	**		All other cases use the default rule, which is to indent if
	**	the last token was a special keyword, and not to indent
	**	otherwise.
	*/


	switch (token)
		{
		case "BEGIN":
		case "RECORD":
			if (_mod_indent_block)
				++code_indent_level;

		case "END;":
		case "END":
			if (match_indented)
				--code_indent_level;

		case "VAR":
		case "CONST":
		case "TYPE":
		case "FROM":
		case "IMPORT":
		case "EXPORT":
			++code_indent_level;

		case "PROCEDURE":
		case "MODULE":
		case "IMPLEMENTATION":
		case "DEFINITION":
			if (_mod_indent_first)
				++code_indent_level;

		/*
		**		We indent when a line ended in THEN, ELSE, ELSIF, DO, OF,
		**	REPEAT, LOOP, or RECORD.  This works well except when a
		**	comment line ends in one of these keywords.	We also
		**	indent when a line ends in a colon (we're probably
		**	in a CASE) and outdent when one ends in a vertical bar
		**	(ditto).
		*/

		default:
			if (code_trail != '\;')

				if (code_trail == ':')
					++code_indent_level;
				else
					if (code_trail == '|')
						--code_indent_level;
					else
						{
						sprintf (code_text, "~%s~", substr (code_text, rindex (" " + code_text, " ")));

						if (index (TERMINAL_LIST, code_text))
							++code_indent_level;
						else if ("~UNTIL~" == code_text)
							--code_indent_level;
						}
		}
	/*
	**		Move to the new position.
	**
	**	If we cut characters from the previous line, reinsert them.
	*/

	move_abs (0, .mod_indent_level (code_indent_level));

	if (following_string != "")
		{
		save_position ();
		insert (following_string);
		restore_position ();
		}
}

/*
**		Maps between indent levels (in tab stops) and column positions in a
**	file.  Column 1 to just before the first tab stop is level 0; from
**	the first to just before the second tab stop is level 1; etc.
**
**		If a parameter is passed, we treat it as an indent level, and we
**	calculate the column corresponding to it.  Otherwise, we calculate
**	the indent level corresponding to the current column.
*/

int .mod_indent_level (~int)
{
	int	curr_col,
			level,
			lev_to_col;

	save_position ();
	curr_col = 1;

	if (get_parm (0, lev_to_col))
		{
		beginning_of_line ();

		while (level < lev_to_col)
			{
			move_abs (0, curr_col += distance_to_tab ());
			++level;
			}
		level = curr_col;
		}
	else
		{
		inq_position (NULL, lev_to_col);
		beginning_of_line ();

		while ((curr_col += distance_to_tab ()) <= lev_to_col)
			{
			move_abs (0, curr_col);
			++level;
			}
		}
	restore_position ();
	returns (level);
}

/*
**		Moves the cursor to the first character on the current line that
**	is not a space or a tab.
*/

void .mod_first_nonwhite ()
{
	beginning_of_line ();
	next_char (strlen (read ()) - strlen (ltrim (read ())));
}

/*
**		Outdents a line until it pairs up with another keyword.
**
**		If the match is of an ELSE to a CASE, the ELSE is reindented one
**	tab stop to the right of the CASE line.  If the match is of an END
**	(or an UNTIL) the END (in some styles) is reindented; the trailing
**	END of a procedure or module is exempted.
**
**	Parameters:
**		0 -- the search pattern.
**		1 -- the current indenting level.
**		2 -- the trimmed text of the line being outdented.
**
**	Returns:
**		TRUE if the line was an END or UNTIL indented an extra level.
**
**		Puts the new indenting level, if it changes, back into parameter 1.
*/

int .mod_outdent_to_match (string match_pattern, int curr_indent_level, string trim_text)
{
	int	new_indent_level,
			nesting,
			token_matched;

	save_position ();
	nesting = 1;

	/*
	**		Repeat until nesting is zero, or until we can't find another
	**	keyword.  END and UNTIL increase the nesting level; other
	**	keywords decrease it.
	*/

	while (nesting)
		{								 		
		move_abs (0, MAX_COL);

		if (!(up () && sea#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <dos.h>
#include <i86.h>


//#define MAX_BMP_SIZE (200*1024)
#define MAX_BMP_SIZE (512*512*2)



#include "st2pc.h"


typedef struct
{
    short Mode;
    short Pal[16];
    short Pixels[80*200];
} PI1Str;

PI1Str Pi1File;

unsigned char   BmpPixData[MAX_BMP_SIZE];
unsigned short  BmpPalData[256];
int             BmpWidth,BmpHeight,BmpCols,BmpPalNum;
long            BmpImageSize;

BMPFILE BmpFile;    //Size up to 128x128x256 BMP file
BODGEBMPFILE BodgeBmpFile;    //48x48x16 Bodge BMP file

int      AddBitmap(char *Fname);
int      ReadRealBmpFile(FILE *fp);
int      ReadBodgeBmpFile(FILE *fp);
int      ReadTrueColFile(FILE *fp);
int      UpdateBitmapsFile(void);
int      UpdatePalettesFile(void);
int      UpdateInfoFile(char *Fname);
//void     ConvBmpInfStr(BmpInfStr *Info);
void     SwapShort(unsigned short *pshort);
void     SwapLong(unsigned long *plong);
void     CheckErr(int Err, struct find_t *);
void     DisplayBitmap(void);
void     GetSysCols(void);
void     SetSysCols(void);
void     SetVideoMode(int set_mode);
int      ReadPI1File(FILE *fp);

int Force16=0;
int BsDone=0;
int OutputBMPs=0;
int OutputPause=0;
int Mode13=0;
int VramOffset;
int Andval[16]={32768,16384,8192,4096,2048,1024,512,256,128,64,32,16,8,4,2,1};

void main(int argc, char * argv[])
{
    //struct ffblk ffblk;
    struct find_t  fileinfo;
    int End;
    int Arg;
    int HelpMe=0;
    int Err;
    int TrackNum;

    //clrscr();

    for (Arg=1;Arg<argc;Arg++)
    {
        if (strcmpi("/?",argv[Arg])==0)
        {
            HelpMe=1;
        }
        else
        if (strcmpi("/V",argv[Arg])==0)
        {
            OutputBMPs=1;
        }
    }

    if (argc<1 || HelpMe)
    {
        printf("\n");
        printf("ST2PC.EXE by Steve Camber.\n");
        printf("Converts PI1 files to BMP\n");
        printf("Usage:\n");
        printf("        ST2PC Pi1File [options]\n");
        printf("Where:\n");
        printf("        Pi1File = file to convert\n");
        printf("        Options = /?     This help\n");
        printf("                  /V     View Bitmaps\n");
        exit(1);
    }

    if (OutputBMPs) GetSysCols();

    //Add bitmaps. Handle wildcards.
    End = _dos_findfirst(argv[1],_A_NORMAL,&fileinfo);
    while (!End)
    {
        Err=AddBitmap(fileinfo.name);       //add the bitmap !
        CheckErr(Err,&fileinfo);
        End = _dos_findnext(&fileinfo);
    }

    if (OutputBMPs)
    {
        SetVideoMode(0x3);  //change back screen mode
        SetSysCols();
    }

    if (BsDone==0)
    {
        printf("\nNo bitmaps added to list..\n");
    }
}


void CheckErr(int Err, struct find_t *ffblk)
{
    switch(Err)
    {
        case 0:
             if (!OutputBMPs) printf("Added %s \n",ffblk->name);
             BsDone++;
             break;

        case -1:
             printf("Error - invalid file\n");
             break;

        case -2:
             printf("Error - could not open file\n");
             break;

        case -3:
             printf("Error - not 16 or 256 cols\n");
             break;

        case -4:
             printf("Error - could not read file\n");
             break;

        case -5:
             printf("Error - bitmap too big\n");
             break;

        case -6:
             printf("Error - invalid true colour bin\n");
             break;

        default:
             printf("Could not add %s\n",ffblk->name);
    }

    if (Err!=0) getch();



}


int AddBitmap(char *Fname)
{
    FILE *NewFile;

    int RealBmp=1;
    int Err=0;

    //fix filename to upper case
    strupr(Fname);

    //open new file
    if((NewFile=fopen(Fname,"rb"))==NULL)
    {
        printf("Unable to open PI1 file %s \n",Fname);
        return -2;
    }


    //initialise BMP header
    BmpFile.bmfh.bfType          = 19778; //"BM"
    BmpFile.bmfh.bfSize          = 32118;
    BmpFile.bmfh.bfReserved1     = 0    ;
    BmpFile.bmfh.bfReserved2     = 0    ;
    BmpFile.bmfh.bfOffBits       = 118  ;

    BmpFile.bmih.biSize          = 40   ;
    BmpFile.bmih.biWidth         = 320  ;
    BmpFile.bmih.biHeight        = 200  ;
    BmpFile.bmih.biPlanes        = 1    ;
    BmpFile.bmih.biBitCount      = 4    ;
    BmpFile.bmih.biCompression   = 0    ;
    BmpFile.bmih.biSizeImage     = 32000;
    BmpFile.bmih.biXPelsPerMeter = 4740 ;
    BmpFile.bmih.biYPelsPerMeter = 4740 ;
    BmpFile.bmih.biClrUsed       = 0    ;
    BmpFile.bmih.biClrImportant  = 0    ;

    ReadPI1File(NewFile);

    if (!Err)
    {
        if (OutputBMPs) DisplayBitmap();    //check it visually
    }

    return Err;
}




int ReadRealBmpFile(FILE *fp)
{
    int  R,G,B,x,y,f;
    long Ret;
    unsigned short OutCol;
    unsigned char TwoPixels;
    unsigned char *tPixels;

    printf("Real  ");

    Ret = fread(&BmpFile.bmfh,sizeof(BITMAPFILEHEADER),1,fp);
    if (Ret<=0) return -4;
    Ret = fread(&BmpFile.bmih,sizeof(BITMAPINFOHEADER),1,fp);
    if (Ret<=0) return -4;

    if (BmpFile.bmih.biBitCount==4)
    {
        BmpCols=16;
        printf("16 colour source.  ");
    }
    else
    if (BmpFile.bmih.biBitCount==8)
    {
        BmpCols=256;
        printf("256 colour source.  ");
    }
    else
    {
        printf("Not 16 or 256 colour bitmap.  \n");
        return -3;
    }


    BmpWidth=(int)BmpFile.bmih.biWidth;
    BmpHeight=(int)BmpFile.bmih.biHeight;

    if (BmpHeight==0) BmpHeight=BmpWidth; //undocumented thingy ?

    printf("Size = %ix%i.  ",BmpWidth,BmpHeight);

    Ret = fread(&BmpFile.aColors,BmpCols,sizeof(RGBQUAD),fp);    //read in palette
    if (Ret<=0) return -4;

    BmpImageSize=((long)(BmpWidth*BmpHeight*BmpFile.bmih.biBitCount))/8L;

    if (BmpImageSize>MAX_BMP_SIZE) return -5;

    Ret = fread(&BmpFile.aBitmapBits,BmpImageSize,1,fp);    //read in x*y*b pixels
    if (Ret<=0) return -4;

    //convert palette to 15 bit
    for (f=0;f<BmpCols;f++)
    {
        B=BmpFile.aColors[f].rgbBlue  >>3;
        G=BmpFile.aColors[f].rgbGreen >>3;
        R=BmpFile.aColors[f].rgbRed   >>3;
        B=B<<10;
        G=G<<5;
        OutCol=0x8000|B|G|R;
        SwapShort(&OutCol); //swap byte ordering
        BmpPalData[f]=OutCol;
    }

    tPixels=BmpPixData; //pointer to start of pixel data to write

    //
    //
    if (Force16 && BmpCols==256)   //....8-bit to 4-bit conversion
    {
        for (f=0;f<BmpHeight*BmpWidth/2;f++)
        {
            BmpFile.aBitmapBits[f]=
                (BmpFile.aBitmapBits[f*2]   << 4) +
                (BmpFile.aBitmapBits[f*2+1] & 15);
        }
        BmpCols=16;

    }
    //
    //

    if (BmpCols==16)
    {
        for (y=BmpHeight-1;y>=0;y--)
            for (x=0;x<BmpWidth/2;x++)
            {
                TwoPixels=BmpFile.aBitmapBits[y*(BmpWidth/2)+x];
                *tPixels++=TwoPixels;
            }
    }
    else
    if (BmpCols==256)
    {
        for (y=BmpHeight-1;y>=0;y--)
            for (x=0;x<BmpWidth;x++)
            {
                *tPixels++ = BmpFile.aBitmapBits[y*(BmpWidth)+x];
            }
    }

    return 0;   //OK
}

int ReadPI1File(FILE *fp)
{
    int  R,G,B,x,y,f,RGB;
    long Ret;
    unsigned short OutCol;
    unsigned char TwoPixels;
    unsigned char *tPixels;

    Ret = fread(&Pi1File,sizeof(PI1Str),1,fp);

    BmpCols=16;
    BmpWidth=320;
    BmpHeight=200;

    BmpImageSize=(long)(BmpWidth*BmpHeight/2);

    if (BmpImageSize>MAX_BMP_SIZE) return -5;

    //convert palette to 15 bit
    for (f=0;f<BmpCols;f++)
    {
        RGB=Pi1File.Pal[f];
        R=(RGB>> 0)&7;
        G=(RGB>>12)&7;
        B=(RGB>> 8)&7;

        R=R<<2;
        G=G<<7;
        B=B<<12;
        OutCol=0x8000|B|G|R;
        SwapShort(&OutCol); //swap byte ordering
        BmpPalData[f]=OutCol;
    }

    tPixels=BmpPixData; //pointer to start of pixel data to write

    for (y=BmpHeight-1;y>=0;y--)
    {
        for (x=0;x<BmpWidth;x+=16)
        {
            unsigned short P1,P2,P3,P4,z,i1,i2;

            P1=Pi1File.Pixels[y*(BmpWidth/4)+(x/4)+0];
            SwapShort(&P1);
            P2=Pi1File.Pixels[y*(BmpWidth/4)+(x/4)+1];
            SwapShort(&P2);
            P3=Pi1File.Pixels[y*(BmpWidth/4)+(x/4)+2];
            SwapShort(&P3);
            P4=Pi1File.Pixels[y*(BmpWidth/4)+(x/4)+3];
            SwapShort(&P4);

            for (z=0;z<16;z+=2)
            {
                i1=0;
                if (P1 & Andval[z]) i1+=8;
                if (P2 & Andval[z]) i1+=4;
                if (P3 & Andval[z]) i1+=2;
                if (P4 & Andval[z]) i1+=1;

                i2=0;
                if (P1 & Andval[z+1]) i2+=8;
                if (P2 & Andval[z+1]) i2+=4;
                if (P3 & Andval[z+1]) i2+=2;
                if (P4 & Andval[z+1]) i2+=1;
                *tPixels++ = (i1<<4) | i2;
            }
        }
    }

    return 0;   //OK
}


int ReadBodgeBmpFile(FILE *fp)
{
    int  R,G,B,Ret,f;
    unsigned short OutCol;
    unsigned char c1,c2;

    if (!OutputBMPs) printf("Bodge ");

    Ret = fread(&BodgeBmpFile,16*2+48*48/2,1,fp);    //read in 48x48x16 bmp file
    if (Ret<=0) return -4;

    BmpWidth=48;
    BmpHeight=48;
    BmpImageSize=BmpWidth*BmpHeight/2;
    BmpCols=16;

    for (f=0;f<16;f++)
    {
        B= BodgeBmpFile.aColors[f].RGB      & 0x1f;
        G=(BodgeBmpFile.aColors[f].RGB>>5)  & 0x1f;
        R=(BodgeBmpFile.aColors[f].RGB>>10) & 0x1f;
        OutCol=0x8000 | (B<<10) | (G<<5) | R;
        SwapShort(&OutCol); //swap byte ordering
        BmpPalData[f]=OutCol;
    }

    for (f=0;f<BmpWidth*BmpHeight/4;f++)
    {
        c1=BodgeBmpFile.aBitmapBits[f*2  ];
        c2=BodgeBmpFile.aBitmapBits[f*2+1];

        BmpPixData[f*2  ]=c2;
        BmpPixData[f*2+1]=c1;
    }

    return 0;   //OK
}

typedef struct
{
    unsigned long    Size;
    unsigned short   Width;
    unsigned short   Height;
} TRUECOLFILE;


int ReadTrueColFile(FILE *fp)
{
    int  R,G,B,Ret,f;
    unsigned short OutCol;
    unsigned char c1,c2;

    TRUECOLFILE Header;

    printf("15-bit BIN bitmap  ");

    Ret = fread(&Header,sizeof(TRUECOLFILE),1,fp);    //read in header
    if (Ret<=0) return -4;

    SwapShort(&Header.Width);
    SwapShort(&Header.Height);
    SwapLong(&Header.Size);

    printf("X: %3i  Y: %3i   ",Header.Width,Header.Height);

    BmpWidth =Header.Width;
    BmpHeight=Header.Height;
    BmpImageSize=BmpWidth*BmpHeight*2;
    BmpCols=0;
    if (Header.Size!=BmpImageSize) return -6;


    Ret = fread(&BmpPixData,BmpImageSize,1,fp);    //read in pixels
    if (Ret<=0) return -6;

    return 0;   //OK
}

int UpdateBitmapsFile(void)
{
    FILE *BmpFile;

    if((BmpFile=fopen("BITMAPS.BIN","ab"))==NULL)
    {
        printf("Unable to open BITMAPS.BIN %s \n");
        return -2;
    }

    VramOffset=ftell(BmpFile);

    //add bitmap pixel data to end of file
    fwrite(BmpPixData,1,BmpImageSize,BmpFile);

    fclose(BmpFile);

    return 0;
}


unsigned short Palette[512][16];

int UpdatePalettesFile(void)
{
    FILE *PalFile;
    int PalCount=0,f,DupFlag=0;


    if (BmpCols==0)     //true colour - no palette
    {
        BmpPalNum=0;
        return 0;
    }

    if((PalFile=fopen("PALETTES.BIN","rb"))==NULL)
    {
        //PALETTES.BIN doesn't exist yet.
        ;;
    }
    else
    {
        while (!feof(PalFile))
        {
            //read in a 16 colour palette
            if(fread(Palette[PalCount],sizeof(short),16,PalFile)) PalCount++;
        }

        fclose(PalFile);
    }


    //search for duplicate palette
    for (f=0;f<PalCount;f++)
    {
        if (memcmp(Palette[f],BmpPalData,sizeof(short)*BmpCols)==0)
        {
            //duplicate found
            DupFlag=1;
            BmpPalNum=f;
        }
    }

    if (!DupFlag)
    {
        //append new palette
        memcpy(Palette[PalCount],BmpPalData,sizeof(short)*BmpCols);
        BmpPalNum=PalCount;
        PalCount+=(BmpCols/16);
    }

    if((PalFile=fopen("PALETTES.BIN","wb"))==NULL)
    {
        printf("Unable to open PALETTES.BIN %s \n");
        return -2;
    }

    //write new palette
    fwrite(Palette,sizeof(short)*16,PalCount,PalFile);

    fclose(PalFile);

    return 0;
}

int UpdateInfoFile(char *Fname)
{
    FILE *InfFile;
    BmpInfStr Info;

    if((InfFile=fopen("BITMAPS.INF","ab"))==NULL)
    {
        printf("Unable to open BITMAPS.INF %s \n");
        return -2;
    }

    Info.Width   = BmpWidth;
    Info.Height  = BmpHeight;
    Info.CGadr   = VramOffset>>3;
    Info.HVsize  = (((BmpWidth)&0x1f8)<<5)|(BmpHeight);
    Info.Palette = BmpPalNum;
    Info.Colours = BmpCols;
    Info.pad0    = 0;
    Info.pad1    = 0;

//    ConvBmpInfStr(&Info);

    //add bitmap info to end of file
    fwrite(&Info,sizeof(BmpInfStr),1,InfFile);

    fclose(InfFile);

    if((InfFile=fopen("BITMAPS.TXT","at"))==NULL)
    {
        printf("Unable to open BITMAPS.TXT %s \n");
        return -2;
    }
    fprintf(InfFile,"%30s  Pal:%03i  X: %3i  Y: %3i  Cols: ",Fname,BmpPalNum,BmpWidth,BmpHeight);
    if (BmpCols)
        fprintf(InfFile,"%3i\n",BmpCols);
    else
        fprintf(InfFile,"32768\n");
    fclose(InfFile);

    return 0;
}


void SwapLong(unsigned long *plong)
{
    char *Ch;
    char t;


    Ch=(char*)plong;

    //swap outer bytes
    t=Ch[0];
    Ch[0]=Ch[3];
    Ch[3]=t;

    //swap inner bytes
    t=Ch[1];
    Ch[1]=Ch[2];
    Ch[2]=t;

}

void SwapShort(unsigned short *pshort)
{
    char *Ch;
    char t;

    Ch=(char*)pshort;

    //swap bytes
    t=Ch[0];
    Ch[0]=Ch[1];
    Ch[1]=t;

}


void ConvBmpInfStr(BmpInfStr *Info)
{
    //short Width;
    SwapShort((unsigned short*)&Info->Width);

    //short Height;
    SwapShort((unsigned short*)&Info->Height);

    //short CGadr;
    SwapShort((unsigned short*)&Info->CGadr);

    //short HVsize;
    SwapShort((unsigned short*)&Info->HVsize);

    //short Colours;
    SwapShort((unsigned short*)&Info->Colours);

    //short Palette;
    SwapShort((unsigned short*)&Info->Palette);
}


#include <dos.h>

void SetVideoMode(int set_mode)
{
	union REGS r;
    r.h.al=set_mode;
	r.h.ah=0;
	int386(0x10,&r,&r);
}


char SysPal[16][3];

void    GetSysCols(void)
{
    union REGS regs;
    int Col;

    for (Col=0;Col<16;Col++)
    {
        regs.h.al = 0x15;
        regs.h.ah = 0x10;
        regs.w.bx = Col;
        int386(0x10, &regs, &regs);
        SysPal[Col][0]=regs.h.dh;  //red
        SysPal[Col][1]=regs.h.ch;  //green
        SysPal[Col][2]=regs.h.cl;  //blue
    }
}

void    SetSysCols(void)
{
    union REGS regs;
    int Col;

    for (Col=0;Col<16;Col++)
    {
        regs.h.al = 0x15;
        regs.h.ah = 0x10;
        regs.w.bx = Col;
        regs.h.dh = SysPal[Col][0];  //red
        regs.h.ch = SysPal[Col][1];  //green
        regs.h.cl = SysPal[Col][2];  //blue
        int386(0x10, &regs, &regs);
    }
}
void    SetCols(void)
{
    union REGS regs;
    int Col;
    unsigned short Col15;
    char Red,Green,Blue;

    //make sure not doing Vblank
    while((inp(0x3da)&(char)8)==(char)8);
    //wait for vblank
    while((inp(0x3da)&(char)8)==(char)0);

    for (Col=0;Col<BmpCols;Col++)
    {
        Col15=BmpPalData[Col];
        SwapShort(&Col15); //swap byte ordering

        Red=(Col15 & 0x1f)*2;
        Col15=Col15>>5;
        Green=(Col15 & 0x1f)*2;
        Col15=Col15>>5;
        Blue=(Col15 & 0x1f)*2;

        //regs.h.al = 0x10;
        //regs.h.ah = 0x10;
        //regs.x.bx = Col;
        //int86(0x10, &regs, &regs);
        //regs.h.dh = (Col15 & 0x1f)*2;  //red
        //Col15=Col15>>5;
        //regs.h.ch = (Col15 & 0x1f)*2;  //green
        //Col15=Col15>>5;
        //regs.h.cl = (Col15 & 0x1f)*2;  //blue
        //int86(0x10, &regs, &regs);

        //Set Colour
        outp(0x3c8,Col);
        outp(0x3c9,Red);
        outp(0x3c9,Green);
        outp(0x3c9,Blue);
    }
}


unsigned char *screen=(unsigned char *)0xa0000L; /*pointer to screen */

void DisplayBitmap(void)
{
    unsigned char far * Scrptr;
    unsigned char far * Screen;
    int x,y,Centre;
    unsigned char a;

    if (BmpCols==0) return; //can't display true col bmps

    if (!Mode13) SetVideoMode(0x13);
    Mode13=1;

    SetCols();

    Centre=((200-BmpHeight)/2)*320+(320-BmpWidth)/2;

    if (BmpCols==16)
    {
        for (y=0;y<BmpHeight;y++)
        {
            for (x=0;x<BmpWidth/2;x++)
            {
                Scrptr=screen+y*320+x*2+Centre;
                //Scrptr=MK_FP(0xa000,y*320+x*2+Centre);

                a=BmpPixData[y*BmpWidth/2+x];

                *(Scrptr+0)=a>>4;
                *(Scrptr+1)=a&15;
            }
        }
    }
    else
    {
        for (y=0;y<BmpHeight;y++)
        {
            for (x=0;x<BmpWidth;x++)
            {
                Scrptr=screen+y*320+x+Centre;

                a=BmpPixData[y*BmpWidth+x];

                *(Scrptr)=a;
            }
        }
    }

//    if (OutputPause)
    {
        a=getch();
        if (a=='c') OutputPause=0;
    }
}
{32768,16384,8192,4096,2048,1024,512,256,128,64,32,16,8,4,2,1};

void main(int argc, char * argv[])
{
    //struct ffblk ffblk;
    struct find_t  fileinfo;
    int End;
    int Arg;
    int HelpMe=0;

0x308CD0:

Num
0002:0008866c+ long near BmpImageSize
0002:00088670+ __39phjlBMPFILE near BmpFile
0001:0000126d+ void near SetVideoMode( int )
0001:000012ab+ void near GetSysCols()
0001:0000132f+ void near SetSysCols()
0001:000013b3+ void near SetCols()
0001:0000149d+ void near DisplayBitmap()
0002:000003c4+ int near Andval[]
0002:00000404+ char unsigned near * near screen
0002:00108aa8+ __afnb7BODGEBMPFILE near BodgeBmpFile
0002:001092c8+ int near Force16
0002:001092cc+ int near BsDone
0002:001092d0+ int near OutputBMPs
0002:001092d4+ int near OutputPause
0002:001092d8+ int near Mode13
0002:001092dc+ int near VramOffset
0002:001092e0+ short unsigned near Palette[][16]
0002:0010d2e0+ char near SysPal[][3]
Module: c:\watcom\lib386\dos\clib3r.lib(stk386)
0001:00001681* __STK
0001:0000166e  __CHK
0001:0000167e* __GRO
0001:0000169f  __STKOVERFLOW_
Module: c:\watcom\lib386\dos\clib3r.lib(stricmp)
0001:000016ae* stricmp_
0001:000016ae* _stricmp_
0001:000016ae  strcmpi_
Module: c:\watcom\lib386\dos\clib3r.lib(printf)
0001:000016e7  printf_
Module: c:\watcom\lib386\dos\clib3r.lib(exit)
0001:00001709+ __null_int23_exit_
0001:0000170a  exit_
0001:00001722+ _exit_
0002:0000041c+ ___atexit
0002:00000420+ ___int23_exit
0002:00000424+ ___FPE_handler_exit
Module: c:\watcom\lib386\dos\clib3r.lib(find386)
0001:00001738  _dos_findfirst_
0001:00001755  _dos_findnext_
0001:00001771* _dos_findclose_
Module: c:\watcom\lib386\dos\clib3r.lib(getch)
0001:000017ba  getch_
Module: c:\watcom\lib386\dos\clib3r.lib(strupr)
0001:000017d7  strupr_
0001:000017d7* _strupr_
Module: c:\watcom\lib386\dos\clib3r.lib(fopen)
0001:000017f6+ __open_flags_
0001:00001972+ _fsopen_
0001:0000198d  fopen_
0001:000019ff* freopen_
Module: c:\watcom\lib386\dos\clib3r.lib(fread)
0001:00001a23  fread_
Module: c:\watcom\lib386\dos\clib3r.lib(ftell)
0001:00001bed  ftell_
Module: c:\watcom\lib386\dos\clib3r.lib(fwrite)
0001:00001c1d  fwrite_
Module: c:\watcom\lib386\dos\clib3r.lib(fclose)
0001:00001e04  fclose_
0001:00001e33  __shutdown_stream_
0001:00001e54+ __MkTmpFile_
0001:00001ebd  __doclose_
Module: c:\watcom\lib386\dos\clib3r.lib(memcmp)
0001:00001f46  memcmp_
Module: c:\watcom\lib386\dos\clib3r.lib(memcpy)
0001:00001f64  memcpy_
Module: c:\watcom\lib386\dos\clib3r.lib(fprintf)
0001:00001f89  fprintf_
Module: c:\watcom\lib386\dos\clib3r.lib(int386)
0001:00001faa  int386_
Module: c:\watcom\lib386\dos\clib3r.lib(inp)
0001:00001fc5  inp_
Module: c:\watcom\lib386\dos\clib3r.lib(outp)
0001:00001fcd  outp_
Module: c:\watcom\lib386\dos\clib3r.lib(cstrt386)
0001:00000003* ___begtext
0002:00000000* __nullarea
0002:00000738* __start_TI
0002:00000738* __end_TI
0002:00000428* __GDAptr
0002:0000042c* __D16Infoseg
0002:0000042e* __x386_zero_base_selector
0001:00001fdc  _cstart_
0001:0000226b  __exit_
0001:0000226d  __do_exit_with_msg__
0001:000022a8* __GETDS
Module: c:\watcom\lib386\dos\clib3r.lib(argcv386)
0002:00000430  __argc
0002:00000434  __argv
Module: c:\watcom\lib386\dos\clib3r.lib(xmsg)
0001:000022b4* __exit_with_msg_
0001:000022b9  __fatal_runtime_error_
Module: c:\watcom\lib386\dos\clib3r.lib(crwd386)
0002:00000448  __psp
0002:00000473  __osmajor
0002:00000474  __osminor
0002:0000046a  __Extender
0002:0000046b  __ExtenderSubtype
0002:0000046c  __X32VM
0002:0000044c* __x386_stacklow
0002:00000440  __LpCmdLine
0002:00000444  __LpPgmName
0002:00000438  __dynend
0002:0000043c  __curbrk
0002:0000044c  __STACKLOW
0002:00000450  __STACKTOP
0002:00000454  __ASTACKSIZ
0002:00000458  __ASTACKPTR
0002:0000045c  __cbyte
0002:00000460* __cbyte2
0002:00000464  __child
0002:0000046d  __Envptr
0002:00000471  __Envseg
0002:00000468  __no87
0002:00000475  __FPE_handler
0002:00000475  ___FPE_handler
Module: c:\watcom\lib386\dos\clib3r.lib(iob)
0002:0000047c  ___iob
0002:00000684* ___tmpfnext
0002:00000685  __fmode
0002:0010d310  ___ClosedStreams
Module: c:\watcom\lib386\dos\clib3r.lib(fprtf)
0001:000022e8  __fprtf_
Module: c:\watcom\lib386\dos\clib3r.lib(error386)
0001:0000236e  __doserror_
Module: c:\watcom\lib386\dos\clib3r.lib(tolower)
0001:00002381  tolower_
0001:00002381* _tolower_
Module: c:\watcom\lib386\dos\clib3r.lib(seterrno)
0001:0000238f* __set_EDOM_
0001:00002394  __set_errno_
0001:000023a0* __set_ERANGE_
0001:000023a7* __set_EINVAL_
0001:000023b7  __set_doserrno_
0001:000023c3* __FPE_exception_
Module: c:\watcom\lib386\dos\clib3r.lib(open)
0001:000023ca* open_
0001:000023ee  sopen_
0001:000025b3* __set_binary_
Module: c:\watcom\lib386\dos\clib3r.lib(allocfp)
0001:00002618  __allocfp_
0001:000026c0  __freefp_
0001:000026f9  __purgefp_
Module: c:\watcom\lib386\dos\clib3r.lib(fseek)
0001:00002759  fseek_
Module: c:\watcom\lib386\dos\clib3r.lib(chktty)
0001:00002855  __chktty_
Module: c:\watcom\lib386\dos\clib3r.lib(stinit)
0002:0010d314  ___OpenStreams
Module: c:\watcom\lib386\dos\clib3r.lib(ioalloc)
0001:00002886  __ioalloc_
Module: c:\watcom\lib386\dos\clib3r.lib(qread)
0001:000028fd  __qread_
Module: c:\watcom\lib386\dos\clib3r.lib(fgetc)
0001:0000291c* fgetc_
0001:000029a5+ __filbuf_
0001:000029d4  __fill_buffer_
Module: c:\watcom\lib386\dos\clib3r.lib(tell)
0001:00002a7f  tell_
Module: c:\watcom\lib386\dos\clib3r.lib(write)
0001:00002a90  write_
Module: c:\watcom\lib386\dos\clib3r.lib(flush)
0001:00002c61  __flush_
Module: c:\watcom\lib386\dos\clib3r.lib(fputc)
0001:00002d20  fputc_
Module: c:\watcom\lib386\dos\clib3r.lib(gtpid)
0001:00002dc4  getpid_
Module: c:\watcom\lib386\dos\clib3r.lib(lseek)
0001:00002dca  lseek_
0001:00002dca* _lseek_
Module: c:\watcom\lib386\dos\clib3r.lib(_clse)
0001:00002e0b  __close_
Module: c:\watcom\lib386\dos\clib3r.lib(nfree)
0001:00002e3d  _nfree_
0001:00002e3d  free_
Module: c:\watcom\lib386\dos\clib3r.lib(remove)
0001:00002e9b  remove_
Module: c:\watcom\lib386\dos\clib3r.lib(segread)
0001:00002ea0  segread_
Module: c:\watcom\lib386\dos\clib3r.lib(intx386)
0001:00002ec8  int386x_
Module: c:\watcom\lib386\dos\clib3r.lib(cmain386)
0001:00002ee1  __CMain
Module: c:\watcom\lib386\dos\clib3r.lib(inirt386)
0001:00002f30  __InitRtns
0001:00002f7b  __FiniRtns
Module: c:\watcom\lib386\dos\clib3r.lib(seg386)
0000:00001234  __DOSseg__
Module: c:\watcom\lib386\dos\clib3r.lib(initargv)
0001:00002fca  __Init_Argv_
Module: c:\watcom\lib386\dos\clib3r.lib(enterdb)
0001:00003170  __EnterWVIDEO_
0002:00000690+ ___WD_Present
Module: c:\watcom\lib386\dos\clib3r.lib(prtf)
0001:00003196  __prtf_
Module: c:\watcom\lib386\dos\clib3r.lib(dosret)
0001:00003b90* _dosret0_
0001:00003b97* _dosretax_
0001:00003b9c  __set_errno_dos_
Module: c:\watcom\lib386\dos\clib3r.lib(errno)
0001:00003c02  __get_errno_ptr_
0001:00003c08  __get_doserrno_ptr_
0002:0010d318+ __doserrno
0002:0010d31c+ _errno
Module: c:\watcom\lib386\dos\clib3r.lib(isatt)
0001:00003c0e  isatty_
Module: c:\watcom\lib386\dos\clib3r.lib(umaskval)
0002:000006a8  ___umaskval
Module: c:\watcom\lib386\dos\clib3r.lib(iomode)
0001:00003c2c  __IOMode_
0001:00003c81  __SetIOMode_
0002:000006ac+ ___NFiles
0002:000006b0+ ___init_mode
0002:00000700+ __iomode
Module: c:\watcom\lib386\dos\clib3r.lib(nmalloc)
0001:00003c96  _nmalloc_
0001:00003c96  malloc_
0002:00000704  ___nheapbeg
0002:00000708  ___MiniHeapRover
0002:0000070c  ___LargestSizeB4MiniHeapRover
Module: c:\watcom\lib386\dos\clib3r.lib(set386)
0001:00003d80  memset_
Module: c:\watcom\lib386\dos\clib3r.lib(initfile)
0001:00003d98  __InitFiles_
Module: c:\watcom\lib386\dos\clib3r.lib(ioexit)
0001:00003e10  __full_io_exit_
0001:00003e1c* fcloseall_
Module: c:\watcom\lib386\dos\clib3r.lib(flushall)
0001:00003e73* flushall_
0001:00003e78  __flushall_
Module: c:\watcom\lib386\dos\clib3r.lib(gtche)
0001:00003ea7  getche_
Module: c:\watcom\lib386\dos\clib3r.lib(stack386)
0001:00003ec4  stackavail_
Module: c:\watcom\lib386\dos\clib3r.lib(qwrit)
0001:00003ecd  __qwrite_
Module: c:\watcom\lib386\dos\clib3r.lib(memalloc)
0001:00003f4a  __MemAllocator
0001:00003ff2  __MemFree
Module: c:\watcom\lib386\dos\clib3r.lib(heapmod)
0002:0010d320* ___fheap_clean
0002:0010d321  ___nheap_clean
Module: c:\watcom\lib386\dos\clib3r.lib(unlnk)
0001:000040fd  unlink_
Module: c:\watcom\lib386\dos\clib3r.lib(intxa386)
0001:0000411c  __int386x_
0001:00004179* _DoINTR_
Module: c:\watcom\lib386\dos\clib3r.lib(cinit)
0001:000044fa  __CommonInit_
Module: c:\watcom\lib386\dos\clib3r.lib(___argc)
0002:0010d324  ____Argc
0002:0010d328  ____Argv
Module: c:\watcom\lib386\dos\clib3r.lib(itoa)
0001:0000452a+ utoa_
0001:00004574  itoa_
0001:00004574* _itoa_
Module: c:\watcom\lib386\dos\clib3r.lib(noefgfmt)
0002:00000710  ___EFG_printf
0002:00000714* ___EFG_scanf
Module: c:\watcom\lib386\dos\clib3r.lib(ltoa)
0001:000045c6  ultoa_
0001:0000460f  ltoa_
0001:0000460f* _ltoa_
Module: c:\watcom\lib386\dos\clib3r.lib(toupper)
0001:0000462a  toupper_
0001:0000462a* _toupper_
Module: c:\watcom\lib386\dos\clib3r.lib(grownear)
0001:00004677+ __FreeDPMIBlocks_
0001:000046d5* __ReAllocDPMIBlock_
0001:0000484c+ __LastFree_
0001:00004a1c  __ExpandDGROUP_
Module: c:\watcom\lib386\dos\clib3r.lib(nmemneed)
0001:00004bd7  __nmemneed_
Module: c:\watcom\lib386\dos\clib3r.lib(__stos)
0001:00004be0  __STOSB
0001:00004c17* __STOSD
Module: c:\watcom\lib386\dos\clib3r.lib(amblksiz)
0002:00000718  __amblksiz
Module: c:\watcom\lib386\dos\clib3r.lib(minreal)
0002:0010d32c  ___minreal
Module: c:\watcom\lib386\dos\clib3r.lib(heapen)
0001:00004c83* _heapenable_
0002:0000071c  ___heap_enabled
Module: c:\watcom\lib386\dos\clib3r.lib(sbrk386)
0001:00004c93* sbrk_
0001:00004d52  __brk_


                        +----------------------+
                        |   Imported Symbols   |
                        +----------------------+

Symbol                              Module
======                              ======



                        +--------------------+
                        |   Libraries Used   |
                        +--------------------+

c:\watcom\lib386\dos\clib3r.lib


                        +-----------------------+
                        |   Linker Statistics   |
                        +-----------------------+

Stack size:  00010000 (65536.)
Memory size:  00122144 (1188164.)
Entry point address: 0001:00001fdc
 DATA           DGROUP         0002:00000732   00000006
YIE                    DATA           DGROUP         0002:00000738   00000000
TIB                    DATA           DGROUP         0002:00000738   00000000
TI                     DATA           DGROUP         0002:00000738   00000000
TIE                    DATA           DGROUP         0002:00

0x3C251:

WATCOM C Run-Time system code is provided on an "as is" basis and is (c) Copyright by WATCOM International Corp. 1988-1993. All rights reserved.
*** NULL assignment detected
Not enough memory
(Source: Original TCRF research)