#include <stdio.h>
#include <string.h>
#include "sio.h"

void sio_init(SIO *sio)
{
   memset(sio->wr, 0, sizeof(sio->wr));
   memset(sio->rr, 0, sizeof(sio->rr));
   sio->rx = 0;
   sio->tx = 0;
   sio->in_int = false;
}

bool sio_has_irq(SIO *sio)
{
   bool res = sio->in_int;
   sio->in_int = false;
   return res;
}

bool sio_hasrx(SIO *sio)
{
   return sio->rr[0] & 0x01; // Receive Character Available
}

bool sio_hastx(SIO *sio)
{
   return !(sio->rr[0] & 0x04); // Transmit Buffer Empty
}

uint8_t sio_read(SIO *sio)
{
   sio->rr[0] |= 0x04; // Transmit Buffer Empty high
   return sio->tx;
}

void sio_write(SIO *sio, uint8_t val)
{
   sio->rr[0] |= 0x01; // Receive Character Available high
   sio->rx = val;
   sio->in_int = true;
}

uint8_t sio_actl_rd(SIO *sio)
{
   uint8_t target = sio->wr[0] & 0x3; // PTR
   return sio->rr[target];
}

void sio_actl_wr(SIO *sio, uint8_t val)
{
   uint8_t target = sio->wr[0] & 0x7; // PTR
   sio->wr[target] = val;
   if (target != 0) {
       sio->wr[0] &= ~0x7;
   }
}

uint8_t sio_adata_rd(SIO *sio)
{
   sio->rr[0] &= ~0x01; // Receive Character Available low
   return sio->rx;
}

void sio_adata_wr(SIO *sio, uint8_t val)
{
   sio->tx = val;
   sio->rr[0] &= ~0x04; // Transmit Buffer Empty low
}