{$INCLUDE:'IOSTUFF.INC'}
IMPLEMENTATION OF IOSTUFF;
PROCEDURE INTRPT(NUMBER:BYTE; VAR AX,BX,CX,DX: WORD); EXTERN;

VAR	AXR,BXR,CXR,DXR: word;
	Mode: Modes;
	line: Lines;
	column: Columns;

PROCEDURE GetMode;   {Read the CRT mode status}

BEGIN
	AXR:=Byword(15,0);
	INTRPT(#10,AXR,BXR,CXR,DXR);
	Mode:=ord(lobyte(AXR));
END;

PROCEDURE SetMode;  {Set CRT mode status:
		     0 = 40x25 B & W	  1 = 40x25 Color
		     2 = 80x25 B & W	  3 = 80x25 Color
		     4 = 320x200 Color	  5 = 320x200 B & W
		     6 = 640x200 B & W	  7 = Monochrome    }
BEGIN
	AXR:=Byword(0,Mode);
	INTRPT(#10,AXR,BXR,CXR,DXR);
END;

PROCEDURE CursorSize;	   {Set cursor size.  Lines are 0-13 in Monochrome}
			   {mode and 0-7 in Color mode. 		  }
VAR	maxlines: integer;

BEGIN
	GetMode(Mode);
	if (mode=7) then
	  maxlines:=13
	else
	  maxlines:=7;
	if top <= maxlines then
	begin
	  bottom:=maxlines-bottom;
	  top:=maxlines-top;
	  AXR:=byword(1,0);
	  CXR:=byword(top,bottom);
	  INTRPT(#10,AXR,BXR,CXR,DXR);
	end
END;

PROCEDURE CursorOff;	    {Turn cursor off completely}
			    {by setting bit 6 in CH.   }
BEGIN
	AXR := byword(1,0);
	CXR := byword(32,0);
	INTRPT(#10,AXR,BXR,CXR,DXR);
END;

PROCEDURE PutCursor;	{Place cursor on the screen at Line, Column.}

BEGIN
	AXR:=BYWORD(2,0);
	BXR:=BYWORD(0,0);
	DXR:=BYWORD(Line-1,Column-1);
	INTRPT(#10,AXR,BXR,CXR,DXR);
END;

PROCEDURE FindCursor;	     {Find Line, Column of current cursor position.}

BEGIN
	AXR:=ByWord(3,0);
	BXR:=Byword(0,0);
	INTRPT(#10,AXR,BXR,CXR,DXR);
	Line:=ord(HiByte(DXR))+1;
	Column:=ord(LoByte(DXR))+1;
END;

PROCEDURE ClearScreen;	      {Clear the whole screen to blanks.}

BEGIN
	AXR:=BYWORD(6,0);
	BXR:=BYWORD(7,0);
	CXR:=BYWORD(0,0);
	DXR:=BYWORD(24,79);
	INTRPT(#10,AXR,BXR,CXR,DXR);
END;

PROCEDURE ClearLine;	    {Clear out one line to blanks.  Given the }
			    {line number, cursor position not changed.}
const  blank = '                                                                                 ';
var  xline: lines;
     xcol : columns;

BEGIN
	Findcursor(xLine,xCol);
	PutCursor(Line,1);
	write(blank);
	PutCursor(xLine,xCol);
END;

PROCEDURE ClearEOL;	   {Clear to end of current line.}

VAR   J,I: INTEGER;

BEGIN
	FindCursor(Line,Column);
	J:=Column+1;
	For i:= j to 81 do
	write(' ');
	PutCursor(Line,Column);
END;

PROCEDURE ClearEOP;	   {Clear everything after current line}
			   {with blanks, to bottom of screen.  }
BEGIN
	FindCursor(Line,Column);
	AXR:=BYWORD(6,0);
	BXR:=BYWORD(7,0);
	CXR:=BYWORD(Line,0);
	DXR:=BYWORD(24,79);
	INTRPT(#10,AXR,BXR,CXR,DXR);
END;

PROCEDURE ClearField;	     {Clear a designated field with blanks.}
			     {Parameters are Line, Column of upper-}
var  xLine: Lines;	     {left corner of field, Width of field }
     xCol : Columns;	     {and depth of field in lines.	   }
     rCol : Columns;
     bLine: Lines;

BEGIN
	Findcursor(xLine,xCol);
	AXR:=BYWORD(6,0);
	BXR:=BYWORD(07,0);
	CXR:=BYWORD(Line-1,Column-1);
	rCol:=Column+Width-1;
	if rCol>80 then rCol:=80;
	bLine:=Line+Height-1;
	if bLine>25 then bline:=25;
	DXR:=BYWORD(bLine,rCol);
	INTRPT(#10,AXR,BXR,CXR,DXR);
	PutCursor(xLine,xCol);

END;

PROCEDURE ScrollUp;	   {Scroll entire screen up one line}
			   {filling bottom line with blanks.}
BEGIN

	AXR:=BYWORD(6,1);
	BXR:=BYWORD(7,0);
	CXR:=BYWORD(0,0);
	DXR:=BYWORD(24,79);
	INTRPT(#10,AXR,BXR,CXR,DXR);

END;

PROCEDURE ScrollDn;	   {Scroll entire screen down one line}
			   {filling top line with blanks.     }
BEGIN

	AXR:=BYWORD(7,1);
	BXR:=BYWORD(7,0);
	CXR:=BYWORD(0,0);
	DXR:=BYWORD(24,79);
	INTRPT(#10,AXR,BXR,CXR,DXR);

END;

PROCEDURE ScrollField;	      {Scroll a designated window of the}
			      {screen up or down a given number }
var	bLine: Lines;	      {of lines.			}
	rCol : Columns;

BEGIN

	AXR:=BYWORD(Direction+5,Number);
	BXR:=BYWORD(7,0);
	CXR:=BYWORD(Line-1,Column-1);
	rCol:=Column+width-1;
	bLine:=Line+height-1;
	DXR:=BYWORD(bLine-1,rCol-1);
	INTRPT(#10,AXR,BXR,CXR,DXR);

END;

PROCEDURE SetAttr;	  {Set the attribute byte for an area on the}
			  {screen.  Parameters are Attribute type,  }
VAR	ch : byte;	  {Blink type, Underline type and length.   }
	attribute,count,AB : integer;

BEGIN
  count:=0;
  case attr of
    Normal: attribute := #07;
    Reverse: attribute := #70;
    HiLite: attribute := #0F;
    NoDisp: attribute := #00;
  end;
  if aul = ULine then
    attribute := #01;
  if ABlink = Blink then
    AB := #80
  else
    ab := #00;
  attribute := attribute or AB;
  for count := 1 to len do
    begin
      putcursor(line,column);
      AXR:=byword(8,0);
      BXR:=byword(0,0);
      intrpt(#10,AXR,BXR,CXR,DXR);
      ch:=lobyte(AXR);
      AXR:=byword(9,ch);
      BXR:=byword(0,attribute);
      CXR:=byword(0,1);
      intrpt(#10,AXR,BXR,CXR,DXR);
      if column = 80 then
	begin
	  line:=line+1;
	  column:=1;
	end
      else
	column:=column+1;
    end;
end;

PROCEDURE WriteLine;	    {Write a string of characters sequentially	}
			    {on the screen.  Can be any length up to	}
BEGIN			    {the end of the screen.  Length not checked.}
	Putcursor(Line,Column);
	AXR := byword(9,0);
	Concat(txt,'$');
	DXR := wrd(adr txt[1]);
	INTRPT(#21,AXR,BXR,CXR,DXR);
END;

PROCEDURE GetStatus;	    {Get the current diskette drive status.}
			    {Returns Drive, Side, Track and Sector }
BEGIN			    {of last read performed by system.	   }
	AXR := byword(1,0);
	INTRPT(#13,AXR,BXR,CXR,DXR);
	Drv := ord(lobyte(DXR));
	Side := ord(hibyte(DXR));
	Trk := ord(hibyte(CXR));
	Sect := ord(lobyte(CXR));
END;


PROCEDURE GetDefault;	     {Returns the default drive of the system}

BEGIN
	AXR := byword(25,0);
	INTRPT(#21,AXR,BXR,CXR,DXR);
	Default := ord(lobyte(AXR));
END;


PROCEDURE ReadSector;	     {Read the sector desired, given Drive,}
			     {Side, Track and Sector and given the }
BEGIN			     {pointer to a buffer in which to store}
	AXR := byword(2,1);  {the requested sector.		   }
	BXR := wrd(BufPtr);
	CXR := byword(trk,sect);
	DXR := byword(side,drv);
	INTRPT(#13,AXR,BXR,CXR,DXR);
END;

PROCEDURE WriteSector;	      {Write the sector desired to disk, given}
			      {Drive, Side, Track and sector and the  }
BEGIN			      {pointer to the buffer containing the   }
	AXR := byword(3,1);   {data to be written to the sector.      }
	BXR := wrd(BufPtr);
	CXR := byword(trk,sect);
	DXR := byword(side,drv);
	INTRPT(#13,AXR,BXR,CXR,DXR);
END;

PROCEDURE GetKey;	 {Get the next keypress from the buffer}

BEGIN
	AXR := byword(0,0);
	INTRPT(#16,AXR,BXR,CXR,DXR);
	Key := lobyte(AXR);
	Scan := hibyte(AXR);
END;

PROCEDURE GetShift;    {Return the current shift status of the keyboard}
	     {Insert active = 80H | Alt-Shift	= 08H | Insert-Shift  = 80H}
	     {Caps lock     = 40H | Ctl-Shift	= 04H | Caps-Shift    = 40H}
	     {Numlock	    = 20H | Left Shift	= 02H | Num-Shift     = 20H}
	     {Scroll Lock   = 10H | Right Shift = 01H | Scroll-Shift  = 10H}
	     {			  | Hold State	= 08H | 		   }
	     {See Technical Ref Manual for further explanations of states  }
BEGIN
   AXR := byword(2,0);
   INTRPT(#16,AXR,BXR,CXR,DXR);
   Shift := lobyte(AXR);
END;

END.

