ftp.nice.ch/pub/next/tools/emulators/vice.0.15.0.NeXT.sd.tgz#/vice-0.15.0/src/c64/rsuser.c

This is rsuser.c in view mode; [Download] [Up]

/*
 * rsuser.h - Daniel Dallmann's 9600 baud RS232 userport interface
 *
 * Written by
 *  André Fachat        (a.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.
 *
 */
/*
 * This is a very crude emulation. It does not check for a lot of things.
 * It simply tries to work with existing programs that work on the real
 * machine and does not try to catch rogue attempts...
 */

#include <stdio.h>

#include "vice.h"
#include "types.h"
#include "cmdline.h"
#include "resources.h"
#include "rs232.h"
#include "rsuser.h"
#include "c64cia.h"
#include "interrupt.h"
#include "vmachine.h"

static int fd;

static int dtr;
static int rts;

static int rxstate;
static BYTE rxdata;

#undef DEBUG

#define	RSUSER_TICS	21111

/***********************************************************************
 * resource handling
 */

int rsuser_enabled = 0;

static int rsuser_device;

static int set_up_enabled(resource_value_t v) {
    int newval = ((int) v) ? 1 : 0;

    if(newval && !rsuser_enabled) {
	dtr = DTR_OUT;	/* inactive */
	rts = RTS_OUT;	/* inactive */
	fd = -1;
    }
    if(rsuser_enabled && !newval) {
	if(fd>=0) rs232_close(fd);
	maincpu_unset_alarm(A_RSUSER);
	fd = -1;
    }

    rsuser_enabled = newval;
    return 0;
}

static int set_up_device(resource_value_t v) {
    rsuser_device = (int) v;
    return 0;
}

static resource_t resources[] = {
    { "RsUser", RES_INTEGER, (resource_value_t) 0,
      (resource_value_t *) &rsuser_enabled, set_up_enabled },
    { "RsUserDev", RES_INTEGER, (resource_value_t) 0,
      (resource_value_t *) &rsuser_device, set_up_device },
    { NULL }
};

int rsuser_init_resources(void) {
    return resources_register(resources);
}

static cmdline_option_t cmdline_options[] = {
    { "-rsuser", SET_RESOURCE, 0, NULL, NULL, "RsUser",
        (resource_value_t) 1, NULL,
        "Enable the userport 9600 baud RS232 emulation" },
    { "+rsuser", SET_RESOURCE, 0, NULL, NULL, "RsUser",
        (resource_value_t) 0, NULL,
        "Disable the userport 9600 baud RS232 emulation" },
    { "-rsuserdev", SET_RESOURCE, 1, NULL, NULL, "RsUserDev",
        (resource_value_t) 0,
      "<0-2>", "Specify VICE RS232 device for userport" },
    { NULL }
};

int rsuser_init_cmdline_options(void) {
    return cmdline_register_options(cmdline_options);
}

/*********************************************************************/

static unsigned char code[256];
static unsigned int buf;
static unsigned int valid;
static unsigned int masks[] = {
	1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80, 0x100, 0x200, 0x400, 0x800,
	0x1000, 0x2000, 0x4000, 0x8000
};

void rsuser_init(void) {
	int i, j;
	unsigned char c,d;

	for(i=0;i<256;i++) {
	  c = i; d = 0;
	  for(j=0 ;j<8; j++) {
	    d<<=1;
	    if(c&1) d|=1;
	    c>>=1;
	  }
	  code[i] = d;
	}

	dtr = DTR_OUT;	/* inactive */
	rts = RTS_OUT;	/* inactive */
	fd = -1;

	buf = ~0;	/* all 1s */
	valid = 0;
}

void rsuser_reset(void) {
	rxstate = 0;
	if(fd >= 0) rs232_close(fd);
	maincpu_unset_alarm(A_RSUSER);
	fd = -1;

	maincpu_unset_alarm(A_RSUSER);
}

void userport_serial_write_ctrl(int b) {
    int new_dtr = b & DTR_OUT;	/* = 0 is active, != 0 is inactive */
    int new_rts = b & RTS_OUT;	/* = 0 is active, != 0 is inactive */

#ifdef DEBUG
printf("userport_serial_write_ctrl(b=%02x)\n",b);
#endif
    if(rsuser_enabled) {
        if(dtr && !new_dtr) {
/*printf("switch rs232 on\n");*/
            /* switch rs232 on */
            fd = rs232_open(rsuser_device);
	    maincpu_set_alarm(A_RSUSER, RSUSER_TICS);
        }
        if(new_dtr && !dtr && fd>=0) {
/*printf("switch rs232 off\n");*/
	    maincpu_unset_alarm(A_RSUSER);
            rs232_close(fd);
	    fd = -1;
        }
    }

    dtr = new_dtr;
    rts = new_rts;
}

BYTE userport_serial_read_ctrl(void) {
    return CTS_IN | (rsuser_enabled ? 0 : (CTS_IN | DCD_IN));
}

void userport_serial_write_sr(BYTE b) {
    BYTE c;

    buf = (buf << 8) | b;
    valid += 8;

    while(valid >= 10 && (buf & masks[valid-1])) valid--;

    /* printf("rsuser_write_sr(%02x), buf=%x, valid=%d\n",b, buf, valid); */

    if(valid>=10) {	/* (valid-1)-th bit is not set = start bit! */
	if(!(buf & masks[valid-10])) {
	    fprintf(stderr, "frame error!\n");
	} else {
	    c = (buf >> (valid-9)) & 0xff;
	    /*printf("rsuser_send %c (%02x), buf=%x, valid=%d\n",
						code[c],code[c], buf, valid);*/
	    if(fd>=0) rs232_putc(fd, code[c]);
	}
	valid -= 10;
    }
}


int int_rsuser(long offset) {
#ifdef DEBUG
        printf("int_rsuser(clk=%d, rclk=%ld)\n",clk, clk-offset);
#endif

	switch(rxstate) {
	case 0:
        	if( fd>=0 && rs232_getc(fd, &rxdata)) {

		  /* byte received, signal startbit on flag */
                  rxstate ++;
		  cia2_set_flag();
		  maincpu_set_alarm(A_RSUSER, RSUSER_TICS);

		} else {
		  /* no byte received */
		  maincpu_set_alarm(A_RSUSER, RSUSER_TICS);
		}
		break;
	case 1:
		/* now byte should be in shift register */
		cia2_set_sdr(code[rxdata]);
		rxstate = 0;
		maincpu_set_alarm(A_RSUSER, RSUSER_TICS);
		break;
        }

        return 0;
}


These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.