/* -*- C -*-
 *
 * viap.def - Definitions for VIA emulation in the PET.
 *
 * Written by
 *  Andre' Fachat (fachat@physik.tu-chemnitz.de)
 *
 * This file is part of VICE, the Versatile Commodore Emulator.
 * See README for copyright notice.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 *  02111-1307  USA.
 *
 */

#define mycpu maincpu

#define myclk clk

#define myrmwf rmw_flag

#define myvia via

#define MYVIA VIA

#define	via_set_int		maincpu_set_irq
#define	VIA_INT			IK_IRQ

/* #define VIA_TIMER_DEBUG */

INCLUDES()
{
#include "petvia.h"

#include "../c64/sid.h"
#include "crtc.h"
#include "kbd.h"
#include "parallel.h"
#include "petsound.h"

#ifdef HAVE_PRINTER
#include "pruser.h"
#endif
}

#define GLOBALS()

#define	PRE_VIA_FUNCS

STORE_PRA()
{
 	via[addr] = byte;
	byte = via[VIA_PRA] | ~via[VIA_DDRA];
#ifdef HAVE_PRINTER
	userport_printer_write_data(byte);
#endif
}

STORE_PRB()
{
	via[addr] = byte;
	if((addr==VIA_DDRB) && (byte & 0x20)) {
	    fprintf(stderr,"PET: Killer POKE! might kill a real PET!\n");
	}
	byte = via[VIA_PRB] | ~via[VIA_DDRB];
        par_set_nrfd(!(byte & 0x02));
        par_set_atn(!(byte & 0x04));
}

STORE_PCR()
{
        if(byte != via[VIA_PCR]) {
          register BYTE tmp = byte;
          /* first set bit 1 and 5 to the real output values */
          if((tmp & 0x0c) != 0x0c) tmp |= 0x02;
          if((tmp & 0xc0) != 0xc0) tmp |= 0x20;
          crtc_set_char( byte & 2 ); /* switching PET charrom with CA2 */
				     /* switching userport strobe with CB2 */
#ifdef HAVE_PRINTER
          userport_printer_write_strobe( byte & 0x20 );
#endif
	}
}

STORE_ACR()
{
	store_petsnd_onoff(via[VIA_T2LL] ? (((byte & 0x1c)==0x10)?1:0) : 0);
}

STORE_SR()
{
	store_petsnd_sample(byte);
}

STORE_T2L()
{
        store_petsnd_rate(2*byte+4);
	if(!byte) {
	  store_petsnd_onoff(0);
	} else {
	  store_petsnd_onoff(((via[VIA_ACR] & 0x1c)==0x10)?1:0);
	}
}

RESET_VIA()
{
    /* set IEC output lines */
    par_set_atn(0);
    par_set_nrfd(0);

#ifdef HAVE_PRINTER
    userport_printer_write_data(0xff);
    userport_printer_write_strobe(1);
#endif
}

READ_PRA()
{
        {
            BYTE    j = 255;
            /* VIA PA is connected to the userport pins C-L */
	    j &= (joy[1] & 1) ? ~0x80 : 0xff;
	    j &= (joy[1] & 2) ? ~0x40 : 0xff;
	    j &= (joy[1] & 4) ? ~0x20 : 0xff;
	    j &= (joy[1] & 8) ? ~0x10 : 0xff;
	    j &= (joy[1] & 16)? ~0xc0 : 0xff;
	    j &= (joy[2] & 1) ? ~0x08 : 0xff;
	    j &= (joy[2] & 2) ? ~0x04 : 0xff;
	    j &= (joy[2] & 4) ? ~0x02 : 0xff;
	    j &= (joy[2] & 8) ? ~0x01 : 0xff;
	    j &= (joy[2] & 16)? ~0x0c : 0xff;

#if 0
            printf("read port A %d\n", j);
            printf("a: %x b:%x  ca: %x cb: %x joy: %x\n",
                   (int) j, (int) via[VIA_PRB],
                   (int) via[VIA_DDRA], (int) via[VIA_DDRB], joy[2]);
#endif
            return ((j & ~via[VIA_DDRA]) | (via[VIA_PRA] & via[VIA_DDRA]));
        }
}

READ_PRB()
{
        {
            BYTE    j;
            /* read parallel IEC interface line states */
            j = 255 - (par_nrfd ? 64:0) - (par_ndac ? 1:0) - (par_dav ? 128:0);
            /* vertical retrace */
            j -= crtc_offscreen() ? 32:0;
#if 0
                printf("read port B %d\n", j);
                printf("a: %x b:%x  ca: %x cb: %x joy: %x\n",
                       (int) via[VIA_PRA], (int) j,
                       (int) via[VIA_DDRA], (int) via[VIA_DDRB], joy[1]);
#endif
            byte = ((j & ~via[VIA_DDRB]) | (via[VIA_PRB] & via[VIA_DDRB]));
        }
}


POST_VIA_FUNCS()
{
#ifdef HAVE_PRINTER
void userport_printer_set_busy(int b)
{
    via_signal(VIA_SIG_CA1, b ? VIA_SIG_RISE : VIA_SIG_FALL);
}
#endif

} /* POST_VIA_FUNCS */
