mirror of
https://github.com/rcornwell/sims.git
synced 2026-03-29 02:55:02 +00:00
KA10: Enable PDP6 slave CPU support.
This commit is contained in:
@@ -31,9 +31,6 @@
|
||||
#endif
|
||||
|
||||
#if NUM_DEVS_AUXCPU > 0
|
||||
#include <fcntl.h>
|
||||
//#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/* External bus interface. */
|
||||
#define DATO 1
|
||||
@@ -51,12 +48,11 @@
|
||||
|
||||
#define AUXCPU_POLL 1000
|
||||
|
||||
#define PIA u3
|
||||
#define STATUS u4
|
||||
t_addr auxcpu_base = 03000000;
|
||||
|
||||
static int pia = 0;
|
||||
static int status = 0;
|
||||
int auxcpu_base = 03000000;
|
||||
|
||||
static t_stat auxcpu_devio(uint32 dev, t_uint64 *data);
|
||||
static t_stat auxcpu_devio(uint32 dev, uint64 *data);
|
||||
static t_stat auxcpu_svc (UNIT *uptr);
|
||||
static t_stat auxcpu_reset (DEVICE *dptr);
|
||||
static t_stat auxcpu_attach (UNIT *uptr, CONST char *ptr);
|
||||
@@ -144,7 +140,6 @@ static t_stat auxcpu_attach (UNIT *uptr, CONST char *cptr)
|
||||
return r;
|
||||
sim_debug(DBG_TRC, &auxcpu_dev, "activate connection\n");
|
||||
sim_activate (uptr, 10); /* start poll */
|
||||
uptr->flags |= UNIT_ATT;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -156,8 +151,6 @@ static t_stat auxcpu_detach (UNIT *uptr)
|
||||
return SCPE_OK;
|
||||
sim_cancel (uptr);
|
||||
r = tmxr_detach (&auxcpu_desc, uptr);
|
||||
uptr->flags &= ~UNIT_ATT;
|
||||
free (uptr->filename);
|
||||
uptr->filename = NULL;
|
||||
return r;
|
||||
}
|
||||
@@ -176,9 +169,9 @@ static t_stat auxcpu_svc (UNIT *uptr)
|
||||
tmxr_reset_ln (&auxcpu_ldsc);
|
||||
}
|
||||
|
||||
/* If incoming interrput => status |= 010 */
|
||||
if (status & 010)
|
||||
set_interrupt(AUXCPU_DEVNUM, pia);
|
||||
/* If incoming interrput => uptr->STATUS |= 010 */
|
||||
if (uptr->STATUS & 010)
|
||||
set_interrupt(AUXCPU_DEVNUM, uptr->PIA);
|
||||
else
|
||||
clr_interrupt(AUXCPU_DEVNUM);
|
||||
|
||||
@@ -187,6 +180,7 @@ static t_stat auxcpu_svc (UNIT *uptr)
|
||||
auxcpu_ldsc.rcve = 1;
|
||||
uptr->wait = AUXCPU_POLL;
|
||||
}
|
||||
|
||||
sim_clock_coschedule (uptr, uptr->wait);
|
||||
return SCPE_OK;
|
||||
}
|
||||
@@ -239,25 +233,18 @@ static int transaction (unsigned char *request, unsigned char *response)
|
||||
stat = tmxr_get_packet_ln (&auxcpu_ldsc, &auxcpu_request, &size);
|
||||
} while (stat != SCPE_OK || size == 0);
|
||||
|
||||
if (size > 7)
|
||||
if (size > 9)
|
||||
return error ("Malformed transaction");
|
||||
|
||||
memcpy (response, auxcpu_request, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int auxcpu_read (t_addr addr, t_uint64 *data)
|
||||
int auxcpu_read (t_addr addr, uint64 *data)
|
||||
{
|
||||
unsigned char request[12];
|
||||
unsigned char response[12];
|
||||
|
||||
sim_interval -= AUXCPU_MEM_CYCLE;
|
||||
|
||||
if ((auxcpu_unit[0].flags & UNIT_ATT) == 0) {
|
||||
*data = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
addr &= 037777;
|
||||
|
||||
memset (request, 0, sizeof request);
|
||||
@@ -271,11 +258,11 @@ int auxcpu_read (t_addr addr, t_uint64 *data)
|
||||
switch (response[0])
|
||||
{
|
||||
case ACK:
|
||||
*data = (t_uint64)response[1];
|
||||
*data |= (t_uint64)response[2] << 8;
|
||||
*data |= (t_uint64)response[3] << 16;
|
||||
*data |= (t_uint64)response[4] << 24;
|
||||
*data |= (t_uint64)response[5] << 32;
|
||||
*data = (uint64)response[1];
|
||||
*data |= (uint64)response[2] << 8;
|
||||
*data |= (uint64)response[3] << 16;
|
||||
*data |= (uint64)response[4] << 24;
|
||||
*data |= (uint64)response[5] << 32;
|
||||
break;
|
||||
case ERR:
|
||||
fprintf (stderr, "AUXCPU: Read error %06o\r\n", addr);
|
||||
@@ -286,22 +273,20 @@ int auxcpu_read (t_addr addr, t_uint64 *data)
|
||||
*data = 0;
|
||||
break;
|
||||
default:
|
||||
fprintf (stderr, "AUXCPU: recieved %o\r\n", response[0]);
|
||||
return error ("Protocol error");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int auxcpu_write (t_addr addr, t_uint64 data)
|
||||
int auxcpu_write (t_addr addr, uint64 data)
|
||||
{
|
||||
unsigned char request[12];
|
||||
unsigned char response[12];
|
||||
|
||||
sim_interval -= AUXCPU_MEM_CYCLE;
|
||||
|
||||
if ((ten11_unit[0].flags & UNIT_ATT) == 0) {
|
||||
return 0;
|
||||
}
|
||||
t_addr address;
|
||||
size_t size;
|
||||
t_stat stat;
|
||||
|
||||
addr &= 037777;
|
||||
|
||||
@@ -318,8 +303,7 @@ int auxcpu_write (t_addr addr, t_uint64 data)
|
||||
|
||||
transaction (request, response);
|
||||
|
||||
switch (response[0])
|
||||
{
|
||||
switch (response[0]) {
|
||||
case ACK:
|
||||
break;
|
||||
case ERR:
|
||||
@@ -329,9 +313,9 @@ int auxcpu_write (t_addr addr, t_uint64 data)
|
||||
fprintf (stderr, "AUXCPU: Write timeout %06o\r\n", addr);
|
||||
break;
|
||||
default:
|
||||
fprintf (stderr, "AUXCPU: recieved %o\r\n", response[0]);
|
||||
return error ("Protocol error");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -362,25 +346,26 @@ static int auxcpu_interrupt (void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
t_stat auxcpu_devio(uint32 dev, t_uint64 *data)
|
||||
t_stat auxcpu_devio(uint32 dev, uint64 *data)
|
||||
{
|
||||
DEVICE *dptr = &auxcpu_dev;
|
||||
UNIT *uptr = &auxcpu_unit[0];
|
||||
|
||||
switch(dev & 07) {
|
||||
case CONO:
|
||||
sim_debug(DEBUG_CONO, &auxcpu_dev, "CONO %012llo\n", *data);
|
||||
pia = *data & 7;
|
||||
uptr->PIA = *data & 7;
|
||||
if (*data & 010)
|
||||
{
|
||||
// Clear interrupt from the PDP-6.
|
||||
status &= ~010;
|
||||
uptr->STATUS &= ~010;
|
||||
clr_interrupt(AUXCPU_DEVNUM);
|
||||
}
|
||||
if (*data & 020)
|
||||
auxcpu_interrupt ();
|
||||
break;
|
||||
case CONI:
|
||||
*data = (status & 010) | pia;
|
||||
*data = (uptr->STATUS & 010) | uptr->PIA;
|
||||
sim_debug(DEBUG_CONI, &auxcpu_dev, "CONI %012llo\n", *data);
|
||||
break;
|
||||
case DATAI:
|
||||
@@ -407,13 +392,14 @@ static t_stat auxcpu_set_base (UNIT *uptr, int32 val, CONST char *cptr, void *de
|
||||
if (r != SCPE_OK)
|
||||
return SCPE_ARG;
|
||||
|
||||
auxcpu_base = (int)x;
|
||||
auxcpu_base = (t_addr)(x&03777777);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat auxcpu_show_base (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
|
||||
{
|
||||
fprintf (st, "Base: %06o", auxcpu_base);
|
||||
fprintf (st, "Base: %011o", auxcpu_base);
|
||||
return SCPE_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -263,7 +263,7 @@ int32 tmxr_poll = 10000;
|
||||
/* Physical address range for Rubin 10-11 interface. */
|
||||
#define T11RANGE(addr) ((addr) >= 03040000)
|
||||
/* Physical address range for auxiliary PDP-6. */
|
||||
#define AUXCPURANGE(addr) ((addr) >= 03000000 && (addr) < 03040000)
|
||||
#define AUXCPURANGE(addr) ((addr) >= auxcpu_base && (addr) < (auxcpu_base + 040000))
|
||||
|
||||
|
||||
/* List of RH10 & RH20 devices */
|
||||
@@ -913,6 +913,11 @@ int opflags[] = {
|
||||
#else
|
||||
#define QKLB 0
|
||||
#endif
|
||||
#if PDP6
|
||||
#define QSLAVE (slave_unit[0].flags & UNIT_ATT)
|
||||
#else
|
||||
#define QSLAVE 0
|
||||
#endif
|
||||
|
||||
#if KL
|
||||
struct _byte {
|
||||
@@ -3171,7 +3176,6 @@ int Mem_read_its(int flag, int cur_context, int fetch) {
|
||||
nxm_flag = 1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if (addr >= (int)MEMSIZE) {
|
||||
@@ -3218,7 +3222,6 @@ int Mem_write_its(int flag, int cur_context) {
|
||||
nxm_flag = 1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if (addr >= (int)MEMSIZE) {
|
||||
|
||||
@@ -415,7 +415,6 @@ extern void restore_pi_hold();
|
||||
extern void set_pi_hold();
|
||||
extern UNIT cpu_unit[];
|
||||
extern UNIT ten11_unit[];
|
||||
extern UNIT auxcpu_unit[];
|
||||
#if KL
|
||||
extern DEVICE dte_dev;
|
||||
extern DEVICE lp20_dev;
|
||||
@@ -460,6 +459,7 @@ extern DEVICE mty_dev;
|
||||
extern DEVICE ten11_dev;
|
||||
extern DEVICE dkb_dev;
|
||||
extern DEVICE auxcpu_dev;
|
||||
extern DEVICE slave_dev;
|
||||
extern DEVICE dpk_dev;
|
||||
extern DEVICE wcnsls_dev; /* MIT Spacewar Consoles */
|
||||
extern DEVICE ocnsls_dev; /* Old MIT Spacewar Consoles */
|
||||
@@ -573,8 +573,6 @@ extern void ka10_lights_main (t_uint64);
|
||||
extern void ka10_lights_set_aux (int);
|
||||
extern void ka10_lights_clear_aux (int);
|
||||
|
||||
int auxcpu_read (t_addr addr, t_uint64 *);
|
||||
int auxcpu_write (t_addr addr, t_uint64);
|
||||
|
||||
/* I/O system parameters */
|
||||
#define NUM_DEVS_LP 1
|
||||
@@ -596,6 +594,7 @@ int auxcpu_write (t_addr addr, t_uint64);
|
||||
#define NUM_DEVS_MTC 1
|
||||
#define NUM_DEVS_DSK 1
|
||||
#define NUM_DEVS_DCS 1
|
||||
#define NUM_DEVS_SLAVE PDP6
|
||||
#endif
|
||||
#if !PDP6
|
||||
#define NUM_DEVS_DC 1
|
||||
@@ -650,4 +649,16 @@ extern t_uint64 FM[];
|
||||
extern uint32 PC;
|
||||
extern uint32 FLAGS;
|
||||
|
||||
#if NUM_DEVS_AUXCPU
|
||||
extern t_addr auxcpu_base;
|
||||
int auxcpu_read (t_addr addr, uint64 *);
|
||||
int auxcpu_write (t_addr addr, uint64);
|
||||
extern UNIT auxcpu_unit[];
|
||||
#endif
|
||||
#if NUM_DEVS_SLAVE
|
||||
//int slave_read (t_addr addr);
|
||||
//int slave_write (t_addr addr, uint64);
|
||||
//extern UNIT slave_unit[];
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -197,6 +197,9 @@ DEVICE *sim_devices[] = {
|
||||
#if NUM_DEVS_AUXCPU > 0
|
||||
&auxcpu_dev,
|
||||
#endif
|
||||
#if NUM_DEVS_SLAVE > 0
|
||||
&slave_dev,
|
||||
#endif
|
||||
#if NUM_DEVS_DKB > 0
|
||||
&dkb_dev,
|
||||
#endif
|
||||
|
||||
468
PDP10/pdp6_slave.c
Normal file
468
PDP10/pdp6_slave.c
Normal file
@@ -0,0 +1,468 @@
|
||||
/* pdp6_slave.c: Slaved processor.
|
||||
|
||||
Copyright (c) 2018, Lars Brinkhoff
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL LARS BRINKHOFF BE LIABLE FOR ANY CLAIM, DAMAGES
|
||||
OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
||||
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
This is a device which interfaces with a master processor through
|
||||
shared memory and inter-processor interrupts.
|
||||
*/
|
||||
|
||||
#include "kx10_defs.h"
|
||||
#include "sim_tmxr.h"
|
||||
|
||||
#ifndef NUM_DEVS_SLAVE
|
||||
#define NUM_DEVS_SLAVE 0
|
||||
#endif
|
||||
|
||||
#if NUM_DEVS_SLAVE > 0
|
||||
|
||||
/* External bus interface. */
|
||||
#define DATO 1
|
||||
#define DATI 2
|
||||
#define ACK 3
|
||||
#define ERR 4
|
||||
#define TIMEOUT 5
|
||||
#define IRQ 6
|
||||
|
||||
/* Simulator time units for a Unibus memory cycle. */
|
||||
#define SLAVE_MEM_CYCLE 100
|
||||
|
||||
/* Interprocessor interrupt device. */
|
||||
#define SLAVE_DEVNUM 020
|
||||
|
||||
#define SLAVE_POLL 1000
|
||||
|
||||
#define PIA u3
|
||||
#define STATUS u4
|
||||
|
||||
static t_stat slave_devio(uint32 dev, uint64 *data);
|
||||
static t_stat slave_svc (UNIT *uptr);
|
||||
static t_stat slave_reset (DEVICE *dptr);
|
||||
static t_stat slave_attach (UNIT *uptr, CONST char *ptr);
|
||||
static t_stat slave_detach (UNIT *uptr);
|
||||
static t_stat slave_attach_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
|
||||
static const char *slave_description (DEVICE *dptr);
|
||||
static uint8 slave_valid[040000];
|
||||
|
||||
UNIT slave_unit[1] = {
|
||||
{ UDATA (&slave_svc, UNIT_IDLE|UNIT_ATTABLE, 0), 1000 },
|
||||
};
|
||||
|
||||
static REG slave_reg[] = {
|
||||
{ DRDATAD (POLL, slave_unit[0].wait, 24, "poll interval"), PV_LEFT },
|
||||
{BRDATA(BUFF, &slave_valid[0], 8, 8, sizeof(slave_valid)), REG_HRO},
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static MTAB slave_mod[] = {
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
#define DEBUG_TRC 0x0000400
|
||||
|
||||
static DEBTAB slave_debug[] = {
|
||||
{"TRACE", DEBUG_TRC, "Routine trace"},
|
||||
{"CMD", DEBUG_CMD, "Command Processing"},
|
||||
{"CONO", DEBUG_CONO, "CONO instructions"},
|
||||
{"CONI", DEBUG_CONI, "CONI instructions"},
|
||||
{"DATAIO", DEBUG_DATAIO, "DATAI/O instructions"},
|
||||
{0},
|
||||
};
|
||||
|
||||
DEVICE slave_dev = {
|
||||
"SLAVE", slave_unit, slave_reg, slave_mod,
|
||||
1, 8, 16, 2, 8, 16,
|
||||
NULL, /* examine */
|
||||
NULL, /* deposit */
|
||||
&slave_reset, /* reset */
|
||||
NULL, /* boot */
|
||||
slave_attach, /* attach */
|
||||
slave_detach, /* detach */
|
||||
NULL, /* context */
|
||||
DEV_DISABLE | DEV_DIS | DEV_DEBUG | DEV_MUX,
|
||||
DEBUG_CMD, /* debug control */
|
||||
slave_debug, /* debug flags */
|
||||
NULL, /* memory size chage */
|
||||
NULL, /* logical name */
|
||||
NULL, /* help */
|
||||
&slave_attach_help, /* attach help */
|
||||
NULL, /* help context */
|
||||
&slave_description, /* description */
|
||||
};
|
||||
|
||||
static TMLN slave_ldsc; /* line descriptor */
|
||||
static TMXR slave_desc = { 1, 0, 0, &slave_ldsc }; /* mux descriptor */
|
||||
|
||||
static t_stat slave_reset (DEVICE *dptr)
|
||||
{
|
||||
sim_debug(DEBUG_TRC, dptr, "slave_reset()\n");
|
||||
|
||||
slave_unit[0].flags |= UNIT_ATTABLE | UNIT_IDLE;
|
||||
slave_desc.packet = TRUE;
|
||||
slave_desc.notelnet = TRUE;
|
||||
slave_desc.buffered = 2048;
|
||||
|
||||
if (slave_unit[0].flags & UNIT_ATT)
|
||||
sim_activate (&slave_unit[0], 1000);
|
||||
else
|
||||
sim_cancel (&slave_unit[0]);
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat slave_attach (UNIT *uptr, CONST char *cptr)
|
||||
{
|
||||
char *peer = "localhost:6666";
|
||||
char linkinfo[256];
|
||||
t_stat r;
|
||||
|
||||
if (!cptr || !*cptr)
|
||||
return SCPE_ARG;
|
||||
if (!(uptr->flags & UNIT_ATTABLE))
|
||||
return SCPE_NOATT;
|
||||
snprintf (linkinfo, sizeof linkinfo, "%s,connect=%s;notelnet",
|
||||
cptr, peer);
|
||||
r = tmxr_attach_ex (&slave_desc, uptr, cptr, FALSE);
|
||||
if (r != SCPE_OK) /* error? */
|
||||
return r;
|
||||
sim_debug(DEBUG_TRC, &slave_dev, "activate connection\n");
|
||||
sim_activate (uptr, 10); /* start poll */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat slave_detach (UNIT *uptr)
|
||||
{
|
||||
t_stat r;
|
||||
|
||||
if (!(uptr->flags & UNIT_ATT))
|
||||
return SCPE_OK;
|
||||
sim_cancel (uptr);
|
||||
r = tmxr_detach (&slave_desc, uptr);
|
||||
uptr->filename = NULL;
|
||||
return r;
|
||||
}
|
||||
|
||||
static int error (const char *message)
|
||||
{
|
||||
sim_debug (DEBUG_TRC, &slave_dev, "%s\r\n", message);
|
||||
sim_debug (DEBUG_TRC, &slave_dev, "CLOSE\r\n");
|
||||
slave_ldsc.rcve = 0;
|
||||
tmxr_reset_ln (&slave_ldsc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void build (uint8 *request, uint8 octet)
|
||||
{
|
||||
request[0]++;
|
||||
request[request[0]] = octet & 0377;
|
||||
}
|
||||
|
||||
static t_stat process_request (UNIT *uptr, const uint8 *request, size_t size)
|
||||
{
|
||||
uint8 response[12];
|
||||
int address;
|
||||
uint64 data;
|
||||
t_stat stat;
|
||||
|
||||
if (size == 0)
|
||||
return SCPE_OK;
|
||||
if (size > 9)
|
||||
return error ("Malformed transaction");
|
||||
|
||||
sim_debug(DEBUG_CMD, &slave_dev, "got packet\n");
|
||||
|
||||
memset (response, 0, sizeof response);
|
||||
|
||||
switch (request[0]) {
|
||||
case DATI:
|
||||
address = request[1] + (request[2] << 8) + (request[3] << 16);
|
||||
if (address < MEMSIZE) {
|
||||
data = M[address];
|
||||
build (response, ACK);
|
||||
build (response, data);
|
||||
build (response, data >> 8);
|
||||
build (response, data >> 16);
|
||||
build (response, data >> 24);
|
||||
build (response, data >> 32);
|
||||
sim_debug(DEBUG_DATAIO, &slave_dev, "DATI %06o -> %012llo\n",
|
||||
address, data);
|
||||
} else {
|
||||
build (response, ERR);
|
||||
sim_debug(DEBUG_DATAIO, &slave_dev, "DATI %06o -> NXM\n", address);
|
||||
}
|
||||
break;
|
||||
case DATO:
|
||||
address = request[1] + (request[2] << 8) + (request[3] << 16);
|
||||
if (address < MEMSIZE) {
|
||||
data = request[4];
|
||||
data |= ((uint64)request[5]) << 8;
|
||||
data |= ((uint64)request[6]) << 16;
|
||||
data |= ((uint64)request[7]) << 24;
|
||||
data |= ((uint64)request[8]) << 32;
|
||||
M[address] = data;
|
||||
build (response, ACK);
|
||||
sim_debug(DEBUG_DATAIO, &slave_dev, "DATO %06o <- %012llo\n",
|
||||
address, data);
|
||||
} else {
|
||||
build (response, ERR);
|
||||
sim_debug(DEBUG_DATAIO, &slave_dev, "DATO %06o -> NXM\n", address);
|
||||
}
|
||||
break;
|
||||
case ACK:
|
||||
break;
|
||||
case IRQ:
|
||||
uptr->STATUS |= 010;
|
||||
set_interrupt(SLAVE_DEVNUM, uptr->PIA);
|
||||
build (response, ACK);
|
||||
sim_debug(DEBUG_DATAIO, &slave_dev, "IRQ\n");
|
||||
break;
|
||||
default:
|
||||
return error ("Malformed transaction");
|
||||
}
|
||||
|
||||
stat = tmxr_put_packet_ln (&slave_ldsc, response + 1, (size_t)response[0]);
|
||||
if (stat != SCPE_OK)
|
||||
return error ("Write error in transaction");
|
||||
return stat;
|
||||
}
|
||||
|
||||
static t_stat slave_svc (UNIT *uptr)
|
||||
{
|
||||
const uint8 *slave_request;
|
||||
size_t size;
|
||||
|
||||
if (tmxr_poll_conn(&slave_desc) >= 0) {
|
||||
sim_debug(DEBUG_CMD, &slave_dev, "got connection\n");
|
||||
slave_ldsc.rcve = 1;
|
||||
memset(&slave_valid[0], 0, sizeof(slave_valid));
|
||||
uptr->wait = SLAVE_POLL;
|
||||
}
|
||||
|
||||
tmxr_poll_rx (&slave_desc);
|
||||
if (slave_ldsc.rcve && !slave_ldsc.conn) {
|
||||
slave_ldsc.rcve = 0;
|
||||
tmxr_reset_ln (&slave_ldsc);
|
||||
sim_debug(DEBUG_CMD, &slave_dev, "reset\n");
|
||||
}
|
||||
|
||||
if (tmxr_get_packet_ln (&slave_ldsc, &slave_request, &size) == SCPE_OK)
|
||||
process_request (uptr, slave_request, size);
|
||||
|
||||
sim_clock_coschedule (uptr, uptr->wait);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat slave_attach_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
||||
{
|
||||
const char helpString[] =
|
||||
/* The '*'s in the next line represent the standard text width of a help line */
|
||||
/****************************************************************************/
|
||||
" The %D device connects a secondary processor that is sharing memory with the.\n"
|
||||
" primary.\n\n"
|
||||
" The device must be attached to a receive port, this is done by using the\n"
|
||||
" ATTACH command to specify the receive port number.\n"
|
||||
"\n"
|
||||
"+sim> ATTACH %U port\n"
|
||||
"\n"
|
||||
;
|
||||
|
||||
return scp_help (st, dptr, uptr, flag, helpString, cptr);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
static const char *slave_description (DEVICE *dptr)
|
||||
{
|
||||
return "Auxiliary processor";
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int transaction (uint8 *request, uint8 *response)
|
||||
{
|
||||
const uint8 *slave_request;
|
||||
size_t size;
|
||||
t_stat stat;
|
||||
|
||||
stat = tmxr_put_packet_ln (&slave_ldsc, request + 1, (size_t)request[0]);
|
||||
if (stat != SCPE_OK)
|
||||
return error ("Write error in transaction");
|
||||
do {
|
||||
tmxr_poll_rx (&slave_desc);
|
||||
stat = tmxr_get_packet_ln (&slave_ldsc, &slave_request, &size);
|
||||
} while (stat != SCPE_OK || size == 0);
|
||||
|
||||
if (size > 9)
|
||||
return error ("Malformed transaction");
|
||||
|
||||
memcpy (response, slave_request, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int slave_read (t_addr addr)
|
||||
{
|
||||
uint64 data;
|
||||
uint8 request[12];
|
||||
uint8 response[12];
|
||||
|
||||
if ((slave_unit[0].flags & UNIT_ATT) == 0)
|
||||
return 0;
|
||||
|
||||
addr &= 037777;
|
||||
|
||||
if (slave_valid[addr] || slave_ldsc.rcve == 0)
|
||||
return 0;
|
||||
|
||||
memset (request, 0, sizeof request);
|
||||
build (request, DATI);
|
||||
build (request, addr & 0377);
|
||||
build (request, (addr >> 8) & 0377);
|
||||
build (request, (addr >> 16) & 0377);
|
||||
|
||||
transaction (request, response);
|
||||
|
||||
switch (response[0])
|
||||
{
|
||||
case ACK:
|
||||
data = (uint64)response[1];
|
||||
data |= (uint64)response[2] << 8;
|
||||
data |= (uint64)response[3] << 16;
|
||||
data |= (uint64)response[4] << 24;
|
||||
data |= (uint64)response[5] << 32;
|
||||
M[addr] = data;
|
||||
slave_valid[addr] = 1;
|
||||
break;
|
||||
case ERR:
|
||||
fprintf (stderr, "SLAVE: Read error %06o\r\n", addr);
|
||||
break;
|
||||
case TIMEOUT:
|
||||
fprintf (stderr, "SLAVE: Read timeout %06o\r\n", addr);
|
||||
break;
|
||||
default:
|
||||
return error ("Protocol error");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int slave_write (t_addr addr, uint64 data)
|
||||
{
|
||||
uint8 request[12];
|
||||
uint8 response[12];
|
||||
|
||||
if ((slave_unit[0].flags & UNIT_ATT) == 0)
|
||||
return 0;
|
||||
|
||||
addr &= 037777;
|
||||
slave_valid[addr] = 1;
|
||||
|
||||
memset (request, 0, sizeof request);
|
||||
build (request, DATO);
|
||||
build (request, (addr) & 0377);
|
||||
build (request, (addr >> 8) & 0377);
|
||||
build (request, (addr >> 16) & 0377);
|
||||
build (request, (data) & 0377);
|
||||
build (request, (data >> 8) & 0377);
|
||||
build (request, (data >> 16) & 0377);
|
||||
build (request, (data >> 24) & 0377);
|
||||
build (request, (data >> 32) & 0377);
|
||||
|
||||
transaction (request, response);
|
||||
|
||||
switch (response[0])
|
||||
{
|
||||
case ACK:
|
||||
break;
|
||||
case ERR:
|
||||
fprintf (stderr, "SLAVE: Write error %06o\r\n", addr);
|
||||
break;
|
||||
case TIMEOUT:
|
||||
fprintf (stderr, "SLAVE: Write timeout %06o\r\n", addr);
|
||||
break;
|
||||
default:
|
||||
return error ("Protocol error");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int slave_interrupt (void)
|
||||
{
|
||||
uint8 request[12];
|
||||
uint8 response[12];
|
||||
memset (request, 0, sizeof request);
|
||||
|
||||
sim_debug(DEBUG_IRQ, &slave_dev, "PDP-6 interrupting the PDP-10\n");
|
||||
|
||||
build (request, IRQ);
|
||||
|
||||
transaction (request, response);
|
||||
|
||||
switch (response[1])
|
||||
{
|
||||
case ACK:
|
||||
break;
|
||||
case ERR:
|
||||
case TIMEOUT:
|
||||
fprintf (stderr, "SLAVE: Interrupt error or timeout\r\n");
|
||||
break;
|
||||
default:
|
||||
return error ("Protocol error");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
t_stat slave_devio(uint32 dev, uint64 *data)
|
||||
{
|
||||
DEVICE *dptr = &slave_dev;
|
||||
UNIT *uptr = &slave_unit[0];
|
||||
|
||||
switch(dev & 03) {
|
||||
case CONO:
|
||||
sim_debug(DEBUG_CONO, &slave_dev, "CONO %012llo\n", *data);
|
||||
uptr->PIA = *data & 7;
|
||||
if (*data & 010)
|
||||
{
|
||||
// Clear interrupt from the PDP-10.
|
||||
uptr->STATUS &= ~010;
|
||||
clr_interrupt(SLAVE_DEVNUM);
|
||||
}
|
||||
#if 0
|
||||
if (*data & 020)
|
||||
slave_interrupt ();
|
||||
#endif
|
||||
break;
|
||||
case CONI:
|
||||
*data = (uptr->STATUS & 010) | uptr->PIA;
|
||||
sim_debug(DEBUG_CONI, &slave_dev, "CONI %012llo\n", *data);
|
||||
break;
|
||||
case DATAI:
|
||||
*data = 0;
|
||||
sim_debug(DEBUG_CONI, &slave_dev, "DATAI %012llo\n", *data);
|
||||
break;
|
||||
case DATAO:
|
||||
sim_debug(DEBUG_CONI, &slave_dev, "DATAO %012llo\n", *data);
|
||||
break;
|
||||
}
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
2
makefile
2
makefile
@@ -2012,7 +2012,7 @@ PDP6 = ${PDP6D}/kx10_cpu.c ${PDP6D}/kx10_sys.c ${PDP6D}/kx10_cty.c \
|
||||
${PDP6D}/kx10_lp.c ${PDP6D}/kx10_pt.c ${PDP6D}/kx10_cr.c \
|
||||
${PDP6D}/kx10_cp.c ${PDP6D}/pdp6_dct.c ${PDP6D}/pdp6_dtc.c \
|
||||
${PDP6D}/pdp6_mtc.c ${PDP6D}/pdp6_dsk.c ${PDP6D}/pdp6_dcs.c \
|
||||
${PDP6D}/kx10_dpy.c ${DISPLAYL} ${DISPLAY340}
|
||||
${PDP6D}/kx10_dpy.c ${PDP6D}/pdp6_slave.c ${DISPLAYL} ${DISPLAY340}
|
||||
PDP6_OPT = -DPDP6=1 -DUSE_INT64 -I ${PDP6D} -DUSE_SIM_CARD ${DISPLAY_OPT} ${PDP6_DISPLAY_OPT}
|
||||
|
||||
KA10D = ${SIMHD}/PDP10
|
||||
|
||||
Reference in New Issue
Block a user