Binary Specifications
=====================

Binary is a simple, RAW format used to dump directly from/to the video
display, since it is in the same format of the video display itself.

For each character, there are two bytes stored in the file for each
character in the image (even blank ones).  When the first line is
complete, there is NOT a carriage return before the next line, it
just continues to the next line.  This is why you have to specify the
width of binary files when loading them because it is impossible to
know the width from the file itself.

Here is a 'visual' representation of a binary file:

  - each square represents one byte (in HEX)

  0                             10                            20
   -------------------------------------------------------------------
  |48|17|45|17|4C|17|4C|17|4F|17|20|17|57|17|4F|17|52|17|4C|17|44|17| . .
   -------------------------------------------------------------------
  'H'   'E'   'L'   'L'   'O'   ' '   'W'   'O'   'R'   'L'   'D'



So, if you were to make a program that says 'HELLO WORLD' to the screen,
you can use these byte values and write them directly to the video memory.

For Monochrome text modes, (mode 0 or 1) the address of the memory is
at $B000:0000.  This does not apply to newer computers, which use Colour
EGA/VGA mode (mode 3) which has an address of $B800:0000.  How is this
implemented you ask?  well, i'll show some code to explain how it's done.

PASCAL
------

var
  screen : array[1..200,1..80,0..1] of char absolute $B800:$0000;
const
  data : array[0..21] of char = ('H',#23,'E',#23,'L',#23,'L',#23,'O',#23,
                                 ' ',#23,
                                 'W',#23,'O',#23,'R',#23,'L',#23,'D',#23);
begin
  { places it at co-ordinates (10,10) on screen }
  move(data,screen[10,10],sizeof(data));

  { you can also do it this way: }
  move(data,mem[$B800:(10*80+9)*2],sizeof(data));

  end.


Real Mode C/C++
---------------
// this only works with compact, large, and huge memory models

#include <stdlib.h>

char data[] = {'H',0x17,'E',0x17,'L',0x17,'L',0x17,'O',0x17,
               ' ',0x17,
               'W',0x17,'O',0x17,'R',0x17,'L',0x17,'D',0x17};

void main(void) {
  char far *screen = (char far *) 0xB8000000L; //seg:ofs put together in one!

  memcpy(&screen[(9*80+9)*2],data,sizeof(data));

  }


DPMI C/C++
-----------
// this only works if the current base selector is the DOS selector.
// see your compiler manual/online help for documentation.

#include <stdlib.h>

char data[] = {'H',0x17,'E',0x17,'L',0x17,'L',0x17,'O',0x17,
               ' ',0x17,
               'W',0x17,'O',0x17,'R',0x17,'L',0x17,'D',0x17}

void main(void) {
  char far *screen = (char far *) 0x0B8000L; { Linear address }

  memcpy(screen[9*160+9],data,sizeof(data));

  }

===========================================================================
