#include "system.h"
#include "FD.h"


extern const
{
	// K1-bus select byte for SIO1:
	uint8 mSIO_SELECT;
	uint8 k1_wr_data;
	uint8 k1_rd_data;

	// special characters:
	char xon  	= 17;
	char xoff 	= 19;

	// example baudrate:
	uint8 baud_9600 = 9600/2400;
	uint8 baud_57k6 = 57600/2400;
};


type SerialDevice = FD +
{
	bool		hw_handshake;
	uint8		sw_handshake;	// bit.0: enabled
								// bit.1: xoff received
								// bit.2: xoff sent
	uint8		clk_handshake;	// bit.0: emit TX clock
								// bit.1: emit RX clock
								// bit.2: invert clocks
								// bit.3: may be set

	uint8		device;			// select mask
	uint8		channel;		// 0 = channel A; 1 = channel B
	uint8		baudrate;		// baudrate / 2400
	uint8 		sreg;			// SRA/SRB + k1_rd_data
	uint8		rxreg;			// RXA/RXB + k1_rd_data
	uint8		txreg;			// TXA/TXB + k1_wr_data

	uint8		ibuwi;			// input  buffer write index
	uint8		iburi;			// input  buffer read index
	uint8		obuwi;			// output buffer write index
	uint8		oburi;			// output buffer read index

	char[]		ibu;			// input  buffer
	char[]	 	obu;			// output buffer
};


extern SerialDevice new(uint8 ch, str¢ name);	// ONLY for sio1!	✓
extern SerialDevice sio1A;
extern SerialDevice sio1B;
extern uint8 imr_value; 	 	// current value of interrupt mask register IMR
extern uint8 opcr_value;		// current value of output port control register OPCR


scope SerialDevice
{
extern const uint8

	// buffer size:
	obusz		= 64,			// SIO output buffer size; must be 64 (2^n)
	ibusz		= 64,			// SIO input buffer size;  must be 64 (2^n)
	obumask		= obusz-1,
	ibumask		= ibusz-1,

	// bits in SioData.sw_handshake:
	mSWHSK_ENABLED 	= 1,
	mXOFF_RECEIVED 	= 2,
	mXOFF_SENT     	= 4,
	bSWHSK_ENABLED 	= 0,
	bXOFF_RECEIVED 	= 1,
	bXOFF_SENT		= 2;


extern
{
	void reset( SerialDevice¢, bool tx, bool rx );		//	✓
	void set_baudrate( SerialDevice¢, uint8 baudrate );	//	✓
	void set_sw_handshake( SerialDevice¢, bool f );		//	✓
	void set_hw_handshake( SerialDevice¢, bool f );		//	✓
	void set_clock_handshake( SerialDevice¢, uint8 f );	//	✓

	//void init	(SerialDevice¢, ...);  		// NIMP (SIOs are created during boot)
	//void kill	(SerialDevice¢);			// NIMP (SIOs are never deleted)
	SerialDevice kill(SerialDevice) = FD FD.kill(FD);

	// note: SIO functions never set or test data member FD.error

	void setctl( SerialDevice¢, uint8 fu, uint n );		//	✓
	uint getctl( SerialDevice¢, uint8 fu );				//	✓

	uint avail_in(SerialDevice¢);						//	✓
	uint avail_out(SerialDevice¢);						//	✓

	char getc( SerialDevice¢ );							//	✓
	void putc( SerialDevice¢, char c );					//	✓

	void puts ( SerialDevice¢, str¢ );					//	✓
	void puts ( SerialDevice¢, str );					//	✓
	//str gets( SerialDevice¢, uint );					//  FD.gets(FD¢,uint)

	bool read ( SerialDevice¢, uint8[]¢ bu, uint a, uint e );	//  ✓
	bool write( SerialDevice¢, uint8[]¢ bu, uint a, uint e );	//  ✓

	bool read (SerialDevice¢, uint8[…]) = bool read (SerialDevice¢, uint8[]¢, uint, uint);
	bool write(SerialDevice¢, uint8[…]) = bool write(SerialDevice¢, uint8[]¢, uint, uint);
}
}// scope SerialDevice













