#include <stdio.h>

#include "atari.h"
#include "cpu.h"
#include "pia.h"
#include "platform.h"
#include "sio.h"
#include "mem.h"

static char *rcsid = "$Id: pia.c,v 1.20 1997/09/30 thor,david Exp $";

UBYTE PACTL;
UBYTE PBCTL;
UBYTE PORTA;
UBYTE PORTB;
UBYTE PORTA_mask = 0xff;
UBYTE PORTB_mask = 0xff;


extern UWORD regPC;

extern int CommandIndex,DataIndex,TransferStatus,ExpectedBytes;


mtype PIA_PACTLR(void)
{
  return PACTL;
}

mtype PIA_PBCTLR(void)
{
  return PBCTL;
}

mtype PIA_PORTAR(void)
{
  return (PORTA & (~PORTA_mask)) | (Atari_PORT(0) & PORTA_mask);
}

mtype PIA_PORTBR(void)
{
  switch (machine)
    {
    case Atari :
      return (Atari_PORT(1) & PORTB_mask);
    case AtariXL :
    case AtariXE : 
      return (PORTB & (~PORTB_mask)) | PORTB_mask;
      /*
      return PORTB = (PORTB & (~PORTB_mask)) | PORTB_mask;
      */
      break;
    default :
      printf ("Fatal Error in pia.c: PIA_GetByte(): Unknown machine\n");
      Atari800_Exit (FALSE, 1);
      break;
    }
  return 0xff;
}  


int PIA_PORTAW(mtype byte)
{
  if (!(PACTL & 0x04)) {
    PORTA_mask = ~byte;
  }
  else PORTA=byte;

  return FALSE;
}

int PIA_PORTBW(mtype byte)
{
  if (!(PBCTL & 0x04)) {
    PORTB_mask = ~byte;
    byte=PORTB;
    return FALSE;
  }

  switch (machine) {
  case Atari :
    PORTB = byte;
    break;

  case AtariXE :
    byte|=PORTB_mask;   
    /* A special hack....  */
    if (byte==0)  break;
 
    SelectXEBank(byte);
    /* l"auft hier hinein */
  case AtariXL :
    byte|=PORTB_mask;    
    /* A special hack....  */
    if (byte==0)  break; 
    

    /*
     * Enable/Disable OS ROM 0xc000-0xcfff and 0xd800-0xffff
     *
     */
       if (byte & 0x01) 
         EnableOs();
	 else DisableOs();

    /*
     * Enable/Disable XL Basic 
     */
       if (byte & 0x02)
	 DisableBasic();
       else EnableBasic();

    /*
     * Enable/Disable Selftest
     */
      if (byte & 0x80)
	DisableSelftest();
      else EnableSelftest();

    PORTB = byte;

#ifdef DEBUG
    printf ("PortB PutByte = %08x, Mask=%08x PBCTL=%08x \n",byte,PORTB_mask,PBCTL);
#endif

    break;
  default :
    printf ("Fatal Error in pia.c: PIA_PutByte(): Unknown machine\n");
    Atari800_Exit (FALSE, 1);
    break;
  }

  return FALSE;
}

int PIA_PACTLW(mtype byte)
{
  PACTL = byte;
  /*
  if (PACTL & 0x04)
    PIA_PORTAW(PORTA); 
  */

  return FALSE;
}

int PIA_PBCTLW(mtype byte)
{
  /* This code is part of the serial I/O emulation */
  if ((PBCTL ^ byte) & 0x08) { /* The command line status has changed */
    SwitchCommandFrame((byte & 0x08)?(0):(1));
  }
  PBCTL = byte;
  /*
  if (PBCTL & 0x04)
    PIA_PORTBW(PORTB);
  */
 
  return FALSE;
}


void Init_PIA(int *argc, char *argv[],int base)
{
  PORTA = 0xff;
  PORTB = 0xff;
  PORTA_mask = 0xff;
  PORTB_mask = 0xff;
  SetHW(base+_PORTA,0xff03,&PIA_PORTAR,&PIA_PORTAW);
  SetHW(base+_PORTB,0xff03,&PIA_PORTBR,&PIA_PORTBW);
  SetHW(base+_PACTL,0xff03,&PIA_PACTLR,&PIA_PACTLW);
  SetHW(base+_PBCTL,0xff03,&PIA_PBCTLR,&PIA_PBCTLW);
  DisableBasic();
  EnableOs();
  DisableSelftest();
  if (machine==AtariXE)
    SelectXEBank(0xff);
}
