The Borland C Nonstandard Library

Version 2.0 of Borland Turbo C was released in 1988, around the same time that the ANSI C standard was being finalized. Most of Turbo C’s language features were influenced by the earlier specifications by Brian W. Kernighan and Dennis M. Ritchie (“K&R C”), but early ANSI draft standards no doubt played a part as well. While most of the functions provided by Borland’s standard library ended up matching the final ANSI standard closely, many functions were vendor-specific and never appeared in any published standard. Most of these functions are specific to either the IBM PC hardware, the DOS API, or both. The game uses 21 of these functions throughout its code.

This page collects information and examples on these obsolete and/or nonstandard library functions (and their associated enums and structs) directly from the Borland manuals. Functions with standard behavior, and details that still apply to modern C implementations or POSIX-compliant environments, have been omitted.


enum COLORS

#define BLINK 128
enum COLORS {
    BLACK, BLUE, GREEN, CYAN,
    RED, MAGENTA, BROWN, LIGHTGRAY,
    DARKGRAY, LIGHTBLUE, LIGHTGREEN, LIGHTCYAN,
    LIGHTRED, LIGHTMAGENTA, YELLOW, WHITE
};

Defines the colors available for console text output.

These color values are accepted in text mode to control both the foreground and background colors of text. These values control foreground color; shifting the value 4 bits to the left will control the background color. Generally graphics palette indexes follow the same ordering and naming style. Adding the numeric value of BLINK to any value will cause the text to flash.

Symbolic ConstantValue
BLACK0
BLUE1
GREEN2
CYAN3
RED4
MAGENTA5
BROWN6
LIGHTGRAY7
DARKGRAY8
LIGHTBLUE9
LIGHTGREEN10
LIGHTCYAN11
LIGHTRED12
LIGHTMAGENTA13
YELLOW14
WHITE15
BLINK128

Defined In

conio.h


coreleft()

unsigned long coreleft(void);

Returns a measure of RAM not in use.

It gives a different measurement value, depending on whether the memory model is of the small data group or the large data group.

Prototype In

alloc.h

Syntax

In the tiny, small, and medium models:

unsigned coreleft(void);

In the compact, large, and huge models:

unsigned long coreleft(void);

Return Value

In the large data models, coreleft() returns the amount of unused memory between the heap and the stack.

In the small data memory models, coreleft() returns the amount of unused memory between the stack and the data segment minus 256 bytes.

Notes

This function is unique to DOS.


disable()

void disable(void);

Disables hardware interrupts.

disable() is designed to provide a programmer with flexible hardware interrupt control. Only the NMI interrupt will still be allowed from any external device.

Prototype In

dos.h

Return Value

None.

Notes

This macro is unique to the 8086 family of processors.


enable()

void enable(void);

Enables hardware interrupts, allowing any device interrupts to occur.

enable() is designed to provide a programmer with flexible hardware interrupt control.

Prototype In

dos.h

Return Value

None.

Notes

This macro is unique to the 8086 family of processors.


farmalloc()

void far *farmalloc(unsigned long nbytes);

Allocates a block of memory nbytes bytes long from the far heap.

For allocating from the far heap, note that:

  • All available RAM can be allocated.
  • Blocks larger than 64K can be allocated.
  • Far pointers are used to access the allocated blocks.

In the compact, large, and huge memory models, farmalloc() is similar, though not identical, to malloc(). farmalloc() takes unsigned long parameters, while malloc takes unsigned parameters.

A tiny model program cannot make use of farmalloc() if it is to be converted to a .COM file.

Prototype In

alloc.h

Return Value

farmalloc() returns a pointer to the newly allocated block, or NULL if not enough space exists for the new block.

Notes

farmalloc() is unique to DOS.

Example

/*
Far Memory Management
farcoreleft - gets the amount of core memory left
farmalloc - allocates space on the far heap
farrealloc - adjusts allocated block in far heap
farfree - frees far heap
*/

#include <stdio.h>
#include <alloc.h>

main()
{
    char far *block;
    long size = 65000;

    /* Find out what's out there */
    printf("%lu bytes free\n", farcoreleft());

    /* Get a piece of it */
    block = farmalloc(size);
    if (block == NULL) {
        printf("failed to allocate\n");
        exit(1);
    }
    printf("%lu bytes allocated, ", size);
    printf("%lu bytes free\n", farcoreleft());

    /* Shrink the block */
    size /= 2;
    block = farrealloc(block, size);
    printf("Block now reallocated to %lu bytes, ", size);
    printf("%lu bytes free\n", farcoreleft());

    /* Let it go entirely */
    printf("Free the block\n");
    farfree(block);
    printf ("Block now freed, ");
    printf("%lu bytes free\n", farcoreleft());
}  /* End of main */

Program output:

359616 bytes free
65000 bytes allocated, 294608 bytes free
Block now reallocated to 32500 bytes, 262100 bytes free
Free the block
Block now freed, 359616 bytes free

