module  serio;
{
	A set of procedures and functions for the Apple II version of CP/M
    which do I/O via 'COMM' cards (or their equivalent) put into various
    slots.
}

const	slot = 2;	{ slot card is in }
	base = $E08E;	{ base address for ACIA's }

procedure poke(ch:byte;add:integer);
{
	Puts 'ch' into the absolute address, 'add'
}
	
begin
    inline ("LDA / ch /
	    "LHLD / add /
	    $77  );		{ MOV M,A  }
end;

function peek (add:integer):	byte;
{
	Returns the value of the byte located at the absolute address, 'add'
}

var value:integer;

begin
    inline ( "LHLD/ add /
	     $7E  /		{ MOV A,M  }
	     "STA / value );
    peek := value;
end;

procedure initac;
{
	Initializes the ACIA in the slot
}
    
var	status:	integer;
    
begin
    status := base + slot *16;
    inline	("LHLD/ status /
		  $3E / $03 /	{ MVI A,03 }
		  $77 /		{ MOV M,A  }
		  $3E / $11 /	{ MVI A,11 }
		  $77 );	{ MOV M,A  }
end;    (*   initac    *)
    
function serin:	char;
{
	Returns the byte which has just been received.
    NOTE: it will stay forever in this routine if a byte has NOT been received
}

const	rxmask = $01;		{ mask for receive buffer full }

var	status,
	data:	integer;

begin
    status := base + slot*16;
    data := status+1;
    repeat until (peek(status) & rxmask ) <> 0;
    serin := peek( data );
end;

procedure serout(ch: char);
{
	Sends the character, 'ch', out
}
    
const	txmask=$02;		{ mask for transmit buffer empty }
    
var	data,
        status:	integer;
    
	    
begin
    status := base + 16*slot;
    data := status + 1;
    repeat until (peek(status) & txmask ) <> 0;
    poke (ch,data);
end;    (*    serout   *)

modend.
