libi86
This is a code library which attempts to reimplement non-standard C library facilities (e.g. <conio.h>) commonly used in classical MS-DOS programs.
For now, the library is meant to be used with a GCC toolchain for 16-bit x86; but it may be ported to other compilers in the future.
The current aim is to be compatible enough with the Open Watcom runtime — as described in the Open Watcom C Library Reference — to be useful for building existing MS-DOS code.
Defining the macro _BORLANDC_SOURCE will also enable some degree of compatibility with the Borland Turbo C++ compiler's C library, which is described in the Borland C++ 2.0 Library Reference.
Synopsis
Use
ia16-elf-gcc[...gcc-options...]-li86[...]- On MS-DOS:
i16gcc[...gcc-options...]-li86[...]
Installing from pre-compiled Ubuntu Linux packages, for cross development
Grab the gcc-ia16-elf and libi86-ia16-elf packages from my build-ia16 PPA.
Building from sources, installing, and testing, on Linux
Detailed instructions for doing so are available.
License
libi86 as a whole is now distributed under the 3-clause BSD License.
(A few files are distributed under other licenses, but in a way that is ultimately compatible with the BSD License.)
Implemented facilities
Legend
| Meaning | |
|---|---|
| W | Behaves like the corresponding function in Open Watcom. |
| W+ | Behaves like the corresponding function in Open Watcom, but with some extended behaviours. |
| B | From Borland Turbo C++ — enable with _BORLANDC_SOURCE. |
| W/B | By default, behaves as in Open Watcom; if _BORLANDC_SOURCE is defined, behaves as in Borland C++. |
| IW | From internal interfaces in Open Watcom's library code. |
| X | libi86-specific extension; not in Open Watcom or Borland C++. |
| XB | libi86-specific extension. Behaves slightly differently if _BORLANDC_SOURCE is defined. |
Functions
| Compat. | Function | Notes |
|---|---|---|
▗▚▚▚▚ <bios.h> ▞▞▞▞▖ |
||
| W+ | _bios_disk (service, *diskinfo); |
As an extension, also accepts service = _DISK_DRIVEPARAMS, which returns drive parameters in *diskinfo. |
| W | _bios_equiplist (); |
|
| B | biosequip (); |
|
| W | _bios_memsize (); |
|
| B | biosmemory (); |
|
| W | _bios_keybrd (service); |
|
| B | bioskey (service); |
|
| W | _bios_timeofday (service, *timeval); |
|
| X | _bios_joystick (service, *joyinfo); |
Reads joystick status via int 0x15 function 0x84. |
▗▚▚▚▚ <conio.h> ▞▞▞▞▖ |
If _BORLANDC_SOURCE is defined, <conio.h> switches to an alternate implementation of the console output routines which is based on <graph.h> facilities. |
|
| W/B | *cgets (*buf); |
|
| W/B | cprintf (*fmt, ...); |
|
| W/B | cputs (*buf); |
|
| W/B | cscanf (*fmt, ...); |
|
| W | getch (); |
|
| W | _getch (); |
|
| W/B | getche (); |
|
| W | _getche (); |
|
| W | kbhit (); |
|
| W | _kbhit (); |
|
| W | ungetch (ch); |
|
| W | _ungetch (ch); |
|
| W/B | putch (ch); |
|
| W/B | vcprintf (*fmt, ap); |
|
| W/B | vcscanf (*fmt, ap); |
|
| B | clreol (); |
|
| B | clrscr (); |
|
| B | delline (); |
|
| B | *getpass (*prompt); |
|
| B | gettextinfo (*text-info); |
If the active video mode is a SuperVGA mode, text-info->currmode may be invalid. |
| B | gotoxy (x, y); |
|
| B | highvideo (); |
|
| B | insline (); |
|
| B | lowvideo (); |
|
| B | normvideo (); |
|
| B | textattr (new-attr); |
|
| B | textbackground (new-color); |
|
| B | textcolor (new-color); |
|
| B | textmode (mode); |
Does not support mode = LASTMODE yet. |
| B | wherex (); |
|
| B | wherey (); |
|
| B | window (left, top, right, bottom); |
|
| W | inp (port); |
|
| W | _inp (port); |
|
| B | inportb (port); |
|
| W | inpw (port); |
|
| W | _inpw (port); |
|
| B | inportw (port); |
|
| W | outp (port, value); |
|
| W | _outp (port, value); |
|
| B | outportb (port, value); |
|
| W | outpw (port, value); |
|
| W | _outpw (port, value); |
|
| B | outportw (port, value); |
|
▗▚▚▚▚ <dos.h> ▞▞▞▞▖ |
<dos.h> also includes <i86.h>, described below. If _BORLANDC_SOURCE is defined, the union REGS type gets an additional .x.flags field, and <dos.h> switches accordingly to a different version of the intdos and intdosx routines. |
|
| W | bdos (dos-func, dx, al); |
|
| B | bdosptr (dos-func, *dx, al); |
|
| W/B | intdos (*in-regs, *out-regs); |
|
| W/B | intdosx (*in-regs, *out-regs, *seg-regs); |
|
| W+ | _dos_allocmem (size, *segment); |
Also works under DPMI; yields a starting protected-mode selector. |
| W | _dos_close (handle); |
|
| W | _dos_commit (handle); |
|
| W | _dos_creat (*path, attr, *handle); |
|
| W | _dos_creatnew (*path, attr, *handle); |
|
| W | _dos_findfirst (*path, attributes, *buffer); |
|
| W | _dos_findnext (*buffer); |
|
| W | _dos_findclose (*buffer); |
|
| W+ | _dos_freemem (segment); |
Also works under DPMI; accepts a starting protected-mode selector. |
| W | _dos_getdrive (*drive); |
|
| W | _dos_getfileattr (*path, *attributes); |
|
| W | *_dos_getvect (intr-no); |
Some versions of gcc-ia16 may not understand the interrupt function attribute. In that case, this function will return a far data pointer. |
| W | _dos_open (*path, mode, *handle); |
|
| W | _dos_read (handle, *buf, count, *bytes); |
|
| W | _dos_setdrive (drive, *total); |
|
| W | _dos_setfileattr (*path, attributes); |
|
| W | _dos_setvect (intr-no, *handler); |
Some versions of gcc-ia16 may not understand the interrupt function attribute. In that case, this function will not be supported. |
| W | _dos_write (handle, *buf, count, *bytes); |
|
| W | _getdrive (); |
|
| B | peek (segment, offset); |
|
| B | peekb (segment, offset); |
|
| B | poke (segment, offset, word-value); |
|
| B | pokeb (segment, offset, byte-value); |
|
▗▚▚▚▚ <dpmi.h> ▞▞▞▞▖ |
Except for __DPMI_hosted (), functions in <dpmi.h> should only be called when the caller knows it is running in DPMI mode. |
|
| IW | __DPMI_hosted (); |
Returns 1 if running in protected mode under DPMI, -1 otherwise. If the underlying C library has an implementation of this function, libi86 will use that instead. |
| IW | _DPMIAllocateDOSMemoryBlock (paras); |
int 0x31 function 0x0100. Returns a structure giving the real mode segment and protected mode selector for the DOS memory block. On failure, returns { 0, 0 }. |
| IW | _DPMIFreeDOSMemoryBlock (sel); |
int 0x31 function 0x0101. Returns 0 on success, -1 on error. |
| IW | _DPMIGetDescriptor (sel, *desc); |
int 0x31 function 0x000b. Returns 0 on success, -1 on error. |
| IW | _DPMIGetSegmentBaseAddress (sel); |
int 0x31 function 0x0006. Returns sel's base address on success; return value is undefined on error. |
| IW | _DPMISegmentToDescriptor (seg-para); |
int 0x31 function 0x0002. On success, returns a protected-mode selector value for the real-mode segment seg-para:0. On failure, returns a negative value. |
| IW | _DPMISimulateRealModeInterrupt (inter-no, reset, words-to-copy, *call-struct); |
int 0x31 function 0x0300. Returns 0 on success, -1 on error. words-to-copy should probably be 0. |
▗▚▚▚▚ <graph.h> ▞▞▞▞▖ |
Unlike in Open Watcom, where all functions in <graph.h> are far, in libi86 the far-ness of functions follows the chosen memory model. Thus, in a small-memory-model program, _setvideomode is a near function. However, pointers to data are still far. |
|
| W | _clearscreen (area); |
|
| W | _gettextposition (); |
|
| X | _getvideomode (); |
|
| W | _outmem (*text, length); |
|
| W | _outtext (*text); |
|
| W | _scrolltextwindow (rows); |
|
| W | _settextcolor (pix-val); |
|
| W | _settextposition (row, col); |
|
| W | _settextwindow (row1, col1, row2, col2); |
|
| W | _setvideomode (mode); |
In the case of SuperVGA screen modes, only works with VESA interface. |
▗▚▚▚▚ <i86.h> ▞▞▞▞▖ |
If _BORLANDC_SOURCE is defined, the union REGS type gets an additional .x.flags field, and <i86.h> switches accordingly to a different version of the int86, int86x, _int86f, and _int86xf routines. |
|
| W | delay (ms); |
|
| W | nosound (); |
|
| W | sound (freq); |
|
| W | segread (*seg-regs); |
|
| W | _disable (); |
|
| W | _enable (); |
|
| W/B | int86 (inter-no, *in-regs, *out-regs); |
|
| W/B | int86x (inter-no, *in-regs, *out-regs, *seg-regs); |
|
| W | intr (inter-no, *regs); |
Clears SZAPC flags to 0 before issuing interrupt. (This follows a documentation change in Open Watcom versions after Oct 2018.) |
| XB | _int86f (inter-no, *in-regs, *out-regs); |
Loads carry flag before issuing interrupt. |
| XB | _int86xf (inter-no, *in-regs, *out-regs, *seg-regs); |
Loads carry flag before issuing interrupt. |
| W | intrf (inter-no, *regs); |
Loads SZAPC flags before issuing interrupt. |
| X | _intrf (inter-no, *regs); |
Loads SZAPC flags before issuing interrupt. |
| W | FP_OFF (*ptr); |
Macro. |
| W | _FP_OFF (*ptr); |
Macro. |
| W | FP_SEG (*ptr); |
Macro. |
| W | _FP_SEG (*ptr); |
Macro. |
| W | *MK_FP (seg, off); |
Macro. |
| W | *_MK_FP (seg, off); |
Macro. |
| X | *_CV_FP (*ptr); |
Convert a default-sized pointer to a far pointer. This is reserved for future use with compilers that lack built-in far pointer support. |
| X | *_FP_EQ (*ptr1, ptr2); |
Test whether two far pointers are exactly equal. This is reserved for future use with compilers that lack built-in far pointer support. |
▗▚▚▚▚ <libi86/stdlib.h> ▞▞▞▞▖ |
||
| W | *lltoa (value, *buffer, radix); |
|
| W | *_lltoa (value, *buffer, radix); |
|
| W | *ltoa (value, *buffer, radix); |
|
| W | *_ltoa (value, *buffer, radix); |
|
| W+ | _makepath (*path, *drive, *dir, *fname, *ext); |
As extensions, this function (1) checks for buffer overflow, and (2) gives a return value. Upon an error, the return value is non-zero, errno is set, and path[] holds either an empty string or a truncated path. Network drive[] values starting with two backslashes (\\) are not supported. |
| W | _splitpath (*path, *drive, *dir, *fname, *ext); |
Long filenames, and network paths starting with two backslashes (\\), are not supported. |
| W | *ulltoa (value, *buffer, radix); |
|
| W | *_ulltoa (value, *buffer, radix); |
|
| W | *ultoa (value, *buffer, radix); |
|
| W | *_ultoa (value, *buffer, radix); |
|
▗▚▚▚▚ <libi86/string.h> ▞▞▞▞▖ |
||
| W | *_fmemcpy (*dest, *src, n); |
|
| W | *_fmemmove (*dest, *src, n); |
|
| W | _fstrlen (*s); |
Variables
| Compat. | Variable | Notes |
|---|---|---|
▗▚▚▚▚ <libi86/stdlib.h> ▞▞▞▞▖ |
||
| W | _osmajor |
|
| W | _osminor |
|
| W | _psp |