filelength()

long filelength(int handle);

Returns the length (in bytes) of the file associated with handle.

Prototype In

io.h

Return Value

On success, filelength() returns a long value, the file length in bytes. On error, it returns -1, and errno is set to EBADF (“bad file number”).


fileno()

#define fileno(stream) ((stream)->fd)

Returns the file handle for the given stream.

If stream has more than one handle, fileno() returns the handle assigned to the stream when it was first opened.

Prototype In

stdio.h

Return Value

fileno() returns the integer file handle associated with stream.

Note from the 21st century: The stream argument to this function should be a pointer to a FILE stream. In the definition of the FILE struct, fd is a char. If we’re being pedantic, the return type of fileno() is actually char.


getch()

int getch(void);

Reads a single character directly from the console (keyboard), without echoing to the screen.

getch() uses stdin.

Prototype In

conio.h

Return Value

getch() returns the character read from the keyboard.

Notes

This function is unique to DOS.


getvect()

void interrupt (*getvect(int interruptno))();

Reads the value of the interrupt vector given by interruptno and returns that value as a far pointer to an interrupt function.

Every processor of the 8086 family includes a set of interrupt vectors, numbered 0 to 255. The 4-byte value in each vector is actually an address, which is the location of an interrupt function (“interrupt service routine”). The value of interruptno can be from 0 to 255.

Prototype In

dos.h

Return Value

getvect() returns the current 4-byte value stored in the interrupt vector named by interruptno.

Notes

This function is unique to DOS.

Example

#include <stdio.h>
#include <dos.h>

/* getvect example */

void interrupt (*oldfunc)();
int looping = 1;

/* get_out - this is our new interrupt routine */
void interrupt get_out()
{
    /* restore to original interrupt routine */
    setvect(5, oldfunc);
    looping = 0;
}

/* capture_prtscr - installs a new interrupt for <Shift><PrtSc> */
/* arguments: func -- new interrupt function pointer */
void capture_prtscr(void interrupt (*func)())
{
    /* save the old interrupt */
    oldfunc = getvect(5);
    /* install our interrupt handler */
    setvect(5, func);
}

void main()
{
    puts("Press <Shift><PrtSc> to terminate");
    /* capture the print screen interrupt */
    capture_prtscr(get_out);

    /* do nothing */
    while (looping);

    puts ("Success");
}

getw()

int getw(FILE *stream);

Returns the next integer (machine word) in the named input stream. It assumes no special alignment in the file.

getw() should not be used when the stream is opened in text mode.

Prototype In

stdio.h

Return Value

getw() returns the next integer on the input stream. On end-of-file or error, getw() returns EOF. Because EOF is a legitimate value for getw() to return, feof() or ferror() should be used to detect end-of-file or error.


inportb()

unsigned char inportb(int portid);

Reads a byte from the hardware I/O port specified by portid.

If inportb() is called when dos.h has been included, it will be treated as a macro that expands to inline code.

If you don’t include dos.h, or if you do include dos.h and #undef the macro inportb, you will get the inportb() function.

Prototype In

dos.h

Return Value

inportb() returns the value read.

Notes

inportb() is unique to the 8086 family of processors.


int86()

int int86(int intno, union REGS *inregs, union REGS *outregs);

Executes an 8086 software interrupt specified by the argument intno.

Before executing the software interrupt, it copies register values from union REGS inregs into the registers.

After the software interrupt returns, int86() copies the current register values to union REGS outregs, copies the status of the carry flag to the x.cflag field in outregs, and copies the value of the 8086 flags register to the x.flags field in outregs. If the carry flag is set, it usually indicates that an error has occurred.

Note that inregs can point to the same structure that outregs points to.

Prototype In

dos.h

Return Value

int86() returns the value of AX after completion of the software interrupt. If the carry flag is set (outregs->x.cflag != 0), indicating an error, this function sets _doserrno to the error code.

Notes

This function is unique to the 8086 family of processors.

Example

#include <dos.h>

#define VIDEO 0x10

/* gotoxy - positions cursor at line y, column x */
void gotoxy(int x, int y)
{
    union REGS regs;

    regs.h.ah = 2;  /* set cursor position */
    regs.h.dh = y;
    regs.h.dl = x;
    regs.h.bh = 0;  /* video page 0 */

    int86(VIDEO, &regs, &regs);
}

MK_FP()

#define MK_FP(seg, ofs) \
    ((void far *) (((unsigned long)(seg) << 16) | (unsigned)(ofs)))

Makes a far pointer from its component segment (seg) and offset (ofs) parts.

Prototype In

dos.h

Return Value

MK_FP() returns a far pointer.


movmem()

void movmem(void *src, void *dest, unsigned length);

Copies a block of length bytes from src to dest.

Even if the source and destination blocks overlap, the copy direction is chosen so that the data is always copied correctly.

