/**
 * N: I/O
 */

/* "stripped down" version that harcodes some parameters! Don't
   use this as example code for writing your own fujinet app! */

#include <atari.h>
#include "nio.h"
#include "sio.h"
#include "config.h"
#include "rxtxbuf.h"

#define TIMEOUT 0x1f /* approx 30 seconds */

#define UNIT 1 /* only support one FujiNet connection! */

/* 0 = no translation (used to use 3, CRLF) */
#define TRANS 0

static char get_status(void) {
	if(OS.dcb.dstats != SUCCESS) {
		// something went wrong
		// do we need to return extended status?
		if(OS.dcb.dstats == DERROR) {
			nstatus();
			return OS.dvstat[DVSTAT_EXTENDED_ERROR]; // return extended error.
		}
	}
	return OS.dcb.dstats; // Return SIO error or success
}

static void set_defaults(void) {
	OS.dcb.ddevic   = DFUJI;      // Fuji Device Identifier
	OS.dcb.dunit    = UNIT;       // Unit number integer 1 through 4
	OS.dcb.dtimlo   = TIMEOUT;    // approximately 30 second timeout
}

char nopen(void) {
	set_defaults();
	OS.dcb.dcomnd   = 'O';        // Open
	OS.dcb.dstats   = DWRITE;     // sending to to SIO device
	OS.dcb.dbuf     = config.url;  // eg: N:TCP//
	OS.dcb.dbyt     = 256;        // max size of our device spec
	OS.dcb.daux1    = OUPDATE;    // Read and write
	OS.dcb.daux2    = TRANS;      // CR/LF translation
	siov();

	return get_status();
}

char nclose(void) {
	set_defaults();
	OS.dcb.dcomnd   = 'C';      // Close
	OS.dcb.dstats   = 0x00;
	OS.dcb.dbuf     = 0;
	OS.dcb.dbyt     = 0;
	OS.dcb.daux     = 0;
	siov();

	return get_status();
}

char nstatus(void) {
	set_defaults();
	OS.dcb.dcomnd   = 'S';    // status
	OS.dcb.dstats   = DREAD;
	OS.dcb.dbuf     = OS.dvstat;
	OS.dcb.dbyt     = sizeof(OS.dvstat);
	OS.dcb.daux     = 0;
	siov();

	return OS.dvstat[DVSTAT_EXTENDED_ERROR]; // return extended status
}

char nread_rxbuf(void) {
	extern unsigned int rxbuflen;
	set_defaults();
	OS.dcb.dcomnd   = 'R';    // read
	OS.dcb.dstats   = DREAD;
	OS.dcb.dbuf     = rx_buf;
	OS.dcb.dbyt     = OS.dcb.daux = rxbuflen; // Set the buffer size AND daux with length
	siov();

	return get_status();
}

char nwrite_txbuf(void) {
	extern unsigned int txbuflen;
	set_defaults();
	OS.dcb.dcomnd   = 'W';    // write
	OS.dcb.dstats   = DWRITE;
	OS.dcb.dbuf     = tx_buf;
	OS.dcb.dbyt     = OS.dcb.daux = txbuflen;
	siov();

	return get_status();
}

/* https://fujinet.online/wiki/?p=SIO-Command-%24FF-Reset-FujiNet */
char nreset(void) {
	set_defaults();
	OS.dcb.ddevic   = 0x70;
	OS.dcb.dcomnd   = 0xff; /* reset */
	OS.dcb.dstats   = DWRITE;
	OS.dcb.dbuf     = 0;
	OS.dcb.dbyt     = 0;
	OS.dcb.daux     = 0;
	siov();

	return OS.dvstat[DVSTAT_EXTENDED_ERROR]; // return extended status
}

