/*

chargen.c - Character generator service

*/

/*...sincludes:0:*/
#include <stdio.h>
#include "types.h"
#include "fiber.h"
#include "cpmio.h"
#include "net.h"
#include "chargen.h"

/*...vtypes\46\h:0:*/
/*...vfiber\46\h:0:*/
/*...vcpmio\46\h:0:*/
/*...vnet\46\h:0:*/
/*...vchargen\46\h:0:*/
/*...e*/

/*...schargen_next_char:0:*/
static byte chargen_next_char(byte b)
	{
	return b == '}' ? ' ' : b+1;
	}
/*...e*/

static void chargen_listen(CHARGEN *chargen);
static void chargen_send(CHARGEN *chargen);

/*...schargen_disconnect:0:*/
static void chargen_disconnect(CHARGEN *chargen)
	{
	SOCKET *socket = chargen->socket_alloc.socket;
	bdos_printf("chargen_disconnect:\r\n$");
	net_disconnect(socket, (NF)chargen_listen, chargen);
	}		
/*...e*/
/*...schargen_sent:0:*/
static void chargen_sent(CHARGEN *chargen)
	{
	SOCKET *socket = chargen->socket_alloc.socket;
	if ( socket->state == SS_ERROR )
		chargen_disconnect(chargen);
	else
		chargen_send(chargen);
	}		
/*...e*/
/*...schargen_send:0:*/
static void chargen_send(CHARGEN *chargen)
	{
	SOCKET *socket = chargen->socket_alloc.socket;
	byte b = chargen_next_char(chargen->start);
	byte i;
	chargen->start = b;
	for ( i = 0; i < CHARGEN_CHARS; i++ )
		{
		chargen->buf[i] = b;
		b = chargen_next_char(b);
		}
	net_send(socket, chargen->buf, CHARGEN_BUF_SIZE, (NF)chargen_sent, chargen);
	}
/*...e*/
/*...schargen_connected:0:*/
static void chargen_connected(CHARGEN *chargen)
	{
	SOCKET *socket = chargen->socket_alloc.socket;
	bdos_printf("chargen_connected:\r\n$");
	chargen->buf[72] = '\r';
	chargen->buf[73] = '\n';
	chargen->start = ' ';
	chargen_send(chargen);
	}
/*...e*/
/*...schargen_listen:0:*/
static void chargen_listen(CHARGEN *chargen)
	{
	SOCKET *socket = chargen->socket_alloc.socket;
	bdos_printf("chargen_listen:\r\n$");
	net_listen(socket, CHARGEN_PORT, (NF)chargen_connected, chargen);
	}
/*...e*/
/*...schargen_start:0:*/
void chargen_start(CHARGEN *chargen)
	{
	net_alloc(&(chargen->socket_alloc), (NF)chargen_listen, chargen);
	}
/*...e*/
/*...schargen_init:0:*/
void chargen_init(void)
	{
	}
/*...e*/