Prototype In

mem.h

Return Value

None.

Notes

This function operates in essentially the same way as memmove() from string.h, except src and dest are swapped.


outport()

void outport(int portid, int value);

Writes the word given by value to the hardware I/O port specified by portid.

Prototype In

dos.h

Return Value

None.

Notes

This function is unique to the 8086 family of processors.


outportb()

void outportb(int portid, unsigned char value);

Writes the byte given by value to the hardware I/O port specified by portid.

If outportb() is called when dos.h has been included, it will be treated as a macro that expands to inline code.

If you don’t include dos.h, or if you do include dos.h and #undef the macro outportb, you will get the outportb() function.

Prototype In

dos.h

Return Value

None.

Notes

outportb() is unique to the 8086 family of processors.


putw()

int putw(int w, FILE *stream);

Outputs the integer w (machine word) to the given stream.

putw() neither expects nor causes special alignment in the file.

Prototype In

stdio.h

Return Value

On success, putw() returns the integer w. On error, putw() returns EOF.

Since EOF is a legitimate integer, ferror() should be used to detect errors with putw().


random()

#define random(num) (rand() % (num))

Returns a random number between 0 and (num - 1).

random(num) is a macro defined as (rand() % (num)). Both num and the random number returned are integers.

Prototype In

stdlib.h

Return Value

random() returns a number between 0 and (num - 1).

Example

#include <stdlib.h>
#include <time.h>

/* prints a random number (1-20) of random numbers in the range 0-99 */

main()
{
    int n;
    randomize();
    /* selects a random number between 1 and 20 */
    n = random(20) + 1;
    while (n-- > 0)
        printf("%d ", random(100));
    printf ("\n");
}

union REGS

union REGS {
    struct WORDREGS x;
    struct BYTEREGS h;
};

Provides an interface to read and write x86 registers through C functions.

All 16-bit word registers are available in x. The half-word views into AX, BX, CX, and DX are available in h. The definitions of these structs are as follows:

struct WORDREGS {
    unsigned int ax, bx, cx, dx, si, di, cflag, flags;
};

struct BYTEREGS {
    unsigned char al, ah, bl, bh, cl, ch, dl, dh;
};

Defined In

dos.h


setvect()

void setvect(int interruptno, void interrupt (*isr)());

Sets the value of the interrupt vector named by interruptno to a new value, isr, which is a far pointer containing the address of a new interrupt function.

The address of a C routine can only be passed to isr if that routine is declared to be an interrupt routine.

Every processor of the 8086 family includes a set of interrupt vectors, numbered 0 to 255. The 4-byte value in each vector is actually an address, which is the location of an interrupt function (“interrupt service routine”).

Prototype In

dos.h

Return Value

None.

Notes

If you use the prototypes declared in dos.h, you can simply pass the address of an interrupt function to setvect() in any memory model.

This function is unique to the 8086 family of processors.


strupr()

char *strupr(char *s);

Converts lowercase letters (az) in string s to uppercase (AZ). No other characters are changed.

Prototype In

string.h

Return Value

strupr() returns s.


enum text_modes

enum text_modes {LASTMODE=-1, BW40=0, C40, BW80, C80, MONO=7};

Defines the available screen text modes.

The text_modes type constants, their numeric values, and the modes they specify are given in the following table:

Symbolic ConstantValueText Mode
LASTMODE-1Previous text mode.
BW400Black and white, 40 columns.
C401Color, 40 columns.
BW802Black and white, 80 columns.
C803Color, 80 columns.
MONO7Monochrome, 80 columns.

Defined In

conio.h


textmode()

void textmode(int newmode);

Selects a specific screen text mode.

You can give the text mode (the argument newmode) by using a symbolic constant from the enum text_modes type. To use these constants, you must include conio.h.

When textmode() is called, the current window is reset to the entire screen, and the current text attributes are reset to normal, corresponding to a call to normvideo().

Specifying LASTMODE to textmode() causes the most recently selected text mode to be reselected. This feature is really only useful when you want to return to text mode after using a graphics mode.

textmode() should be used only when the screen is in the text mode (presumably to change to a different text mode). This is the only context in which textmode() should be used. When the screen is in graphics mode, you should use restorecrtmode() instead to escape temporarily to text mode.

Prototype In

conio.h

Return Value

None.

Notes

textmode() works with IBM PCs and compatibles only.


ultoa()

char *ultoa(unsigned long value, char *string, int radix);

Converts value to a null-terminated string and stores the result in string.

value is an unsigned long.

radix specifies the base to be used in converting value; it must be between 2 and 36, inclusive. ultoa() performs no overflow-checking, and if value is negative and radix equals 10, it does not set the minus sign.

Prototype In

stdlib.h

Return Value

ultoa() returns string. There is no error return.

Notes

The space allocated for string must be large enough to hold the returned string, including the terminating null character (\0). ultoa() can return up to 33 bytes.