KA10: Added support for KL10A/B.
This commit is contained in:
parent
c7d529c4db
commit
c686f75894
49 changed files with 13982 additions and 2447 deletions
|
@ -5,7 +5,7 @@ language: c
|
||||||
env:
|
env:
|
||||||
# These are supposed to match ALL in makefile.
|
# These are supposed to match ALL in makefile.
|
||||||
# Each job builds 15 simulators.
|
# Each job builds 15 simulators.
|
||||||
- SIM="pdp1 pdp4 pdp6 pdp7 pdp8 pdp9 pdp10 pdp10-ka pdp10-ki pdp11 pdp15 vax microvax3900 microvax1 rtvax1000"
|
- SIM="pdp1 pdp4 pdp6 pdp7 pdp8 pdp9 pdp10 pdp10-ka pdp10-ki pdp10-kl pdp11 pdp15 vax microvax3900 microvax1 rtvax1000"
|
||||||
- SIM="microvax2 vax730 vax750 vax780 vax8200 vax8600 microvax2000 infoserver100 infoserver150vxt microvax3100 microvax3100e vaxstation3100m30 vaxstation3100m38 vaxstation3100m76 vaxstation4000m60"
|
- SIM="microvax2 vax730 vax750 vax780 vax8200 vax8600 microvax2000 infoserver100 infoserver150vxt microvax3100 microvax3100e vaxstation3100m30 vaxstation3100m38 vaxstation3100m76 vaxstation4000m60"
|
||||||
- SIM="microvax3100m80 vaxstation4000vlc infoserver1000 nova eclipse hp2100 hp3000 i1401 i1620 s3 altair altairz80 gri i7094 ibm1130"
|
- SIM="microvax3100m80 vaxstation4000vlc infoserver1000 nova eclipse hp2100 hp3000 i1401 i1620 s3 altair altairz80 gri i7094 ibm1130"
|
||||||
- SIM="id16 id32 sds lgp h316 cdc1700 swtp6800mp-a swtp6800mp-a2 tx-0 ssem b5500 isys8010 isys8020 isys8030 isys8024"
|
- SIM="id16 id32 sds lgp h316 cdc1700 swtp6800mp-a swtp6800mp-a2 tx-0 ssem b5500 isys8010 isys8020 isys8030 isys8024"
|
||||||
|
|
|
@ -279,7 +279,7 @@ DEVICE ai_dev = {
|
||||||
AI_NAME, ai_unit, ai_reg, ai_mod,
|
AI_NAME, ai_unit, ai_reg, ai_mod,
|
||||||
NUM_UNITS, 8, 18, 1, 8, 36,
|
NUM_UNITS, 8, 18, 1, 8, 36,
|
||||||
NULL, NULL, &ai_reset, NULL, &ai_attach, &ai_detach,
|
NULL, NULL, &ai_reset, NULL, &ai_attach, &ai_detach,
|
||||||
&ai_dib, DEV_DISABLE | DEV_DEBUG, 0, ai_debug,
|
&ai_dib, DEV_DISABLE | DEV_DEBUG | DEV_DIS, 0, ai_debug,
|
||||||
NULL, NULL, &ai_help, NULL, NULL, &ai_description
|
NULL, NULL, &ai_help, NULL, NULL, &ai_description
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -997,7 +997,7 @@ t_stat ai_attach (UNIT *uptr, CONST char *cptr)
|
||||||
DIB *dib;
|
DIB *dib;
|
||||||
|
|
||||||
r = attach_unit (uptr, cptr);
|
r = attach_unit (uptr, cptr);
|
||||||
if (r != SCPE_OK)
|
if (r != SCPE_OK || (sim_switches & SIM_SW_REST) != 0)
|
||||||
return r;
|
return r;
|
||||||
rptr = find_dev_from_unit(uptr);
|
rptr = find_dev_from_unit(uptr);
|
||||||
if (rptr == 0)
|
if (rptr == 0)
|
||||||
|
|
|
@ -31,9 +31,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if NUM_DEVS_AUXCPU > 0
|
#if NUM_DEVS_AUXCPU > 0
|
||||||
#include <fcntl.h>
|
|
||||||
//#include <unistd.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
/* External bus interface. */
|
/* External bus interface. */
|
||||||
#define DATO 1
|
#define DATO 1
|
||||||
|
@ -51,12 +48,11 @@
|
||||||
|
|
||||||
#define AUXCPU_POLL 1000
|
#define AUXCPU_POLL 1000
|
||||||
|
|
||||||
|
#define PIA u3
|
||||||
|
#define STATUS u4
|
||||||
|
t_addr auxcpu_base = 03000000;
|
||||||
|
|
||||||
static int pia = 0;
|
static t_stat auxcpu_devio(uint32 dev, uint64 *data);
|
||||||
static int status = 0;
|
|
||||||
int auxcpu_base = 03000000;
|
|
||||||
|
|
||||||
static t_stat auxcpu_devio(uint32 dev, t_uint64 *data);
|
|
||||||
static t_stat auxcpu_svc (UNIT *uptr);
|
static t_stat auxcpu_svc (UNIT *uptr);
|
||||||
static t_stat auxcpu_reset (DEVICE *dptr);
|
static t_stat auxcpu_reset (DEVICE *dptr);
|
||||||
static t_stat auxcpu_attach (UNIT *uptr, CONST char *ptr);
|
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;
|
return r;
|
||||||
sim_debug(DBG_TRC, &auxcpu_dev, "activate connection\n");
|
sim_debug(DBG_TRC, &auxcpu_dev, "activate connection\n");
|
||||||
sim_activate (uptr, 10); /* start poll */
|
sim_activate (uptr, 10); /* start poll */
|
||||||
uptr->flags |= UNIT_ATT;
|
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,8 +151,6 @@ static t_stat auxcpu_detach (UNIT *uptr)
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
sim_cancel (uptr);
|
sim_cancel (uptr);
|
||||||
r = tmxr_detach (&auxcpu_desc, uptr);
|
r = tmxr_detach (&auxcpu_desc, uptr);
|
||||||
uptr->flags &= ~UNIT_ATT;
|
|
||||||
free (uptr->filename);
|
|
||||||
uptr->filename = NULL;
|
uptr->filename = NULL;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -176,9 +169,9 @@ static t_stat auxcpu_svc (UNIT *uptr)
|
||||||
tmxr_reset_ln (&auxcpu_ldsc);
|
tmxr_reset_ln (&auxcpu_ldsc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If incoming interrput => status |= 010 */
|
/* If incoming interrput => uptr->STATUS |= 010 */
|
||||||
if (status & 010)
|
if (uptr->STATUS & 010)
|
||||||
set_interrupt(AUXCPU_DEVNUM, pia);
|
set_interrupt(AUXCPU_DEVNUM, uptr->PIA);
|
||||||
else
|
else
|
||||||
clr_interrupt(AUXCPU_DEVNUM);
|
clr_interrupt(AUXCPU_DEVNUM);
|
||||||
|
|
||||||
|
@ -187,6 +180,7 @@ static t_stat auxcpu_svc (UNIT *uptr)
|
||||||
auxcpu_ldsc.rcve = 1;
|
auxcpu_ldsc.rcve = 1;
|
||||||
uptr->wait = AUXCPU_POLL;
|
uptr->wait = AUXCPU_POLL;
|
||||||
}
|
}
|
||||||
|
|
||||||
sim_clock_coschedule (uptr, uptr->wait);
|
sim_clock_coschedule (uptr, uptr->wait);
|
||||||
return SCPE_OK;
|
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);
|
stat = tmxr_get_packet_ln (&auxcpu_ldsc, &auxcpu_request, &size);
|
||||||
} while (stat != SCPE_OK || size == 0);
|
} while (stat != SCPE_OK || size == 0);
|
||||||
|
|
||||||
if (size > 7)
|
if (size > 9)
|
||||||
return error ("Malformed transaction");
|
return error ("Malformed transaction");
|
||||||
|
|
||||||
memcpy (response, auxcpu_request, size);
|
memcpy (response, auxcpu_request, size);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int auxcpu_read (int addr, t_uint64 *data)
|
int auxcpu_read (t_addr addr, uint64 *data)
|
||||||
{
|
{
|
||||||
unsigned char request[12];
|
unsigned char request[12];
|
||||||
unsigned char response[12];
|
unsigned char response[12];
|
||||||
|
|
||||||
sim_interval -= AUXCPU_MEM_CYCLE;
|
|
||||||
|
|
||||||
if ((auxcpu_unit[0].flags & UNIT_ATT) == 0) {
|
|
||||||
*data = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
addr &= 037777;
|
addr &= 037777;
|
||||||
|
|
||||||
memset (request, 0, sizeof request);
|
memset (request, 0, sizeof request);
|
||||||
|
@ -271,11 +258,11 @@ int auxcpu_read (int addr, t_uint64 *data)
|
||||||
switch (response[0])
|
switch (response[0])
|
||||||
{
|
{
|
||||||
case ACK:
|
case ACK:
|
||||||
*data = (t_uint64)response[1];
|
*data = (uint64)response[1];
|
||||||
*data |= (t_uint64)response[2] << 8;
|
*data |= (uint64)response[2] << 8;
|
||||||
*data |= (t_uint64)response[3] << 16;
|
*data |= (uint64)response[3] << 16;
|
||||||
*data |= (t_uint64)response[4] << 24;
|
*data |= (uint64)response[4] << 24;
|
||||||
*data |= (t_uint64)response[5] << 32;
|
*data |= (uint64)response[5] << 32;
|
||||||
break;
|
break;
|
||||||
case ERR:
|
case ERR:
|
||||||
fprintf (stderr, "AUXCPU: Read error %06o\r\n", addr);
|
fprintf (stderr, "AUXCPU: Read error %06o\r\n", addr);
|
||||||
|
@ -286,23 +273,18 @@ int auxcpu_read (int addr, t_uint64 *data)
|
||||||
*data = 0;
|
*data = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
fprintf (stderr, "AUXCPU: recieved %o\r\n", response[0]);
|
||||||
return error ("Protocol error");
|
return error ("Protocol error");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int auxcpu_write (int addr, t_uint64 data)
|
int auxcpu_write (t_addr addr, uint64 data)
|
||||||
{
|
{
|
||||||
unsigned char request[12];
|
unsigned char request[12];
|
||||||
unsigned char response[12];
|
unsigned char response[12];
|
||||||
|
|
||||||
sim_interval -= AUXCPU_MEM_CYCLE;
|
|
||||||
|
|
||||||
if ((ten11_unit[0].flags & UNIT_ATT) == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
addr &= 037777;
|
addr &= 037777;
|
||||||
|
|
||||||
memset (request, 0, sizeof request);
|
memset (request, 0, sizeof request);
|
||||||
|
@ -318,8 +300,7 @@ int auxcpu_write (int addr, t_uint64 data)
|
||||||
|
|
||||||
transaction (request, response);
|
transaction (request, response);
|
||||||
|
|
||||||
switch (response[0])
|
switch (response[0]) {
|
||||||
{
|
|
||||||
case ACK:
|
case ACK:
|
||||||
break;
|
break;
|
||||||
case ERR:
|
case ERR:
|
||||||
|
@ -329,9 +310,9 @@ int auxcpu_write (int addr, t_uint64 data)
|
||||||
fprintf (stderr, "AUXCPU: Write timeout %06o\r\n", addr);
|
fprintf (stderr, "AUXCPU: Write timeout %06o\r\n", addr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
fprintf (stderr, "AUXCPU: recieved %o\r\n", response[0]);
|
||||||
return error ("Protocol error");
|
return error ("Protocol error");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,25 +343,26 @@ static int auxcpu_interrupt (void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
t_stat auxcpu_devio(uint32 dev, t_uint64 *data)
|
t_stat auxcpu_devio(uint32 dev, uint64 *data)
|
||||||
{
|
{
|
||||||
DEVICE *dptr = &auxcpu_dev;
|
DEVICE *dptr = &auxcpu_dev;
|
||||||
|
UNIT *uptr = &auxcpu_unit[0];
|
||||||
|
|
||||||
switch(dev & 07) {
|
switch(dev & 07) {
|
||||||
case CONO:
|
case CONO:
|
||||||
sim_debug(DEBUG_CONO, &auxcpu_dev, "CONO %012llo\n", *data);
|
sim_debug(DEBUG_CONO, &auxcpu_dev, "CONO %012llo\n", *data);
|
||||||
pia = *data & 7;
|
uptr->PIA = *data & 7;
|
||||||
if (*data & 010)
|
if (*data & 010)
|
||||||
{
|
{
|
||||||
// Clear interrupt from the PDP-6.
|
// Clear interrupt from the PDP-6.
|
||||||
status &= ~010;
|
uptr->STATUS &= ~010;
|
||||||
clr_interrupt(AUXCPU_DEVNUM);
|
clr_interrupt(AUXCPU_DEVNUM);
|
||||||
}
|
}
|
||||||
if (*data & 020)
|
if (*data & 020)
|
||||||
auxcpu_interrupt ();
|
auxcpu_interrupt ();
|
||||||
break;
|
break;
|
||||||
case CONI:
|
case CONI:
|
||||||
*data = (status & 010) | pia;
|
*data = (uptr->STATUS & 010) | uptr->PIA;
|
||||||
sim_debug(DEBUG_CONI, &auxcpu_dev, "CONI %012llo\n", *data);
|
sim_debug(DEBUG_CONI, &auxcpu_dev, "CONI %012llo\n", *data);
|
||||||
break;
|
break;
|
||||||
case DATAI:
|
case DATAI:
|
||||||
|
@ -407,13 +389,14 @@ static t_stat auxcpu_set_base (UNIT *uptr, int32 val, CONST char *cptr, void *de
|
||||||
if (r != SCPE_OK)
|
if (r != SCPE_OK)
|
||||||
return SCPE_ARG;
|
return SCPE_ARG;
|
||||||
|
|
||||||
auxcpu_base = (int)x;
|
auxcpu_base = (t_addr)(x&03777777);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static t_stat auxcpu_show_base (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
|
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;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -335,8 +335,6 @@ void ch10_command (uint32 data)
|
||||||
|
|
||||||
t_stat ch10_devio(uint32 dev, uint64 *data)
|
t_stat ch10_devio(uint32 dev, uint64 *data)
|
||||||
{
|
{
|
||||||
DEVICE *dptr = &imx_dev;
|
|
||||||
|
|
||||||
switch(dev & 07) {
|
switch(dev & 07) {
|
||||||
case CONO:
|
case CONO:
|
||||||
sim_debug (DBG_REG, &ch10_dev, "CONO %012llo %012llo \n", *data, ch10_status);
|
sim_debug (DBG_REG, &ch10_dev, "CONO %012llo %012llo \n", *data, ch10_status);
|
||||||
|
|
366
PDP10/ka10_dkb.c
366
PDP10/ka10_dkb.c
|
@ -1,6 +1,6 @@
|
||||||
/* ka10_dkb.c:Stanford Microswitch scanner.
|
/* ka10_dkb.c:Stanford Microswitch scanner.
|
||||||
|
|
||||||
Copyright (c) 2013-2017, Richard Cornwell
|
Copyright (c) 2019-2020, Richard Cornwell
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -32,20 +32,40 @@
|
||||||
|
|
||||||
#if NUM_DEVS_DKB > 0
|
#if NUM_DEVS_DKB > 0
|
||||||
|
|
||||||
t_stat dkb_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
|
#include "sim_video.h"
|
||||||
const char *dkb_description (DEVICE *dptr);
|
|
||||||
|
|
||||||
#define DKB_DEVNUM 0310
|
#define DKB_DEVNUM 0310
|
||||||
|
|
||||||
|
#define DONE 010 /* Device has character */
|
||||||
|
#define SPW 020 /* Scanner in SPW mode */
|
||||||
|
|
||||||
|
#define VALID 010000
|
||||||
|
#define SPW_FLG 020000
|
||||||
|
#define CHAR 001777
|
||||||
|
#define SHFT 000100
|
||||||
|
#define TOP 000200
|
||||||
|
#define META 000400
|
||||||
|
#define CTRL 001000
|
||||||
|
|
||||||
#define STATUS u3
|
#define STATUS u3
|
||||||
#define DATA u4
|
#define DATA u4
|
||||||
#define PIA u5
|
#define PIA u5
|
||||||
|
#define LINE u6
|
||||||
|
|
||||||
t_stat dkb_devio(uint32 dev, uint64 *data);
|
t_stat dkb_devio(uint32 dev, uint64 *data);
|
||||||
|
int dkb_keyboard (SIM_KEY_EVENT *kev);
|
||||||
|
t_stat dkb_svc(UNIT *uptr);
|
||||||
|
t_stat dkb_reset(DEVICE *dptr);
|
||||||
|
t_stat dkb_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
|
||||||
|
const char *dkb_description (DEVICE *dptr);
|
||||||
|
|
||||||
|
|
||||||
|
int dkb_kmod = 0;
|
||||||
|
|
||||||
DIB dkb_dib = { DKB_DEVNUM, 1, dkb_devio, NULL};
|
DIB dkb_dib = { DKB_DEVNUM, 1, dkb_devio, NULL};
|
||||||
|
|
||||||
UNIT dkb_unit[] = {
|
UNIT dkb_unit[] = {
|
||||||
|
{UDATA (&dkb_svc, UNIT_IDLE, 0) },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -57,42 +77,368 @@ MTAB dkb_mod[] = {
|
||||||
DEVICE dkb_dev = {
|
DEVICE dkb_dev = {
|
||||||
"DKB", dkb_unit, NULL, dkb_mod,
|
"DKB", dkb_unit, NULL, dkb_mod,
|
||||||
2, 10, 31, 1, 8, 8,
|
2, 10, 31, 1, 8, 8,
|
||||||
NULL, NULL, NULL,
|
NULL, NULL, dkb_reset,
|
||||||
NULL, NULL, NULL, &dkb_dib, DEV_DEBUG | DEV_DISABLE | DEV_DIS, 0, dev_debug,
|
NULL, NULL, NULL, &dkb_dib, DEV_DEBUG | DEV_DISABLE | DEV_DIS, 0, dev_debug,
|
||||||
NULL, NULL, &dkb_help, NULL, NULL, &dkb_description
|
NULL, NULL, &dkb_help, NULL, NULL, &dkb_description
|
||||||
};
|
};
|
||||||
|
|
||||||
int status;
|
|
||||||
t_stat dkb_devio(uint32 dev, uint64 *data) {
|
t_stat dkb_devio(uint32 dev, uint64 *data) {
|
||||||
/* uint64 res; */
|
UNIT *uptr = &dkb_unit[0];
|
||||||
switch(dev & 3) {
|
switch(dev & 3) {
|
||||||
case CONI:
|
case CONI:
|
||||||
*data = status;
|
*data = (uint64)(uptr->STATUS|uptr->PIA);
|
||||||
sim_debug(DEBUG_CONI, &dkb_dev, "DKB %03o CONI %06o\n", dev, (uint32)*data);
|
sim_debug(DEBUG_CONI, &dkb_dev, "DKB %03o CONI %06o\n", dev, (uint32)*data);
|
||||||
break;
|
break;
|
||||||
case CONO:
|
case CONO:
|
||||||
status = (int)(*data&7);
|
uptr->PIA = (int)(*data&7);
|
||||||
|
if (*data & DONE)
|
||||||
|
uptr->STATUS = 0;
|
||||||
|
clr_interrupt(DKB_DEVNUM);
|
||||||
sim_debug(DEBUG_CONO, &dkb_dev, "DKB %03o CONO %06o\n", dev, (uint32)*data);
|
sim_debug(DEBUG_CONO, &dkb_dev, "DKB %03o CONO %06o\n", dev, (uint32)*data);
|
||||||
break;
|
break;
|
||||||
case DATAI:
|
case DATAI:
|
||||||
|
*data = (uint64)((uptr->LINE << 18) | (uptr->DATA));
|
||||||
|
uptr->STATUS = 0;
|
||||||
|
clr_interrupt(DKB_DEVNUM);
|
||||||
sim_debug(DEBUG_DATAIO, &dkb_dev, "DKB %03o DATAI %06o\n", dev, (uint32)*data);
|
sim_debug(DEBUG_DATAIO, &dkb_dev, "DKB %03o DATAI %06o\n", dev, (uint32)*data);
|
||||||
break;
|
break;
|
||||||
case DATAO:
|
case DATAO:
|
||||||
|
if (*data & 010000) {
|
||||||
|
uptr->STATUS |= SPW;
|
||||||
|
uptr->LINE = (int)(*data & 077);
|
||||||
|
}
|
||||||
sim_debug(DEBUG_DATAIO, &dkb_dev, "DKB %03o DATAO %06o\n", dev, (uint32)*data);
|
sim_debug(DEBUG_DATAIO, &dkb_dev, "DKB %03o DATAO %06o\n", dev, (uint32)*data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int dkb_modifiers (SIM_KEY_EVENT *kev)
|
||||||
|
{
|
||||||
|
if (kev->state == SIM_KEYPRESS_UP) {
|
||||||
|
switch (kev->key) {
|
||||||
|
case SIM_KEY_SHIFT_L:
|
||||||
|
case SIM_KEY_SHIFT_R:
|
||||||
|
case SIM_KEY_CAPS_LOCK:
|
||||||
|
dkb_kmod |= SHFT;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_CTRL_L:
|
||||||
|
case SIM_KEY_CTRL_R:
|
||||||
|
dkb_kmod |= CTRL;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_WIN_L:
|
||||||
|
case SIM_KEY_WIN_R:
|
||||||
|
dkb_kmod |= META;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_ALT_L:
|
||||||
|
case SIM_KEY_ALT_R:
|
||||||
|
dkb_kmod |= TOP;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (kev->state == SIM_KEYPRESS_DOWN) {
|
||||||
|
switch (kev->key) {
|
||||||
|
case SIM_KEY_SHIFT_L:
|
||||||
|
case SIM_KEY_SHIFT_R:
|
||||||
|
case SIM_KEY_CAPS_LOCK:
|
||||||
|
dkb_kmod &= ~SHFT;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_CTRL_L:
|
||||||
|
case SIM_KEY_CTRL_R:
|
||||||
|
dkb_kmod &= ~CTRL;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_WIN_L:
|
||||||
|
case SIM_KEY_WIN_R:
|
||||||
|
dkb_kmod &= ~META;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_ALT_L:
|
||||||
|
case SIM_KEY_ALT_R:
|
||||||
|
dkb_kmod &= ~TOP;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dkb_keys (SIM_KEY_EVENT *kev, UNIT *uptr)
|
||||||
|
{
|
||||||
|
if (kev->state == SIM_KEYPRESS_UP)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (kev->key) {
|
||||||
|
case SIM_KEY_0: /* ok */
|
||||||
|
if ((dkb_kmod & (TOP|SHFT)) == TOP)
|
||||||
|
uptr->DATA = dkb_kmod | 051; /* ) */
|
||||||
|
else
|
||||||
|
uptr->DATA = dkb_kmod | 060;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_1:
|
||||||
|
if ((dkb_kmod & (TOP|SHFT)) == TOP)
|
||||||
|
uptr->DATA = (dkb_kmod | 054) & ~TOP; /* ! */
|
||||||
|
else
|
||||||
|
uptr->DATA = dkb_kmod | 061;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_2:
|
||||||
|
if ((dkb_kmod & (TOP|SHFT)) == TOP)
|
||||||
|
uptr->DATA = (dkb_kmod | 052) & ~TOP; /* Circle Star */
|
||||||
|
else
|
||||||
|
uptr->DATA = dkb_kmod | 062;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_3:
|
||||||
|
if ((dkb_kmod & (TOP|SHFT)) == TOP)
|
||||||
|
uptr->DATA = (dkb_kmod | 022) & ~TOP; /* # */
|
||||||
|
else
|
||||||
|
uptr->DATA = dkb_kmod | 063;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_4:
|
||||||
|
if ((dkb_kmod & (TOP|SHFT)) == TOP)
|
||||||
|
uptr->DATA = (dkb_kmod | 066) & ~TOP; /* $ */
|
||||||
|
else
|
||||||
|
uptr->DATA = dkb_kmod | 064;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_5:
|
||||||
|
if ((dkb_kmod & (TOP|SHFT)) == TOP)
|
||||||
|
uptr->DATA = (dkb_kmod | 067) & ~TOP; /* % */
|
||||||
|
else
|
||||||
|
uptr->DATA = dkb_kmod | 065;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_6:
|
||||||
|
if ((dkb_kmod & (TOP|SHFT)) == TOP)
|
||||||
|
uptr->DATA = (dkb_kmod | 073) & ~TOP; /* ^ */
|
||||||
|
else
|
||||||
|
uptr->DATA = dkb_kmod | 066;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_7:
|
||||||
|
if ((dkb_kmod & (TOP|SHFT)) == TOP)
|
||||||
|
uptr->DATA = (dkb_kmod | 024) & ~TOP; /* & */
|
||||||
|
else
|
||||||
|
uptr->DATA = dkb_kmod | 067;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_8: /* ok */
|
||||||
|
if ((dkb_kmod & (TOP|SHFT)) == TOP)
|
||||||
|
uptr->DATA = (dkb_kmod | 052) & ~TOP; /* * */
|
||||||
|
else
|
||||||
|
uptr->DATA = dkb_kmod | 070;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_9: /* ok */
|
||||||
|
if ((dkb_kmod & (TOP|SHFT)) == TOP)
|
||||||
|
uptr->DATA = dkb_kmod | 050; /* ( */
|
||||||
|
else
|
||||||
|
uptr->DATA = dkb_kmod | 071;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_A:
|
||||||
|
uptr->DATA = dkb_kmod | 001;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_B:
|
||||||
|
uptr->DATA = dkb_kmod | 002;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_C:
|
||||||
|
if (dkb_kmod == (META|TOP|SHFT)) /* Control C */
|
||||||
|
uptr->DATA = dkb_kmod | 043;
|
||||||
|
else
|
||||||
|
uptr->DATA = dkb_kmod | 003;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_D:
|
||||||
|
uptr->DATA = dkb_kmod | 004;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_E:
|
||||||
|
uptr->DATA = dkb_kmod | 005;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_F:
|
||||||
|
uptr->DATA = dkb_kmod | 006;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_G:
|
||||||
|
uptr->DATA = dkb_kmod | 007;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_H:
|
||||||
|
uptr->DATA = dkb_kmod | 010;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_I:
|
||||||
|
uptr->DATA = dkb_kmod | 011;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_J:
|
||||||
|
uptr->DATA = dkb_kmod | 012;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_K:
|
||||||
|
uptr->DATA = dkb_kmod | 013;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_L:
|
||||||
|
uptr->DATA = dkb_kmod | 014;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_M:
|
||||||
|
uptr->DATA = dkb_kmod | 015;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_N:
|
||||||
|
uptr->DATA = dkb_kmod | 016;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_O:
|
||||||
|
uptr->DATA = dkb_kmod | 017;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_P:
|
||||||
|
uptr->DATA = dkb_kmod | 020;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_Q:
|
||||||
|
uptr->DATA = dkb_kmod | 021;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_R:
|
||||||
|
uptr->DATA = dkb_kmod | 022;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_S:
|
||||||
|
uptr->DATA = dkb_kmod | 023;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_T:
|
||||||
|
uptr->DATA = dkb_kmod | 024;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_U:
|
||||||
|
uptr->DATA = dkb_kmod | 025;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_V:
|
||||||
|
uptr->DATA = dkb_kmod | 026;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_W:
|
||||||
|
uptr->DATA = dkb_kmod | 027;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_X:
|
||||||
|
uptr->DATA = dkb_kmod | 030;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_Y:
|
||||||
|
uptr->DATA = dkb_kmod | 031;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_Z:
|
||||||
|
uptr->DATA = dkb_kmod | 032;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_BACKQUOTE: /* ` ~ */
|
||||||
|
if ((dkb_kmod & (TOP|SHFT)) == TOP)
|
||||||
|
uptr->DATA = dkb_kmod | 043;
|
||||||
|
else
|
||||||
|
uptr->DATA = dkb_kmod | 00;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_MINUS: /* - not */
|
||||||
|
uptr->DATA = dkb_kmod | 055;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_EQUALS: /* = + */
|
||||||
|
if ((dkb_kmod & (TOP|SHFT)) == TOP)
|
||||||
|
uptr->DATA = dkb_kmod | 053;
|
||||||
|
else
|
||||||
|
uptr->DATA = (dkb_kmod | 010) & ~TOP;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_LEFT_BRACKET: /* [ { */
|
||||||
|
if ((dkb_kmod & (TOP|SHFT)) == TOP)
|
||||||
|
uptr->DATA = (dkb_kmod | 017) & ~TOP;
|
||||||
|
else
|
||||||
|
uptr->DATA = (dkb_kmod | 050) & ~TOP;;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_RIGHT_BRACKET: /* ] } */
|
||||||
|
if ((dkb_kmod & (TOP|SHFT)) == TOP)
|
||||||
|
uptr->DATA = (dkb_kmod | 020) & ~TOP;
|
||||||
|
else
|
||||||
|
uptr->DATA = (dkb_kmod | 051) & ~TOP;;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_SEMICOLON: /* ; : */
|
||||||
|
if ((dkb_kmod & (TOP|SHFT)) == TOP)
|
||||||
|
uptr->DATA = dkb_kmod | 072 | TOP;
|
||||||
|
else
|
||||||
|
uptr->DATA = dkb_kmod | 073 | TOP;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_SINGLE_QUOTE: /* ok */ /* ' " */
|
||||||
|
if ((dkb_kmod & (TOP|SHFT)) == TOP)
|
||||||
|
uptr->DATA = (dkb_kmod | 031) & ~TOP;
|
||||||
|
else
|
||||||
|
uptr->DATA = (dkb_kmod | 011) & ~TOP;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_BACKSLASH: /* Ok */
|
||||||
|
if ((dkb_kmod & (TOP|SHFT)) == TOP) /* \ | */
|
||||||
|
uptr->DATA = (dkb_kmod | 053) & ~TOP;
|
||||||
|
else if ((dkb_kmod & (TOP|SHFT)) == SHFT)
|
||||||
|
uptr->DATA = (dkb_kmod | 034) & ~TOP;
|
||||||
|
else
|
||||||
|
uptr->DATA = dkb_kmod | 034 | TOP;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_LEFT_BACKSLASH:
|
||||||
|
uptr->DATA = dkb_kmod | 034;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_COMMA: /* ok */
|
||||||
|
if ((dkb_kmod & (TOP|SHFT)) == TOP) /* , < */
|
||||||
|
uptr->DATA = (dkb_kmod | 04) & ~TOP;
|
||||||
|
else
|
||||||
|
uptr->DATA = dkb_kmod | 054 | TOP;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_PERIOD: /* Ok */
|
||||||
|
if ((dkb_kmod & (TOP|SHFT)) == TOP) /* . > */
|
||||||
|
uptr->DATA = (dkb_kmod | 06) & ~TOP;
|
||||||
|
else
|
||||||
|
uptr->DATA = dkb_kmod | 056;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_SLASH: /* Ok */
|
||||||
|
if ((dkb_kmod & (TOP|SHFT)) == TOP) /* / ? */
|
||||||
|
uptr->DATA = (dkb_kmod | 056) & ~TOP;
|
||||||
|
else
|
||||||
|
uptr->DATA = dkb_kmod | 057;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_ESC:
|
||||||
|
uptr->DATA = dkb_kmod | 042;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_BACKSPACE:
|
||||||
|
uptr->DATA = dkb_kmod | 074;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_DELETE:
|
||||||
|
uptr->DATA = dkb_kmod | 044;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_TAB:
|
||||||
|
uptr->DATA = dkb_kmod | 045;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_ENTER:
|
||||||
|
uptr->DATA = dkb_kmod | 033;
|
||||||
|
return 1;
|
||||||
|
case SIM_KEY_SPACE:
|
||||||
|
uptr->DATA = dkb_kmod | 040;
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int dkb_keyboard (SIM_KEY_EVENT *kev)
|
||||||
|
{
|
||||||
|
sim_debug(DEBUG_DETAIL, &dkb_dev, "DKB key %d %o\n", kev->key, kev->state);
|
||||||
|
if (dkb_modifiers (kev))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (dkb_keys (kev, &dkb_unit[0])) {
|
||||||
|
dkb_unit[0].DATA |= VALID;
|
||||||
|
dkb_unit[0].STATUS |= DONE;
|
||||||
|
set_interrupt(DKB_DEVNUM, dkb_unit[0].PIA);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
t_stat dkb_svc( UNIT *uptr)
|
||||||
|
{
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat dkb_reset( DEVICE *dptr)
|
||||||
|
{
|
||||||
|
if ((dkb_dev.flags & DEV_DIS) == 0)
|
||||||
|
vid_display_kb_event_process = dkb_keyboard;
|
||||||
|
dkb_kmod = SHFT|TOP|META|CTRL;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
t_stat dkb_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
t_stat dkb_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
||||||
{
|
{
|
||||||
return SCPE_OK;
|
fprintf (stderr, "This is the keyboard input for the Stanford III display\n");
|
||||||
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *dkb_description (DEVICE *dptr)
|
const char *dkb_description (DEVICE *dptr)
|
||||||
{
|
{
|
||||||
return "Console TTY Line";
|
return "Keyboard scanner for III display devices";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
113
PDP10/ka10_dpk.c
113
PDP10/ka10_dpk.c
|
@ -1,6 +1,6 @@
|
||||||
/* ka10_dpk.c: Systems Concepts DK-10, Datapoint kludge.
|
/* ka10_dpk.c: Systems Concepts DK-10, Datapoint kludge.
|
||||||
|
|
||||||
Copyright (c) 2018-2019, Lars Brinkhoff
|
Copyright (c) 2018-2020, Lars Brinkhoff
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -65,7 +65,8 @@
|
||||||
#define PORT_INPUT 2
|
#define PORT_INPUT 2
|
||||||
|
|
||||||
static t_stat dpk_devio(uint32 dev, uint64 *data);
|
static t_stat dpk_devio(uint32 dev, uint64 *data);
|
||||||
static t_stat dpk_svc (UNIT *uptr);
|
static t_stat dpk_input_svc (UNIT *uptr);
|
||||||
|
static t_stat dpk_output_svc (UNIT *uptr);
|
||||||
static t_stat dpk_reset (DEVICE *dptr);
|
static t_stat dpk_reset (DEVICE *dptr);
|
||||||
static t_stat dpk_attach (UNIT *uptr, CONST char *cptr);
|
static t_stat dpk_attach (UNIT *uptr, CONST char *cptr);
|
||||||
static t_stat dpk_detach (UNIT *uptr);
|
static t_stat dpk_detach (UNIT *uptr);
|
||||||
|
@ -84,9 +85,11 @@ static int dpk_port[16];
|
||||||
static int dpk_ibuf[16];
|
static int dpk_ibuf[16];
|
||||||
static int dpk_ird = 0;
|
static int dpk_ird = 0;
|
||||||
static int dpk_iwr = 0;
|
static int dpk_iwr = 0;
|
||||||
|
static int dpk_port_done = 0;
|
||||||
|
|
||||||
UNIT dpk_unit[] = {
|
UNIT dpk_unit[] = {
|
||||||
{UDATA(dpk_svc, TT_MODE_8B|UNIT_IDLE|UNIT_ATTABLE, 0)}, /* 0 */
|
{UDATA(dpk_input_svc, TT_MODE_8B|UNIT_IDLE|UNIT_ATTABLE, 0)},
|
||||||
|
{UDATA(dpk_output_svc, UNIT_DIS|UNIT_IDLE, 0)},
|
||||||
};
|
};
|
||||||
DIB dpk_dib = {DPK_DEVNUM, 1, &dpk_devio, NULL};
|
DIB dpk_dib = {DPK_DEVNUM, 1, &dpk_devio, NULL};
|
||||||
|
|
||||||
|
@ -107,14 +110,26 @@ MTAB dpk_mod[] = {
|
||||||
|
|
||||||
DEVICE dpk_dev = {
|
DEVICE dpk_dev = {
|
||||||
DPK_NAME, dpk_unit, NULL, dpk_mod,
|
DPK_NAME, dpk_unit, NULL, dpk_mod,
|
||||||
1, 8, 0, 1, 8, 36,
|
2, 8, 0, 1, 8, 36,
|
||||||
NULL, NULL, dpk_reset, NULL, dpk_attach, dpk_detach,
|
NULL, NULL, dpk_reset, NULL, dpk_attach, dpk_detach,
|
||||||
&dpk_dib, DEV_DISABLE | DEV_DIS | DEV_DEBUG, 0, dev_debug,
|
&dpk_dib, DEV_DISABLE | DEV_DIS | DEV_DEBUG, 0, dev_debug,
|
||||||
NULL, NULL, dpk_help, NULL, NULL, dpk_description
|
NULL, NULL, dpk_help, NULL, NULL, dpk_description
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void dpk_set_ospeed (int port, uint64 data)
|
||||||
|
{
|
||||||
|
static const char *map[] =
|
||||||
|
{ "134", "600", "110", "150", "300", "1200", "2400", "4800" };
|
||||||
|
static const char *speed;
|
||||||
|
speed = map[(data & DPK_SPEED) >> 9];
|
||||||
|
sim_debug(DEBUG_CMD, &dpk_dev, "Set port %d output speed %s\n",
|
||||||
|
port, speed);
|
||||||
|
tmxr_set_line_speed(&dpk_ldsc[port], speed);
|
||||||
|
}
|
||||||
|
|
||||||
static t_stat dpk_devio(uint32 dev, uint64 *data)
|
static t_stat dpk_devio(uint32 dev, uint64 *data)
|
||||||
{
|
{
|
||||||
|
static int scan = 0;
|
||||||
DEVICE *dptr = &dpk_dev;
|
DEVICE *dptr = &dpk_dev;
|
||||||
int port;
|
int port;
|
||||||
|
|
||||||
|
@ -138,22 +153,27 @@ static t_stat dpk_devio(uint32 dev, uint64 *data)
|
||||||
break;
|
break;
|
||||||
case DPK_OSTART:
|
case DPK_OSTART:
|
||||||
dpk_port[port] |= PORT_OUTPUT;
|
dpk_port[port] |= PORT_OUTPUT;
|
||||||
|
dpk_port_done &= ~(1 << port);
|
||||||
|
if (dpk_port_done == 0)
|
||||||
dpk_status &= ~DPK_ODONE;
|
dpk_status &= ~DPK_ODONE;
|
||||||
|
sim_activate_abs (&dpk_unit[1], 0);
|
||||||
break;
|
break;
|
||||||
case DPK_ISTOP:
|
case DPK_ISTOP:
|
||||||
dpk_port[port] &= ~PORT_INPUT;
|
dpk_port[port] &= ~PORT_INPUT;
|
||||||
break;
|
break;
|
||||||
case DPK_ISTART:
|
case DPK_ISTART:
|
||||||
dpk_port[port] |= PORT_OUTPUT;
|
dpk_port[port] |= PORT_INPUT;
|
||||||
break;
|
break;
|
||||||
case DPK_OSTOP:
|
case DPK_OSTOP:
|
||||||
dpk_port[port] &= ~PORT_OUTPUT;
|
dpk_port[port] &= ~PORT_OUTPUT;
|
||||||
|
dpk_port_done &= ~(1 << port);
|
||||||
|
if (dpk_port_done == 0)
|
||||||
dpk_status &= ~DPK_ODONE;
|
dpk_status &= ~DPK_ODONE;
|
||||||
break;
|
break;
|
||||||
case DPK_OSPEED:
|
case DPK_OSPEED:
|
||||||
sim_debug(DEBUG_CMD, &dpk_dev, "Set port %d output speed %lld\n",
|
dpk_set_ospeed (port, *data);
|
||||||
port, (*data & DPK_SPEED) >> 9);
|
|
||||||
dpk_port[port] |= PORT_OUTPUT;
|
dpk_port[port] |= PORT_OUTPUT;
|
||||||
|
sim_activate_abs (&dpk_unit[1], 0);
|
||||||
break;
|
break;
|
||||||
case DPK_ISPEED_STOP:
|
case DPK_ISPEED_STOP:
|
||||||
dpk_port[port] &= ~PORT_INPUT;
|
dpk_port[port] &= ~PORT_INPUT;
|
||||||
|
@ -173,13 +193,20 @@ static t_stat dpk_devio(uint32 dev, uint64 *data)
|
||||||
dpk_status |= *data & DPK_PIA;
|
dpk_status |= *data & DPK_PIA;
|
||||||
break;
|
break;
|
||||||
case CONI|4:
|
case CONI|4:
|
||||||
|
dpk_status &= ~DPK_OLINE;
|
||||||
|
for (port = 0; port < DPK_LINES; port++) {
|
||||||
|
scan = (scan + 1) & 017;
|
||||||
|
if (dpk_port_done & (1 << scan)) {
|
||||||
|
dpk_status |= scan << 18;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
*data = dpk_status & DPK_CONI_BITS;
|
*data = dpk_status & DPK_CONI_BITS;
|
||||||
sim_debug(DEBUG_CONI, &dpk_dev, "%07llo\n", *data);
|
sim_debug(DEBUG_CONI, &dpk_dev, "%07llo\n", *data);
|
||||||
break;
|
break;
|
||||||
case DATAO|4:
|
case DATAO|4:
|
||||||
dpk_base = *data & 03777777;
|
dpk_base = *data & 03777777;
|
||||||
if (*data & DPK_IEN)
|
dpk_ien = ((*data & DPK_IEN) != 0);
|
||||||
dpk_ien = 1;
|
|
||||||
sim_debug(DEBUG_DATAIO, &dpk_dev, "DATAO %06llo\n", *data);
|
sim_debug(DEBUG_DATAIO, &dpk_dev, "DATAO %06llo\n", *data);
|
||||||
break;
|
break;
|
||||||
case DATAI|4:
|
case DATAI|4:
|
||||||
|
@ -230,73 +257,60 @@ static int ildb (uint64 *pointer)
|
||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dpk_output (int port, TMLN *lp)
|
static void dpk_output (int port, TMLN *lp)
|
||||||
{
|
{
|
||||||
uint64 count;
|
uint64 count;
|
||||||
int ch;
|
int ch;
|
||||||
|
|
||||||
if ((dpk_port[port] & PORT_OUTPUT) == 0)
|
if ((dpk_port[port] & PORT_OUTPUT) == 0)
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
|
if (tmxr_txdone_ln (lp) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
if (M[dpk_base + 2*port] == 0777777777777LL) {
|
if (M[dpk_base + 2*port] == 0777777777777LL) {
|
||||||
dpk_port[port] &= ~PORT_OUTPUT;
|
dpk_port[port] &= ~PORT_OUTPUT;
|
||||||
dpk_status &= ~DPK_OLINE;
|
|
||||||
dpk_status |= port << 18;
|
|
||||||
dpk_status |= DPK_ODONE;
|
dpk_status |= DPK_ODONE;
|
||||||
|
dpk_port_done |= 1 << port;
|
||||||
if (dpk_ien)
|
if (dpk_ien)
|
||||||
set_interrupt(DPK_DEVNUM, dpk_status & DPK_PIA);
|
set_interrupt(DPK_DEVNUM, dpk_status & DPK_PIA);
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ch = ildb (&M[dpk_base + 2*port + 1]);
|
ch = ildb (&M[dpk_base + 2*port + 1]);
|
||||||
if (lp->conn) {
|
|
||||||
ch = sim_tt_outcvt(ch & 0377, TT_GET_MODE (dpk_unit[0].flags));
|
ch = sim_tt_outcvt(ch & 0377, TT_GET_MODE (dpk_unit[0].flags));
|
||||||
tmxr_putc_ln (lp, ch);
|
tmxr_putc_ln (lp, ch);
|
||||||
}
|
|
||||||
|
|
||||||
count = M[dpk_base + 2*port] - 1;
|
count = M[dpk_base + 2*port] - 1;
|
||||||
M[dpk_base + 2*port] = count & 0777777777777LL;
|
M[dpk_base + 2*port] = count & 0777777777777LL;
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static t_stat dpk_svc (UNIT *uptr)
|
static t_stat dpk_input_svc (UNIT *uptr)
|
||||||
{
|
{
|
||||||
static int scan = 0;
|
static int scan = 0;
|
||||||
|
int32 ch;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* 16 ports at 4800 baud, rounded up. */
|
sim_clock_coschedule (uptr, 1000);
|
||||||
sim_clock_coschedule (uptr, 200);
|
|
||||||
|
|
||||||
i = tmxr_poll_conn (&dpk_desc);
|
i = tmxr_poll_conn (&dpk_desc);
|
||||||
if (i >= 0) {
|
if (i >= 0) {
|
||||||
dpk_ldsc[i].conn = 1;
|
|
||||||
dpk_ldsc[i].rcve = 1;
|
dpk_ldsc[i].rcve = 1;
|
||||||
dpk_ldsc[i].xmte = 1;
|
dpk_ldsc[i].xmte = 1;
|
||||||
sim_debug(DEBUG_CMD, &dpk_dev, "Connect %d\n", i);
|
sim_debug(DEBUG_CMD, &dpk_dev, "Connect %d\n", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
tmxr_poll_rx (&dpk_desc);
|
tmxr_poll_rx (&dpk_desc);
|
||||||
tmxr_poll_tx (&dpk_desc);
|
|
||||||
|
|
||||||
for (i = 0; i < DPK_LINES; i++) {
|
for (i = 0; i < DPK_LINES; i++) {
|
||||||
/* Round robin scan 16 lines. */
|
/* Round robin scan 16 lines. */
|
||||||
scan = (scan + 1) & 017;
|
scan = (scan + 1) & 017;
|
||||||
|
|
||||||
/* 1 means the line became ready since the last check. Ignore
|
ch = tmxr_getc_ln(&dpk_ldsc[scan]);
|
||||||
-1 which means "still ready". */
|
if (ch & TMXR_VALID) {
|
||||||
if (tmxr_txdone_ln (&dpk_ldsc[scan])) {
|
|
||||||
if (dpk_output (scan, &dpk_ldsc[scan]))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dpk_ldsc[scan].conn)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (tmxr_input_pending_ln (&dpk_ldsc[scan])) {
|
|
||||||
if ((dpk_port[scan] & PORT_INPUT) == 0)
|
if ((dpk_port[scan] & PORT_INPUT) == 0)
|
||||||
continue;
|
continue;
|
||||||
dpk_ibuf[dpk_iwr++] = (scan << 18) | (tmxr_getc_ln (&dpk_ldsc[scan]) & 0177);
|
dpk_ibuf[dpk_iwr++] = (scan << 18) | (ch & 0177);
|
||||||
dpk_iwr &= 15;
|
dpk_iwr &= 15;
|
||||||
dpk_status |= DPK_IDONE;
|
dpk_status |= DPK_IDONE;
|
||||||
if (dpk_ien)
|
if (dpk_ien)
|
||||||
|
@ -308,26 +322,42 @@ static t_stat dpk_svc (UNIT *uptr)
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static t_stat dpk_output_svc (UNIT *uptr)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < DPK_LINES; i++) {
|
||||||
|
dpk_output (i, &dpk_ldsc[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
tmxr_poll_tx (&dpk_desc);
|
||||||
|
sim_activate_after (uptr, 1000000);
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static t_stat dpk_reset (DEVICE *dptr)
|
static t_stat dpk_reset (DEVICE *dptr)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
sim_debug(DEBUG_CMD, &dpk_dev, "Reset\n");
|
sim_debug(DEBUG_CMD, &dpk_dev, "Reset\n");
|
||||||
if (dpk_unit->flags & UNIT_ATT)
|
if (dpk_unit->flags & UNIT_ATT)
|
||||||
sim_activate (dpk_unit, tmxr_poll);
|
sim_activate (&dpk_unit[0], tmxr_poll);
|
||||||
else
|
else {
|
||||||
sim_cancel (dpk_unit);
|
sim_cancel (&dpk_unit[0]);
|
||||||
|
sim_cancel (&dpk_unit[1]);
|
||||||
|
}
|
||||||
|
|
||||||
dpk_ien = 0;
|
dpk_ien = 0;
|
||||||
dpk_base = 0;
|
dpk_base = 0;
|
||||||
dpk_status = 0;
|
dpk_status = 0;
|
||||||
dpk_ird = dpk_iwr = 0;
|
dpk_ird = dpk_iwr = 0;
|
||||||
memset (dpk_port, 0, sizeof dpk_port);
|
memset (dpk_port, 0, sizeof dpk_port);
|
||||||
|
dpk_port_done = 0;
|
||||||
clr_interrupt(DPK_DEVNUM);
|
clr_interrupt(DPK_DEVNUM);
|
||||||
|
|
||||||
for (i = 0; i < DPK_LINES; i++) {
|
for (i = 0; i < DPK_LINES; i++) {
|
||||||
tmxr_set_line_unit (&dpk_desc, i, dpk_unit);
|
tmxr_set_line_unit (&dpk_desc, i, &dpk_unit[0]);
|
||||||
tmxr_set_line_output_unit (&dpk_desc, i, dpk_unit);
|
tmxr_set_line_output_unit (&dpk_desc, i, &dpk_unit[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
@ -358,7 +388,8 @@ static t_stat dpk_detach (UNIT *uptr)
|
||||||
dpk_ldsc[i].xmte = 0;
|
dpk_ldsc[i].xmte = 0;
|
||||||
}
|
}
|
||||||
dpk_status = 0;
|
dpk_status = 0;
|
||||||
sim_cancel (uptr);
|
sim_cancel (&dpk_unit[0]);
|
||||||
|
sim_cancel (&dpk_unit[1]);
|
||||||
|
|
||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
|
|
669
PDP10/ka10_iii.c
Normal file
669
PDP10/ka10_iii.c
Normal file
|
@ -0,0 +1,669 @@
|
||||||
|
/* ka10_iii.c: Triple III display processor.
|
||||||
|
|
||||||
|
Copyright (c) 2019-2020, Richard Cornwell
|
||||||
|
|
||||||
|
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
|
||||||
|
RICHARD CORNWELL 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.
|
||||||
|
|
||||||
|
Except as contained in this notice, the name of Richard Cornwell shall not be
|
||||||
|
used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
|
in this Software without prior written authorization from Richard Cornwell
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "kx10_defs.h"
|
||||||
|
#ifndef NUM_DEVS_III
|
||||||
|
#define NUM_DEVS_III 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if NUM_DEVS_III > 0
|
||||||
|
#include "display/display.h"
|
||||||
|
#include "display/iii.h"
|
||||||
|
|
||||||
|
#define III_DEVNUM 0430
|
||||||
|
|
||||||
|
#define STATUS u3
|
||||||
|
#define MAR u4
|
||||||
|
#define PIA u5
|
||||||
|
#define POS u6
|
||||||
|
|
||||||
|
/* CONO Bits */
|
||||||
|
#define SET_PIA 000000010 /* Set if this bit is zero */
|
||||||
|
#define STOP 000000020 /* Stop processor after instruction */
|
||||||
|
#define CONT 000000040 /* Start execution at address */
|
||||||
|
#define F 000000100 /* Clear flags */
|
||||||
|
#define SET_MSK 000360000 /* Set mask */
|
||||||
|
#define RST_MSK 007400000 /* Reset mask */
|
||||||
|
|
||||||
|
/* CONI Bits */
|
||||||
|
#define PIA_MSK 000000007
|
||||||
|
#define INST_HLT 000000010 /* 32 - Halt instruction */
|
||||||
|
#define WRAP_ENB 000000020 /* 31 - Wrap around mask */
|
||||||
|
#define EDGE_ENB 000000040 /* 30 - Edge interrupt mask */
|
||||||
|
#define LIGH_ENB 000000100 /* 29 - Light pen enable mask */
|
||||||
|
#define CLK_STOP 000000200 /* 28 - Clock stop */
|
||||||
|
/* 27 - Not used */
|
||||||
|
#define CLK_BIT 000001000 /* 26 - Clock */
|
||||||
|
#define NXM_BIT 000002000 /* 25 - Non-existent memory */
|
||||||
|
#define IRQ_BIT 000004000 /* 24 - Interrupt pending */
|
||||||
|
#define DATAO_LK 000010000 /* 23 - PDP10 gave DATAO when running */
|
||||||
|
#define CONT_BIT 000020000 /* 22 - Control bit */
|
||||||
|
#define LIGHT_FLG 000040000 /* 21 - Light pen flag */
|
||||||
|
#define WRAP_FLG 000100000 /* 20 - Wrap around flag */
|
||||||
|
#define EDGE_FLG 000200000 /* 19 - Edge overflow */
|
||||||
|
#define HLT_FLG 000400000 /* 18 - Not running */
|
||||||
|
|
||||||
|
#define WRAP_MSK 00001
|
||||||
|
#define EDGE_MSK 00002
|
||||||
|
#define LIGH_MSK 00004
|
||||||
|
#define HLT_MSK 00010
|
||||||
|
#define WRP_FBIT 00020
|
||||||
|
#define EDG_FBIT 00040
|
||||||
|
#define LIT_FBIT 00100
|
||||||
|
#define CTL_FBIT 00200
|
||||||
|
#define HLT_FBIT 00400
|
||||||
|
#define NXM_FLG 01000
|
||||||
|
#define DATA_FLG 02000
|
||||||
|
#define RUN_FLG 04000
|
||||||
|
|
||||||
|
#define TSS_INST 012 /* Test */
|
||||||
|
#define LVW_INST 006 /* Long Vector */
|
||||||
|
#define SVW_INST 002 /* Short vector */
|
||||||
|
#define JMP_INST 000 /* Jump or Halt */
|
||||||
|
#define JSR_INST 004 /* JSR(1) or JMS(0), SAVE(3) */
|
||||||
|
#define RES_INST 014 /* Restore */
|
||||||
|
#define SEL_INST 010 /* Select instruction */
|
||||||
|
|
||||||
|
#define POS_X 01777400000
|
||||||
|
#define POS_Y 00000377700
|
||||||
|
#define CBRT 00000000070 /* Current brightness */
|
||||||
|
#define CSIZE 00000000007 /* Current char size */
|
||||||
|
#define POS_X_V 16
|
||||||
|
#define POS_Y_V 6
|
||||||
|
#define CBRT_V 3
|
||||||
|
#define CSIZE_V 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Character map.
|
||||||
|
* M(x,y) moves pointer to x,y.
|
||||||
|
* V(x,y) draws a vector between current pointer and x,y.
|
||||||
|
* All characters start at 0,6 and end at 8,6.
|
||||||
|
* In the map there are up to 18 points per character. For a character a M(0,0) indicates
|
||||||
|
* that drawing is done and a move to 8,6 should be done.
|
||||||
|
*/
|
||||||
|
#define M(x,y) (x << 4)|y|0000
|
||||||
|
#define V(x,y) (x << 4)|y|0200
|
||||||
|
|
||||||
|
uint8 map[128][18] = {
|
||||||
|
/* Blank */ { 0 },
|
||||||
|
/* Down */ { M(0,9), V(3,6), V(3,14), M(3,6), V(6,9) },
|
||||||
|
/* Alpha */ { M(6,6), V(3,9), V(1,9), V(0,8), V(0,7), V(1,6), V(3,6), V(6,9) },
|
||||||
|
/* Beta */ { V(2,8), V(2,13), V(3,14), V(5,14), V(6,13), V(6,12), V(5,11),
|
||||||
|
V(2,11), M(5,11), V(6,10), V(6,9), V(5,8), V(3,8), V(2,9) },
|
||||||
|
/* ^ */ { M(0,8), V(3,11), V(6,8) },
|
||||||
|
/* Not */ { M(0,10), V(6,10), V(6,7) },
|
||||||
|
/* Epsilon */ { M(3,9), V(2,10), V(1,10), V(0,9), V(0,7), V(1,6), V(2,6), V(3,7),
|
||||||
|
M(2,8), V(0,8) },
|
||||||
|
/* Pi */ { M(0,10), V(6,10), M(4,10), V(4,6), M(2,6), V(2,10) },
|
||||||
|
/* Lambda */ { V(3,9), M(0,11), V(1,11), V(6,6) },
|
||||||
|
/* ?? */ { M(0,11), V(1,12), V(2,12), V(5,9), V(5,7), V(4,6), V(3,6), V(2,7),
|
||||||
|
V(2,8), V(6,12) },
|
||||||
|
/* Delta */ { M(2,10), V(1,10), V(0,9), V(0,7), V(1,6), V(3,6), V(4,7), V(4,9),
|
||||||
|
V(3,10), V(2,10), V(2,12), V(4,12) },
|
||||||
|
/* Integ */ { M(0,7), V(1,6), V(2,6), V(3,7), V(3,12), V(4,13), V(5,13), V(6,12) },
|
||||||
|
/* PlusMinus */{ M(0,9), V(4,9), M(2,11), V(2,7), M(0,7), V(4,7) },
|
||||||
|
/* Circross */ { M(0,8), V(0,7), V(1,6), V(3,6), V(4,7), V(4,9), V(3,10), V(1,10),
|
||||||
|
V(0,9), V(0,8), V(4,8), M(2,10), V(2,6) },
|
||||||
|
/* Sigma */ { M(0,10), V(1,9), V(2,9), V(4,11), V(5,11), V(6,10), V(5,9), V(4,9),
|
||||||
|
V(2,11), V(1,11), V(0,10) },
|
||||||
|
/* Union */ { M(4,8), V(3,9), V(1,9), V(0,8), V(0,7), V(1,6), V(3,6), V(4,7),
|
||||||
|
V(4,10), V(2,12), V(1,12) },
|
||||||
|
/* Intersect */{ M(3,11), V(1,11), V(0,10), V(0,8), V(1,7), V(3,7) },
|
||||||
|
/* Cap */ { M(0,11), V(2,11), V(3,10), V(3,8), V(2,7), V(0,7) },
|
||||||
|
/* Cup */ { M(0,7), V(0,9), V(1,10), V(3,10), V(4,9), V(4,7) },
|
||||||
|
/* A */ { M(0,10), V(0,8), V(1,7), V(3,7), V(4,8), V(4,10) },
|
||||||
|
/* E */ { M(0,13), V(0,8), V(2,6), V(4,6), V(6,8), V(6,13), M(0,10), V(6,10) },
|
||||||
|
/* cx */ { V(6,6), V(6,14), V(0,14), M(2,10), V(6,10) },
|
||||||
|
{ V(4,10), M(0,10), V(4,6), M(3,6), V(1,6), V(0,7), V(0,9), V(1,10),
|
||||||
|
V(3,10), V(4,9), V(4,7), V(3,6) },
|
||||||
|
/* Dbl arrow */{ M(2,8), V(0,10), V(2,12), M(0,10), V(6,10), M(4,12), V(6,10),
|
||||||
|
V(4,8)},
|
||||||
|
/* Under */ { M(0,5), V(6,5) },
|
||||||
|
{ M(0,10), V(6,10), M(3,13), V(6,10), V(3,7) },
|
||||||
|
{ M(0,12), V(2,14), V(4,12), V(6,14) },
|
||||||
|
{ V(6,12), M(0,10), V(6,10), M(0,8), V(6,8) },
|
||||||
|
{ V(3,6), M(3,7), V(0,10), V(3,13) },
|
||||||
|
{ V(3,6), M(0,7), V(3,10), V(0,13) },
|
||||||
|
{ M(0,7), V(6,7), M(6,9), V(0,9), M(0,11), V(6,11) },
|
||||||
|
{ M(0,11), V(3,8), V(6,11) },
|
||||||
|
/* Blank */ { 0, },
|
||||||
|
/* ! */ { M(2,6), V(2,7), M(2,8), V(2,13) },
|
||||||
|
/* " */ { M(2,12), V(2,14), M(4,14), V(4,12) },
|
||||||
|
/* # */ { M(2,7), V(2,13), M(4,13), V(4,7), M(6,9), V(0,9), M(0,11), V(6,11) },
|
||||||
|
/* $ */ { M(0,8), V(2,6), V(4,6), V(6,8), V(4,10), V(2,10), V(0,12), V(2,14),
|
||||||
|
V(4,14), V(6,12), M(4,14), V(4,6), M(2,6), V(2,14) },
|
||||||
|
/* % */ { V(6,12), V(1,12), V(0,11), V(0,10), V(1,9), V(2,9), V(3,10), V(3,11),
|
||||||
|
V(2,12), M(4,9), V(3,8), V(3,7), V(4,6), V(5,6), V(6,7), V(6,8),
|
||||||
|
V(5,9), V(4,9) },
|
||||||
|
/* & */ { M(6,6), V(1,11), V(1,13), V(2,14), V(3,14), V(4,13), V(0,9), V(0,7),
|
||||||
|
V(1,6), V(3,6), V(5,8) },
|
||||||
|
/* ' */ { M(2,12), V(4,14) },
|
||||||
|
/* ( */ { M(2,6), V(0,8), V(0,12), V(2,14) },
|
||||||
|
/* ) */ { V(2,8), V(2,12), V(0,14) },
|
||||||
|
/* * */ { M(1,8), V(5,12), M(3,13), V(3,7), M(5,8), V(1,12), M(0,10),
|
||||||
|
V(6,10) },
|
||||||
|
/* + */ { M(2,7), V(2,11), M(0,9), V(4,9) },
|
||||||
|
/* , */ { M(0,7), V(1,6), V(1,5), V(0,4) },
|
||||||
|
/* - */ { M(0,9), V(4,9) },
|
||||||
|
/* . */ { M(2,6), V(3,6), V(3,7), V(2,7), V(2,6) },
|
||||||
|
/* / */ { V(6,12) },
|
||||||
|
/* 0 */ { M(0,7), V(6,13), M(6,12), V(4,14), V(2,14), V(0,12), V(0,8), V(2,6),
|
||||||
|
V(4,6), V(6,8), V(6,12) },
|
||||||
|
/* 1 */ { M(1,12), V(3,14), V(3,6) },
|
||||||
|
/* 2 */ { M(0,13), V(1,14), V(4,14), V(6,12), V(6,11), V(5,10), V(2,10),
|
||||||
|
V(0,8), V(0,6), V(6,6) },
|
||||||
|
/* 3 */ { M(0,14), V(6,14), V(6,12), V(4,10), V(5,10), V(6,9), V(6,7), V(5,6),
|
||||||
|
V(0,6) },
|
||||||
|
/* 4 */ { M(5,6), V(5,14), V(0,9), V(6,9) },
|
||||||
|
/* 5 */ { M(0,7), V(1,6), V(4,6), V(6,8), V(6,9), V(5,10), V(1,10), V(0,9),
|
||||||
|
V(0,14), V(6,14) },
|
||||||
|
/* 6 */ { M(0,9), V(1,10), V(5,10), V(6,9), V(6,7), V(5,6), V(1,6), V(0,7),
|
||||||
|
V(0,10), V(4,14) },
|
||||||
|
/* 7 */ { V(6,12), V(6,14), V(0,14) },
|
||||||
|
/* 8 */ { M(1,10), V(0,9), V(0,7), V(1,6), V(5,6), V(6,7), V(6,9), V(5,10),
|
||||||
|
V(6,11), V(6,13), V(5,14), V(1,14), V(0,13), V(0,11), V(1,10),
|
||||||
|
V(5,10) },
|
||||||
|
/* 9 */ { M(2,6), V(6,10), V(6,13), V(5,14), V(1,14), V(0,13), V(0,11),
|
||||||
|
V(1,10), V(5,10), V(6,11) },
|
||||||
|
/* : */ { M(2,6), V(3,6), V(3,7), V(2,7), V(2,6), M(2,10), V(3,10), V(3,11),
|
||||||
|
V(2,11), V(2,10) },
|
||||||
|
/* ; */ { M(2,7), V(3,6), V(3,5), V(2,4), M(2,10), V(3,10), V(3,11), V(2,11),
|
||||||
|
V(2,10) },
|
||||||
|
/* < */ { M(3,7), V(0,10), V(3,13) },
|
||||||
|
/* = */ { M(0,8), V(6,8), M(6,10), V(0,10) },
|
||||||
|
/* > */ { M(0,7), V(3,10), V(0,13) },
|
||||||
|
/* ? */ { M(0,13), V(1,14), V(2,13), V(2,12), V(1,11), V(1,8), M(1,7),
|
||||||
|
V(1,6) },
|
||||||
|
/* @ */ { M(1,6), V(0,7), V(0,11), V(1,12), V(5,12), V(6,11), V(6,8), V(5,7),
|
||||||
|
V(4,8), V(4,11), M(4,10), V(3,11), V(2,11), V(1,10), V(1,9), V(2,8),
|
||||||
|
V(3,8), V(4,9) },
|
||||||
|
/* A */ { V(0,12), V(2,14), V(4,14), V(6,12), V(6,9), V(0,9), V(6,9), V(6,6) },
|
||||||
|
/* B */ { V(0,14), V(5,14), V(6,13), V(6,11), V(5,10), V(0,10), V(5,10),
|
||||||
|
V(6,9), V(6,7), V(5,6), V(0,6) },
|
||||||
|
/* C */ { M(6,13), V(5,14), V(2,14), V(0,12), V(0,8), V(2,6), V(5,6), V(6,7) },
|
||||||
|
/* D */ { V(0,14), V(4,14), V(6,12), V(6,8), V(4,6), V(0,6) },
|
||||||
|
/* E */ { M(6,6), V(0,6), V(0,10), V(4,10), V(0,10), V(0,14), V(6,14) },
|
||||||
|
/* F */ { V(0,10), V(4,10), V(0,10), V(0,14), V(6,14) },
|
||||||
|
/* G */ { M(6,13), V(5,14), V(2,14), V(0,12), V(0,8), V(2,6), V(4,6), V(6,8),
|
||||||
|
V(6,10), V(4,10) },
|
||||||
|
/* H */ { V(0,14), V(0,10), V(6,10), V(6,14), V(6,6) },
|
||||||
|
/* I */ { M(1,6), V(5,6), V(3,6), V(3,14), V(1,14), V(5,14) },
|
||||||
|
/* J */ { M(1,9), V(1,7), V(2,6), V(3,6), V(4,7), V(4,14), V(2,14), V(6,14) },
|
||||||
|
/* K */ { V(0,14), V(0,8), V(6,14), V(2,10), V(6,6) },
|
||||||
|
/* L */ { M(0,14), V(0,6), V(6,6) },
|
||||||
|
/* M */ { V(0,14), V(3,11), V(6,14), V(6,6) },
|
||||||
|
/* N */ { V(0,14), V(0,13), V(6,7), V(6,6), V(6,14) },
|
||||||
|
/* O */ { M(0,8), V(0,12), V(2,14), V(4,14), V(6,12), V(6,8), V(4,6), V(2,6),
|
||||||
|
V(0,8) },
|
||||||
|
/* P */ { V(0,14), V(5,14), V(6,13), V(6,11), V(5,10), V(0,10) },
|
||||||
|
/* Q */ { M(0,8), V(0,12), V(2,14), V(4,14), V(6,12), V(6,8), V(4,6), V(2,6),
|
||||||
|
V(0,8), M(3,9), V(6,6) },
|
||||||
|
/* R */ { V(0,14), V(5,14), V(6,13), V(6,11), V(5,10), V(0,10), V(2,10),
|
||||||
|
V(6,6) },
|
||||||
|
/* S */ { M(0,8), V(2,6), V(4,6), V(6,8), V(4,10), V(2,10), V(0,12), V(2,14),
|
||||||
|
V(4,14), V(6,12) },
|
||||||
|
/* T */ { M(3,6), V(3,14), V(0,14), V(6,14) },
|
||||||
|
/* U */ { M(0,14), V(0,7), V(1,6), V(5,6), V(6,7), V(6,14) },
|
||||||
|
/* V */ { M(0,14), V(0,9), V(3,6), V(6,9), V(6,14) },
|
||||||
|
/* W */ { M(0,14), V(0,6), V(3,9), V(6,6), V(6,14) },
|
||||||
|
/* X */ { V(0,7), V(6,13), V(6,14), M(0,14), V(0,13), V(6,7), V(6,6) },
|
||||||
|
/* Y */ { M(0,14), V(3,11), V(6,14), V(3,11), V(3,6) },
|
||||||
|
/* Z */ { M(0,14), V(6,14), V(6,13), V(0,7), V(0,6), V(6,6) },
|
||||||
|
/* [ */ { M(3,5), V(0,5), V(0,15), V(3,15) },
|
||||||
|
/* \ */ { M(0,12), V(6,6) },
|
||||||
|
/* ] */ { M(0,5), V(3,5), V(3,15), V(0,15) },
|
||||||
|
/* up arrow */ { M(0,11), V(3,14), V(6,11), M(3,14), V(3,6) },
|
||||||
|
/* left arrow*/{ M(3,7), V(0,10), V(3,13), M(0,10), V(6,10) },
|
||||||
|
/* ` */ { M(2,14), V(4,12) },
|
||||||
|
/* a */ { M(0,9), V(1,10), V(3,10), V(4,9), V(4,6), M(4,8), V(3,9), V(1,9),
|
||||||
|
V(0,8), V(0,7), V(1,6), V(3,6), V(4,7) },
|
||||||
|
/* b */ { V(0,13), M(0,9), V(1,10), V(3,10), V(4,9), V(4,7), V(3,6), V(1,6),
|
||||||
|
V(0,7) },
|
||||||
|
/* c */ { M(4,9), V(3,10), V(1,10), V(0,9), V(0,7), V(1,6), V(3,6), V(4,7) },
|
||||||
|
/* d */ { M(0,7), V(0,9), V(1,10), V(3,10), V(4,9), V(4,7), V(3,6), V(1,6),
|
||||||
|
V(0,7), M(4,6), V(4,13) },
|
||||||
|
/* e */ { M(4,7), V(3,6), V(1,6), V(0,7), V(0,9), V(1,10), V(3,10), V(4,9),
|
||||||
|
V(4,8), V(0,8) },
|
||||||
|
/* f */ { M(2,6), V(2,12), V(3,13), V(4,13), V(5,12), M(0,11), V(4,11) },
|
||||||
|
/* g */ { M(4,9), V(3,10), V(1,10), V(0,9), V(0,7), V(1,6), V(3,6), V(4,7),
|
||||||
|
M(4,10), V(4,5), V(3,4), V(1,4), V(0,5) },
|
||||||
|
/* h */ { V(0,13), M(0,9), V(1,10), V(3,10), V(4,9), V(4,6) },
|
||||||
|
/* i */ { M(3,12), V(3,11), M(3,10), V(3,7), V(4,6), V(5,6) },
|
||||||
|
/* k */ { M(3,12), V(3,11), M(3,10), V(3,5), V(2,4), V(1,3) },
|
||||||
|
/* j */ { V(0,13), M(0,8), V(2,10), M(0,8), V(2,6) },
|
||||||
|
/* l */ { M(2,6), V(2,13) },
|
||||||
|
/* m */ { V(0,10), M(0,9), V(1,10), V(2,10), V(3,9), V(3,6), M(3,9), V(4,10),
|
||||||
|
V(5,10), V(6,9), V(6,6) },
|
||||||
|
/* n */ { V(0,10), M(0,9), V(1,10), V(2,10), V(3,9), V(3,6) },
|
||||||
|
/* o */ { M(0,7), V(0,9), V(1,10), V(3,10), V(4,9), V(4,7), V(3,6), V(1,6),
|
||||||
|
V(0,7) },
|
||||||
|
/* p */ { M(0,4), V(0,10), M(0,9), V(1,10), V(3,10), V(4,9), V(4,7), V(3,6),
|
||||||
|
V(1,6), V(0,7) },
|
||||||
|
/* q */ { M(4,9), V(3,10), V(1,10), V(0,9), V(0,7), V(1,6), V(3,6), V(4,7),
|
||||||
|
M(4,10), V(4,4) },
|
||||||
|
/* r */ { V(0,10), M(0,9), V(1,10), V(3,10), V(4,9) },
|
||||||
|
/* s */ { M(0,7), V(1,6), V(3,6), V(4,7), V(3,8), V(1,8), V(0,9), V(1,10),
|
||||||
|
V(3,10), V(4,9) },
|
||||||
|
/* t */ { M(2,13), V(2,7), V(3,6), V(4,6), V(5,7), M(1,11), V(3,11) },
|
||||||
|
/* u */ { M(0,10), V(0,7), V(1,6), V(3,6), V(4,7), V(4,10), V(4,6) },
|
||||||
|
/* v */ { M(0,9), V(3,6), V(6,9) },
|
||||||
|
/* w */ { M(0,10), V(0,6), V(2,8), V(4,6), V(4,10) },
|
||||||
|
/* x */ { V(4,10), M(0,10), V(4,6) },
|
||||||
|
/* y */ { M(0,9), V(3,6), M(6,9), V(1,4), V(0,4) },
|
||||||
|
/* z */ { M(0,10), V(4,10), V(0,6), V(4,6) },
|
||||||
|
/* { */ { M(3,15), V(2,14), V(2,12), V(0,10), V(2,8), V(2,6), V(3,5) },
|
||||||
|
/* | */ { M(2,4), V(2,14) },
|
||||||
|
/* diamon */ { M(3,6), V(0,9), V(3,12), V(6,9), V(3,6) },
|
||||||
|
/* } */ { M(0,15), V(1,14), V(1,12), V(3,10), V(1,8), V(1,6), V(0,5) },
|
||||||
|
/* \ */ { M(0,12), V(6,6) },
|
||||||
|
};
|
||||||
|
|
||||||
|
float scale[] = { 1.0F,
|
||||||
|
1.0F, /* 128 chars per line */
|
||||||
|
1.3F, /* 96 chars per line */
|
||||||
|
2.0F, /* 64 chars per line */
|
||||||
|
2.5F, /* 48 chars per line */
|
||||||
|
4.0F, /* 32 chars per line */
|
||||||
|
5.3F, /* 24 chars per line */
|
||||||
|
8.0F /* 16 chars per line */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
uint64 iii_instr; /* Currently executing instruction */
|
||||||
|
int iii_sel; /* Select mask */
|
||||||
|
|
||||||
|
t_stat iii_devio(uint32 dev, uint64 *data);
|
||||||
|
t_stat iii_svc(UNIT *uptr);
|
||||||
|
t_stat iii_reset(DEVICE *dptr);
|
||||||
|
static void draw_point(int x, int y, int b, UNIT *uptr);
|
||||||
|
static void draw_line(int x1, int y1, int x2, int y2, int b, UNIT *uptr);
|
||||||
|
t_stat iii_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
|
||||||
|
const char *iii_description (DEVICE *dptr);
|
||||||
|
|
||||||
|
DIB iii_dib = { III_DEVNUM, 1, iii_devio, NULL};
|
||||||
|
|
||||||
|
UNIT iii_unit[] = {
|
||||||
|
{UDATA (&iii_svc, UNIT_IDLE, 0) },
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
MTAB iii_mod[] = {
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
DEVICE iii_dev = {
|
||||||
|
"III", iii_unit, NULL, iii_mod,
|
||||||
|
2, 10, 31, 1, 8, 8,
|
||||||
|
NULL, NULL, iii_reset,
|
||||||
|
NULL, NULL, NULL, &iii_dib, DEV_DEBUG | DEV_DISABLE | DEV_DIS, 0, dev_debug,
|
||||||
|
NULL, NULL, &iii_help, NULL, NULL, &iii_description
|
||||||
|
};
|
||||||
|
|
||||||
|
t_stat iii_devio(uint32 dev, uint64 *data) {
|
||||||
|
UNIT *uptr = &iii_unit[0];
|
||||||
|
switch(dev & 3) {
|
||||||
|
case CONI:
|
||||||
|
*data = (((uint64)iii_sel) << 18) | (uint64)(uptr->PIA);
|
||||||
|
if ((iii_instr & 037) == 0)
|
||||||
|
*data |= INST_HLT;
|
||||||
|
*data |= (uptr->STATUS & 07) << 4;
|
||||||
|
if (uptr->STATUS & NXM_FLG)
|
||||||
|
*data |= NXM_BIT;
|
||||||
|
if (uptr->STATUS & DATA_FLG)
|
||||||
|
*data |= DATAO_LK;
|
||||||
|
if ((uptr->STATUS & RUN_FLG) == 0)
|
||||||
|
*data |= HLT_FLG;
|
||||||
|
if (uptr->STATUS & CTL_FBIT)
|
||||||
|
*data |= CONT_BIT;
|
||||||
|
if (uptr->STATUS & WRP_FBIT)
|
||||||
|
*data |= WRAP_FLG;
|
||||||
|
if (uptr->STATUS & EDG_FBIT)
|
||||||
|
*data |= EDGE_FLG;
|
||||||
|
if (uptr->STATUS & LIT_FBIT)
|
||||||
|
*data |= LIGHT_FLG;
|
||||||
|
sim_debug(DEBUG_CONI, &iii_dev, "III %03o CONI %06o %06o\n", dev, (uint32)*data,
|
||||||
|
PC);
|
||||||
|
break;
|
||||||
|
case CONO:
|
||||||
|
clr_interrupt(III_DEVNUM);
|
||||||
|
if (*data & SET_PIA)
|
||||||
|
uptr->PIA = (int)(*data&PIA_MSK);
|
||||||
|
if (*data & F)
|
||||||
|
uptr->STATUS &= ~(WRP_FBIT|EDG_FBIT|LIT_FBIT|DATA_FLG|NXM_FLG);
|
||||||
|
uptr->STATUS &= ~(017 & ((*data >> 14) ^ (*data >> 10)));
|
||||||
|
uptr->STATUS ^= (017 & (*data >> 10));
|
||||||
|
if (*data & STOP)
|
||||||
|
uptr->STATUS &= ~RUN_FLG;
|
||||||
|
if (*data & CONT) {
|
||||||
|
uptr->STATUS |= RUN_FLG;
|
||||||
|
iii_instr = M[uptr->MAR];
|
||||||
|
sim_activate(uptr, 10);
|
||||||
|
}
|
||||||
|
if (((uptr->STATUS >> 3) & (uptr->STATUS & (WRAP_MSK|EDGE_MSK|LIGH_MSK))) != 0)
|
||||||
|
set_interrupt(III_DEVNUM, uptr->PIA);
|
||||||
|
if (uptr->STATUS & HLT_MSK)
|
||||||
|
set_interrupt(III_DEVNUM, uptr->PIA);
|
||||||
|
sim_debug(DEBUG_CONO, &iii_dev, "III %03o CONO %06o %06o\n", dev,
|
||||||
|
(uint32)*data, PC);
|
||||||
|
break;
|
||||||
|
case DATAI:
|
||||||
|
sim_debug(DEBUG_DATAIO, &iii_dev, "III %03o DATAI %06o\n", dev, (uint32)*data);
|
||||||
|
break;
|
||||||
|
case DATAO:
|
||||||
|
if (uptr->STATUS & RUN_FLG)
|
||||||
|
uptr->STATUS |= DATA_FLG;
|
||||||
|
else {
|
||||||
|
iii_instr = *data;
|
||||||
|
sim_activate(uptr, 10);
|
||||||
|
}
|
||||||
|
sim_debug(DEBUG_DATAIO, &iii_dev, "III %03o DATAO %06o\n", dev, (uint32)*data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat
|
||||||
|
iii_svc (UNIT *uptr)
|
||||||
|
{
|
||||||
|
uint64 temp;
|
||||||
|
int A;
|
||||||
|
int ox, oy, nx, ny, br, sz;
|
||||||
|
int i, j, ch;
|
||||||
|
float ch_sz;
|
||||||
|
|
||||||
|
iii_cycle(10, 0);
|
||||||
|
|
||||||
|
/* Extract X,Y,Bright and Size */
|
||||||
|
sz = (uptr->POS & CSIZE) >> CSIZE_V;
|
||||||
|
br = (uptr->POS & CBRT) >> CBRT_V;
|
||||||
|
ox = (uptr->POS & POS_X) >> POS_X_V;
|
||||||
|
oy = (uptr->POS & POS_Y) >> POS_Y_V;
|
||||||
|
nx = ox = (ox ^ 02000) - 02000;
|
||||||
|
ny = oy = (oy ^ 02000) - 02000;
|
||||||
|
ch_sz = scale[sz];
|
||||||
|
|
||||||
|
sim_debug(DEBUG_DETAIL, &iii_dev, "III: pos %d %d %d %d %o\n", ox, oy, br, sz,
|
||||||
|
uptr->STATUS );
|
||||||
|
switch(iii_instr & 017) {
|
||||||
|
case 000: /* JMP and HLT */
|
||||||
|
if (iii_instr & 020) {
|
||||||
|
uptr->MAR = (iii_instr >> 18) & RMASK;
|
||||||
|
} else {
|
||||||
|
uptr->STATUS &= ~RUN_FLG;
|
||||||
|
if (uptr->STATUS & HLT_MSK)
|
||||||
|
set_interrupt(III_DEVNUM, uptr->PIA);
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
goto skip_up;
|
||||||
|
case 001:
|
||||||
|
case 003:
|
||||||
|
case 005:
|
||||||
|
case 007:
|
||||||
|
case 011:
|
||||||
|
case 013:
|
||||||
|
case 015:
|
||||||
|
case 017: /* Draw 4 characters */
|
||||||
|
for (i = 29; i >= 1; i -= 7) {
|
||||||
|
/* Extract character and compute initial point */
|
||||||
|
int cx, cy;
|
||||||
|
int lx, ly;
|
||||||
|
ch = (iii_instr >> i) & 0177;
|
||||||
|
cx = 0;
|
||||||
|
cy = (int)(6.0 * ch_sz);
|
||||||
|
lx = ox;
|
||||||
|
ly = oy + cy;
|
||||||
|
sim_debug(DEBUG_DETAIL, &iii_dev, "III: ch %d %d %o '%c' %o %o\n",
|
||||||
|
lx, ly, ch, (ch < ' ')? '.' : ch, sz, br);
|
||||||
|
if (ch == '\t' || ch == 0)
|
||||||
|
continue;
|
||||||
|
if (ch == '\r') {
|
||||||
|
ox = -512;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (ch == '\n') {
|
||||||
|
oy -= (int)(16.0 * ch_sz);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* Scan map and draw lines as needed */
|
||||||
|
if ((iii_sel & 04000) != 0) {
|
||||||
|
for(j = 0; j < 18; j++) {
|
||||||
|
uint8 v = map[ch][j];
|
||||||
|
if (v == 0)
|
||||||
|
break;
|
||||||
|
cx = (int)((float)((v >> 4) & 07) * ch_sz);
|
||||||
|
cy = (int)((float)(v & 017) * ch_sz);
|
||||||
|
nx = ox + cx;
|
||||||
|
ny = oy + cy;
|
||||||
|
sim_debug(DEBUG_DATA, &iii_dev, "III: map %d %d %d %d %02x\n",
|
||||||
|
lx, ly, nx, ny, v);
|
||||||
|
if (v & 0200)
|
||||||
|
draw_line(lx, ly, nx, ny, br, uptr);
|
||||||
|
lx = nx;
|
||||||
|
ly = ny;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ox += (int)(8.0 * ch_sz);
|
||||||
|
}
|
||||||
|
nx = ox;
|
||||||
|
ny = oy;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 002: /* Short Vector */
|
||||||
|
if ((iii_sel & 04000) == 0)
|
||||||
|
break;
|
||||||
|
/* Do first point */
|
||||||
|
nx = (iii_instr >> 26) & 077;
|
||||||
|
ny = (iii_instr >> 20) & 077;
|
||||||
|
/* Sign extend */
|
||||||
|
nx = (nx ^ 040) - 040;
|
||||||
|
ny = (ny ^ 040) - 040;
|
||||||
|
/* Compute relative position. */
|
||||||
|
sim_debug(DEBUG_DETAIL, &iii_dev, "III: short %d %d %o %d\n",
|
||||||
|
nx, ny, sz, br);
|
||||||
|
nx += ox;
|
||||||
|
ny += oy;
|
||||||
|
if (nx < -512 || nx > 512 || ny < -512 || ny > 512)
|
||||||
|
uptr->STATUS |= EDG_FBIT;
|
||||||
|
i = (int)((iii_instr >> 18) & 3);
|
||||||
|
if ((i & 02) == 0 && (iii_sel & 04000) != 0) { /* Check if visible */
|
||||||
|
if ((i & 01) == 0) { /* Draw a line */
|
||||||
|
draw_line(ox, oy, nx, ny, br, uptr);
|
||||||
|
} else {
|
||||||
|
draw_point(nx, ny, br, uptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ox = nx;
|
||||||
|
oy = ny;
|
||||||
|
/* Do second point */
|
||||||
|
nx = (iii_instr >> 12) & 0177;
|
||||||
|
ny = (iii_instr >> 6) & 0177;
|
||||||
|
/* Sign extend */
|
||||||
|
nx = (nx ^ 040) - 040;
|
||||||
|
ny = (ny ^ 040) - 040;
|
||||||
|
sim_debug(DEBUG_DETAIL, &iii_dev, "III: short2 %d %d %o %d\n",
|
||||||
|
nx, ny, sz, br);
|
||||||
|
/* Compute relative position. */
|
||||||
|
nx += ox;
|
||||||
|
ny += oy;
|
||||||
|
if (nx < -512 || nx > 512 || ny < -512 || ny > 512)
|
||||||
|
uptr->STATUS |= EDG_FBIT;
|
||||||
|
/* Check if visible */
|
||||||
|
if ((iii_instr & 040) == 0 && (iii_sel & 04000) != 0) {
|
||||||
|
if ((iii_instr & 020) == 0) { /* Draw a line */
|
||||||
|
draw_line(ox, oy, nx, ny, br, uptr);
|
||||||
|
} else {
|
||||||
|
draw_point(nx, ny, br, uptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 004: /* JSR, JMS, SAVE */
|
||||||
|
temp = (((uint64)uptr->MAR) << 18) | 020 /* | CPC */;
|
||||||
|
A = (iii_instr >> 18) & RMASK;
|
||||||
|
if ((iii_instr & 030) != 030) {
|
||||||
|
M[A] = temp;
|
||||||
|
A++;
|
||||||
|
}
|
||||||
|
if ((iii_instr & 020) != 020) {
|
||||||
|
temp = uptr->STATUS & 0377;
|
||||||
|
temp |= ((uint64)uptr->POS) << 8;
|
||||||
|
M[A] = temp;
|
||||||
|
A++;
|
||||||
|
}
|
||||||
|
if ((iii_instr & 030) != 030) {
|
||||||
|
uptr->MAR = A;
|
||||||
|
}
|
||||||
|
goto skip_up;
|
||||||
|
|
||||||
|
case 006: /* Long Vector */
|
||||||
|
/* Update sizes if needed */
|
||||||
|
if (((iii_instr >> 8) & CSIZE) != 0)
|
||||||
|
sz = (iii_instr >> 8) & CSIZE;
|
||||||
|
if (((iii_instr >> 11) & 7) != 0)
|
||||||
|
br = (iii_instr > 11) & 7;
|
||||||
|
nx = (iii_instr >> 25) & 03777;
|
||||||
|
ny = (iii_instr >> 14) & 03777;
|
||||||
|
nx = (nx ^ 02000) - 02000;
|
||||||
|
ny = (ny ^ 02000) - 02000;
|
||||||
|
sim_debug(DEBUG_DETAIL, &iii_dev, "III: long %d %d %o %o\n",
|
||||||
|
nx, ny, sz, br);
|
||||||
|
if ((iii_instr & 0100) == 0) { /* Relative mode */
|
||||||
|
nx += ox;
|
||||||
|
ny += oy;
|
||||||
|
if (nx < -512 || nx > 512 || ny < -512 || ny > 512)
|
||||||
|
uptr->STATUS |= EDG_FBIT;
|
||||||
|
}
|
||||||
|
/* Check if visible */
|
||||||
|
if ((iii_instr & 040) == 0 && (iii_sel & 04000) != 0) {
|
||||||
|
if ((iii_instr & 020) == 0) /* Draw a line */
|
||||||
|
draw_line(ox, oy, nx, ny, br, uptr);
|
||||||
|
else
|
||||||
|
draw_point(nx, ny, br, uptr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 010: /* Select instruction */
|
||||||
|
i = (iii_instr >> 24) & 07777; /* Set mask */
|
||||||
|
j = (iii_instr >> 12) & 07777; /* Reset mask */
|
||||||
|
ch = i & j; /* Compliment mask */
|
||||||
|
i &= ~ch;
|
||||||
|
j &= ~ch;
|
||||||
|
iii_sel = ((iii_sel | i) & ~j) ^ ch;
|
||||||
|
goto skip_up;
|
||||||
|
|
||||||
|
case 012: /* Test instruction */
|
||||||
|
A = (uptr->STATUS & (int32)(iii_instr >> 12) & 0377) != 0;
|
||||||
|
j = (int)((iii_instr >> 20) & 0377); /* set mask */
|
||||||
|
i = (int)((iii_instr >> 28) & 0377); /* Reset */
|
||||||
|
uptr->STATUS &= ~(i ^ j);
|
||||||
|
uptr->STATUS ^= j;
|
||||||
|
if (A ^ ((iii_instr & 020) != 0))
|
||||||
|
uptr->MAR++;
|
||||||
|
goto skip_up;
|
||||||
|
|
||||||
|
case 014: /* Restore */
|
||||||
|
A = (iii_instr >> 18) & RMASK;
|
||||||
|
temp = M[A];
|
||||||
|
if ((iii_instr & 020) != 0) {
|
||||||
|
uptr->STATUS &= ~0377;
|
||||||
|
uptr->STATUS |= temp & 0377;
|
||||||
|
}
|
||||||
|
if ((iii_instr & 040) != 0) {
|
||||||
|
uptr->POS = (temp >> 8) & (POS_X|POS_Y|CBRT|CSIZE);
|
||||||
|
}
|
||||||
|
goto skip_up;
|
||||||
|
|
||||||
|
case 016: /* Nop */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Repack to new position. */
|
||||||
|
sim_debug(DEBUG_DATA, &iii_dev, "III: update %d %d %8o ", nx, ny, uptr->POS);
|
||||||
|
uptr->POS = (POS_X & ((nx & 03777) << POS_X_V)) |
|
||||||
|
(POS_Y & ((ny & 03777) << POS_Y_V)) |
|
||||||
|
(CBRT & (br << CBRT_V)) |
|
||||||
|
(CSIZE & (sz << CSIZE_V));
|
||||||
|
sim_debug(DEBUG_DATA, &iii_dev, "-> %8o\n", uptr->POS);
|
||||||
|
skip_up:
|
||||||
|
if (uptr->STATUS & RUN_FLG) {
|
||||||
|
iii_instr = M[uptr->MAR];
|
||||||
|
sim_debug(DEBUG_DETAIL, &iii_dev, "III: fetch %06o %012llo\n",
|
||||||
|
uptr->MAR, iii_instr);
|
||||||
|
uptr->MAR++;
|
||||||
|
uptr->MAR &= RMASK;
|
||||||
|
sim_activate(uptr, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((uptr->STATUS >> 3) & (uptr->STATUS & (WRAP_MSK|EDGE_MSK|LIGH_MSK))) != 0)
|
||||||
|
set_interrupt(III_DEVNUM, uptr->PIA);
|
||||||
|
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat iii_reset (DEVICE *dptr)
|
||||||
|
{
|
||||||
|
if (dptr->flags & DEV_DIS) {
|
||||||
|
display_close(dptr);
|
||||||
|
} else {
|
||||||
|
display_reset();
|
||||||
|
dptr->units[0].POS = 0;
|
||||||
|
iii_init(dptr, 1);
|
||||||
|
}
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Draw a point at x,y with intensity b. */
|
||||||
|
/* X and Y runs from -512 to 512. */
|
||||||
|
static void
|
||||||
|
draw_point(int x, int y, int b, UNIT *uptr)
|
||||||
|
{
|
||||||
|
if (x < -512 || x > 512 || y < -512 || y > 512)
|
||||||
|
uptr->STATUS |= WRP_FBIT;
|
||||||
|
iii_point(x, y, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Draw a line between two points */
|
||||||
|
static void
|
||||||
|
draw_line(int x1, int y1, int x2, int y2, int b, UNIT *uptr)
|
||||||
|
{
|
||||||
|
if (x1 < -512 || x1 > 512 || y1 < -512 || y1 > 512)
|
||||||
|
uptr->STATUS |= WRP_FBIT;
|
||||||
|
if (x2 < -512 || x2 > 512 || y2 < -512 || y2 > 512)
|
||||||
|
uptr->STATUS |= WRP_FBIT;
|
||||||
|
iii_draw_line(x1, y1, x2, y2, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat iii_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
||||||
|
{
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *iii_description (DEVICE *dptr)
|
||||||
|
{
|
||||||
|
return "Triple III Display";
|
||||||
|
}
|
||||||
|
#endif
|
251
PDP10/ka10_imx.c
251
PDP10/ka10_imx.c
|
@ -1,6 +1,6 @@
|
||||||
/* ka10_imx.c: Input multplexor for A/D.
|
/* ka10_imx.c: Input multplexor for A/D.
|
||||||
|
|
||||||
Copyright (c) 2018, Lars Brinkhoff
|
Copyright (c) 2018,2020, Lars Brinkhoff
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "kx10_defs.h"
|
#include "kx10_defs.h"
|
||||||
|
#include "sim_video.h"
|
||||||
|
|
||||||
#ifndef NUM_DEVS_IMX
|
#ifndef NUM_DEVS_IMX
|
||||||
#define NUM_DEVS_IMX 0
|
#define NUM_DEVS_IMX 0
|
||||||
|
@ -47,33 +48,78 @@
|
||||||
|
|
||||||
#define IMX_CHANNEL 0000177
|
#define IMX_CHANNEL 0000177
|
||||||
|
|
||||||
|
#define JOY_MAX_UNITS 4
|
||||||
|
#define JOY_MAX_AXES 4
|
||||||
|
#define JOY_NO_CHAN (IMX_CHANNEL + 1)
|
||||||
|
|
||||||
t_stat imx_devio(uint32 dev, uint64 *data);
|
t_stat imx_devio(uint32 dev, uint64 *data);
|
||||||
|
t_stat imx_svc (UNIT *uptr);
|
||||||
|
t_stat imx_reset (DEVICE *dptr);
|
||||||
const char *imx_description (DEVICE *dptr);
|
const char *imx_description (DEVICE *dptr);
|
||||||
|
#if MPX_DEV
|
||||||
|
t_stat imx_set_mpx (UNIT *uptr, int32 val, CONST char *cptr, void *desc) ;
|
||||||
|
t_stat imx_show_mpx (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
||||||
|
#endif
|
||||||
|
t_stat imx_show_channel (FILE* st, UNIT* uptr, int32 val, CONST void* desc);
|
||||||
|
t_stat imx_set_channel (UNIT* uptr, int32 val, CONST char* cptr, void* desc);
|
||||||
|
|
||||||
static uint64 status = IMX_ASSIGNED;
|
static uint64 status = IMX_ASSIGNED;
|
||||||
|
static uint64 imx_data;
|
||||||
|
static uint64 imx_samples;
|
||||||
static int initial_channel = 0;
|
static int initial_channel = 0;
|
||||||
static int current_channel = 0;
|
static int current_channel = 0;
|
||||||
|
static int imx_mpx_lvl;
|
||||||
|
|
||||||
|
static int imx_inputs[0200];
|
||||||
|
static int imx_map[JOY_MAX_UNITS][JOY_MAX_AXES];
|
||||||
|
|
||||||
UNIT imx_unit[] = {
|
UNIT imx_unit[] = {
|
||||||
{UDATA(NULL, UNIT_DISABLE, 0)}, /* 0 */
|
{ UDATA (&imx_svc, UNIT_IDLE, 0) }
|
||||||
};
|
};
|
||||||
DIB imx_dib = {IMX_DEVNUM, 1, &imx_devio, NULL};
|
DIB imx_dib = {IMX_DEVNUM, 1, &imx_devio, NULL};
|
||||||
|
|
||||||
MTAB imx_mod[] = {
|
MTAB imx_mod[] = {
|
||||||
|
#if MPX_DEV
|
||||||
|
{MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "MPX", "MPX",
|
||||||
|
&imx_set_mpx, &imx_show_mpx, NULL},
|
||||||
|
#endif
|
||||||
|
{MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "CHANNEL", "CHANNEL",
|
||||||
|
&imx_set_channel, &imx_show_channel, NULL},
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
DEVICE imx_dev = {
|
DEVICE imx_dev = {
|
||||||
"IMX", imx_unit, NULL, imx_mod,
|
"IMX", imx_unit, NULL, imx_mod,
|
||||||
1, 8, 0, 1, 8, 36,
|
1, 8, 0, 1, 8, 36,
|
||||||
NULL, NULL, NULL, NULL, NULL, NULL,
|
NULL, NULL, imx_reset, NULL, NULL, NULL,
|
||||||
&imx_dib, DEV_DISABLE | DEV_DIS | DEV_DEBUG, 0, NULL,
|
&imx_dib, DEV_DISABLE | DEV_DIS | DEV_DEBUG, 0, NULL,
|
||||||
NULL, NULL, NULL, NULL, NULL, &imx_description
|
NULL, NULL, NULL, NULL, NULL, &imx_description
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void imx_joy_motion(int which, int axis, int value)
|
||||||
|
{
|
||||||
|
int chan;
|
||||||
|
|
||||||
|
if (which < JOY_MAX_UNITS && axis < JOY_MAX_AXES) {
|
||||||
|
chan = imx_map[which][axis];
|
||||||
|
if (chan == JOY_NO_CHAN)
|
||||||
|
return;
|
||||||
|
|
||||||
|
value += 32768;
|
||||||
|
|
||||||
|
if (chan < 0) {
|
||||||
|
chan = -chan;
|
||||||
|
value = 65535 - value;
|
||||||
|
}
|
||||||
|
imx_inputs[chan] = value >> 5;
|
||||||
|
sim_debug(DEBUG_DETAIL, &imx_dev, "Channel %d value %o\n",
|
||||||
|
chan, imx_inputs[chan]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int imx_sample (void)
|
static int imx_sample (void)
|
||||||
{
|
{
|
||||||
int sample = 2048;
|
int sample = imx_inputs[current_channel];
|
||||||
if (status & IMX_SEQUENCE)
|
if (status & IMX_SEQUENCE)
|
||||||
current_channel = (current_channel + 1) & IMX_CHANNEL;
|
current_channel = (current_channel + 1) & IMX_CHANNEL;
|
||||||
else
|
else
|
||||||
|
@ -81,36 +127,217 @@ static int imx_sample (void)
|
||||||
return sample;
|
return sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void imx_activate (void)
|
||||||
|
{
|
||||||
|
int micros;
|
||||||
|
|
||||||
|
if (status & IMX_DONE) {
|
||||||
|
sim_cancel (imx_unit);
|
||||||
|
sim_debug(DEBUG_IRQ, &imx_dev, "Cancel\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
micros = (status >> 16) & 0377;
|
||||||
|
if (micros < 10)
|
||||||
|
micros = 10;
|
||||||
|
sim_activate_after (imx_unit, micros);
|
||||||
|
sim_debug(DEBUG_IRQ, &imx_dev, "Activate\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat imx_reset (DEVICE *dptr)
|
||||||
|
{
|
||||||
|
static int init = 1;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
if (dptr->flags & DEV_DIS) {
|
||||||
|
imx_samples = 0;
|
||||||
|
imx_data = 0;
|
||||||
|
|
||||||
|
for (i = 0; i <= IMX_CHANNEL; i++)
|
||||||
|
imx_inputs[i] = 1000;
|
||||||
|
|
||||||
|
for (i = 0; i < JOY_MAX_UNITS; i++) {
|
||||||
|
for (j = 0; j < JOY_MAX_UNITS; j++)
|
||||||
|
imx_map[i][j] = JOY_NO_CHAN;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (init) {
|
||||||
|
vid_register_gamepad_motion_callback (imx_joy_motion);
|
||||||
|
init = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
t_stat imx_devio(uint32 dev, uint64 *data)
|
t_stat imx_devio(uint32 dev, uint64 *data)
|
||||||
{
|
{
|
||||||
DEVICE *dptr = &imx_dev;
|
DEVICE *dptr = &imx_dev;
|
||||||
|
|
||||||
switch(dev & 07) {
|
switch(dev & 07) {
|
||||||
case CONO|4:
|
case CONO|4:
|
||||||
status &= ~IMX_CONO;
|
sim_debug(DEBUG_CONO, &imx_dev, "%06llo\n", *data);
|
||||||
|
status &= ~(IMX_CONO|IMX_DONE);
|
||||||
status |= *data & IMX_CONO;
|
status |= *data & IMX_CONO;
|
||||||
|
imx_data = 0;
|
||||||
|
imx_samples = 0;
|
||||||
current_channel = initial_channel;
|
current_channel = initial_channel;
|
||||||
|
clr_interrupt (IMX_DEVNUM);
|
||||||
|
imx_activate ();
|
||||||
break;
|
break;
|
||||||
case CONI|4:
|
case CONI|4:
|
||||||
status |= IMX_DONE;
|
|
||||||
*data = status & IMX_CONI;
|
*data = status & IMX_CONI;
|
||||||
|
sim_debug(DEBUG_CONI, &imx_dev, "%012llo\n", *data);
|
||||||
break;
|
break;
|
||||||
case DATAO|4:
|
case DATAO|4:
|
||||||
|
sim_debug(DEBUG_DATAIO, &imx_dev, "DATAO %012llo\n", *data);
|
||||||
initial_channel = *data & IMX_CHANNEL;
|
initial_channel = *data & IMX_CHANNEL;
|
||||||
break;
|
break;
|
||||||
case DATAI|4:
|
case DATAI|4:
|
||||||
*data = imx_sample();
|
*data = imx_data;
|
||||||
if (status & IMX_PACK) {
|
sim_debug(DEBUG_DATAIO, &imx_dev, "DATAI %012llo\n", *data);
|
||||||
*data <<= 24;
|
imx_data = 0;
|
||||||
*data |= imx_sample() << 12;
|
imx_samples = 0;
|
||||||
*data |= imx_sample();
|
status &= ~IMX_DONE;
|
||||||
}
|
clr_interrupt (IMX_DEVNUM);
|
||||||
|
sim_debug(DEBUG_IRQ, &imx_dev, "Clear interrupt\n");
|
||||||
|
imx_activate ();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t_stat imx_svc (UNIT *uptr)
|
||||||
|
{
|
||||||
|
int max_samples;
|
||||||
|
|
||||||
|
if (status & IMX_PACK) {
|
||||||
|
max_samples = 3;
|
||||||
|
} else {
|
||||||
|
max_samples = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (imx_samples < max_samples) {
|
||||||
|
imx_data <<= 12;
|
||||||
|
imx_data |= imx_sample();
|
||||||
|
imx_samples++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (imx_samples == max_samples) {
|
||||||
|
status |= IMX_DONE;
|
||||||
|
if (status & 7) {
|
||||||
|
set_interrupt_mpx (IMX_DEVNUM, status & 7, imx_mpx_lvl);
|
||||||
|
sim_debug(DEBUG_IRQ, &imx_dev, "Raise interrupt\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
imx_activate ();
|
||||||
|
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MPX_DEV
|
||||||
|
/* set MPX level number */
|
||||||
|
t_stat imx_set_mpx (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
|
||||||
|
{
|
||||||
|
int32 mpx;
|
||||||
|
t_stat r;
|
||||||
|
|
||||||
|
if (cptr == NULL)
|
||||||
|
return SCPE_ARG;
|
||||||
|
mpx = (int32) get_uint (cptr, 8, 8, &r);
|
||||||
|
if (r != SCPE_OK)
|
||||||
|
return r;
|
||||||
|
imx_mpx_lvl = mpx;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat imx_show_mpx (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
|
||||||
|
{
|
||||||
|
if (uptr == NULL)
|
||||||
|
return SCPE_IERR;
|
||||||
|
|
||||||
|
fprintf (st, "MPX=%o", imx_mpx_lvl);
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
t_stat imx_set_channel (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
|
||||||
|
{
|
||||||
|
int chan, unit, axis, negate = 0;
|
||||||
|
char gbuf[CBUFSIZE];
|
||||||
|
CONST char *tptr;
|
||||||
|
t_stat r;
|
||||||
|
|
||||||
|
if (cptr == NULL || *cptr == 0)
|
||||||
|
return SCPE_ARG;
|
||||||
|
|
||||||
|
tptr = get_glyph (cptr, gbuf, ';');
|
||||||
|
if (tptr == NULL)
|
||||||
|
return SCPE_ARG;
|
||||||
|
chan = (int) get_uint (gbuf, 8, IMX_CHANNEL, &r);
|
||||||
|
if (r != SCPE_OK)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
tptr = get_glyph (tptr, gbuf, ';');
|
||||||
|
if (tptr == NULL || strncasecmp (gbuf, "unit", 4) != 0)
|
||||||
|
return SCPE_ARG;
|
||||||
|
unit = (int) get_uint (gbuf + 4, 10, JOY_MAX_UNITS - 1, &r);
|
||||||
|
if (r != SCPE_OK)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
tptr = get_glyph (tptr, gbuf, ';');
|
||||||
|
if (strncasecmp (gbuf, "axis", 4) != 0)
|
||||||
|
return SCPE_ARG;
|
||||||
|
axis = (int) get_uint (gbuf + 4, 10, JOY_MAX_AXES - 1, &r);
|
||||||
|
if (r != SCPE_OK)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (*tptr != 0) {
|
||||||
|
if (strcasecmp (tptr, "negate") != 0)
|
||||||
|
return SCPE_ARG;
|
||||||
|
negate = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (negate)
|
||||||
|
chan = -chan;
|
||||||
|
imx_map[unit][axis] = chan;
|
||||||
|
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat imx_show_channel (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
|
||||||
|
{
|
||||||
|
int nothing = 1;
|
||||||
|
const char *negate, *comma = "";
|
||||||
|
int chan, i, j;
|
||||||
|
|
||||||
|
if (uptr == NULL)
|
||||||
|
return SCPE_IERR;
|
||||||
|
|
||||||
|
for (i = 0; i < JOY_MAX_UNITS; i++) {
|
||||||
|
for (j = 0; j < JOY_MAX_AXES; j++) {
|
||||||
|
chan = imx_map[i][j];
|
||||||
|
if (chan != JOY_NO_CHAN) {
|
||||||
|
if (chan < 0) {
|
||||||
|
chan = -chan;
|
||||||
|
negate = ";NEGATE";
|
||||||
|
} else
|
||||||
|
negate = "";
|
||||||
|
|
||||||
|
fprintf (st, "%sCHANNEL=%o;JOY%d;AXIS%d%s", comma, chan, i, j, negate);
|
||||||
|
comma = ", ";
|
||||||
|
nothing = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nothing)
|
||||||
|
fprintf (st, "CHANNEL=(NO MAPPINGS)");
|
||||||
|
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
const char *imx_description (DEVICE *dptr)
|
const char *imx_description (DEVICE *dptr)
|
||||||
{
|
{
|
||||||
return "A/D input multiplexor";
|
return "A/D input multiplexor";
|
||||||
|
|
|
@ -47,8 +47,6 @@
|
||||||
#define PIA_FLG 07
|
#define PIA_FLG 07
|
||||||
#define CLK_IRQ 010
|
#define CLK_IRQ 010
|
||||||
|
|
||||||
#define TMR_PD 3
|
|
||||||
|
|
||||||
int pd_tps = 60;
|
int pd_tps = 60;
|
||||||
|
|
||||||
t_stat pd_devio(uint32 dev, uint64 *data);
|
t_stat pd_devio(uint32 dev, uint64 *data);
|
||||||
|
@ -126,9 +124,6 @@ t_stat pd_devio(uint32 dev, uint64 *data)
|
||||||
t_stat
|
t_stat
|
||||||
pd_srv(UNIT * uptr)
|
pd_srv(UNIT * uptr)
|
||||||
{
|
{
|
||||||
int32 t;
|
|
||||||
|
|
||||||
t = sim_rtcn_calb (pd_tps, TMR_PD);
|
|
||||||
sim_activate_after(uptr, 1000000/pd_tps);
|
sim_activate_after(uptr, 1000000/pd_tps);
|
||||||
if (uptr->PIA_CH & PIA_FLG) {
|
if (uptr->PIA_CH & PIA_FLG) {
|
||||||
uptr->PIA_CH |= CLK_IRQ;
|
uptr->PIA_CH |= CLK_IRQ;
|
||||||
|
@ -139,7 +134,6 @@ pd_srv(UNIT * uptr)
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char *pd_description (DEVICE *dptr)
|
const char *pd_description (DEVICE *dptr)
|
||||||
{
|
{
|
||||||
return "Paul DeCoriolis clock";
|
return "Paul DeCoriolis clock";
|
||||||
|
|
104
PDP10/ka10_pmp.c
104
PDP10/ka10_pmp.c
|
@ -1,6 +1,6 @@
|
||||||
/* PMP disk controller interface for WAITS.
|
/* PMP disk controller interface for WAITS.
|
||||||
|
|
||||||
Copyright (c) 2017, Richard Cornwell
|
Copyright (c) 2017-2020, Richard Cornwell
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -348,9 +348,9 @@ uint64 pmp_status; /* CONI status for device 500 */
|
||||||
int pmp_statusb;
|
int pmp_statusb;
|
||||||
uint32 pmp_cmd_hold; /* Command hold register */
|
uint32 pmp_cmd_hold; /* Command hold register */
|
||||||
uint32 pmp_wc_hold; /* Word count hold */
|
uint32 pmp_wc_hold; /* Word count hold */
|
||||||
uint32 pmp_addr_hold; /* Address register hold */
|
t_addr pmp_addr_hold; /* Address register hold */
|
||||||
uint32 pmp_wc; /* Current word count register */
|
uint32 pmp_wc; /* Current word count register */
|
||||||
uint32 pmp_addr; /* Current address register */
|
t_addr pmp_addr; /* Current address register */
|
||||||
uint64 pmp_data; /* Data assembly register */
|
uint64 pmp_data; /* Data assembly register */
|
||||||
int pmp_cnt; /* Character count in asm register */
|
int pmp_cnt; /* Character count in asm register */
|
||||||
int pmp_cmd; /* Current command */
|
int pmp_cmd; /* Current command */
|
||||||
|
@ -550,22 +550,25 @@ pmp_checkirq() {
|
||||||
sim_debug(DEBUG_DETAIL, &pmp_dev, "parity irq\n");
|
sim_debug(DEBUG_DETAIL, &pmp_dev, "parity irq\n");
|
||||||
f = 1;
|
f = 1;
|
||||||
}
|
}
|
||||||
if ((pmp_irq & IRQ_EMPTY) != 0 && (pmp_statusb & (WCMA_LD|CMD_LD)) != (WCMA_LD|CMD_LD)) {
|
if ((pmp_irq & IRQ_EMPTY) != 0 &&
|
||||||
|
(pmp_statusb & (WCMA_LD|CMD_LD)) != (WCMA_LD|CMD_LD)) {
|
||||||
sim_debug(DEBUG_DETAIL, &pmp_dev, "load irq\n");
|
sim_debug(DEBUG_DETAIL, &pmp_dev, "load irq\n");
|
||||||
f = 1;
|
f = 1;
|
||||||
}
|
}
|
||||||
if ((pmp_irq & IRQ_IDLE) != 0 && (pmp_statusb & (OP1|IDLE_CH)) == IDLE_CH) {
|
if ((pmp_irq & IRQ_IDLE) != 0 && (pmp_statusb & (OP1|IDLE_CH)) == IDLE_CH) {
|
||||||
sim_debug(DEBUG_DETAIL, &pmp_dev, "idle irq\n");
|
sim_debug(DEBUG_DETAIL, &pmp_dev, "idle irq\n");
|
||||||
f = 1;
|
f = 1;
|
||||||
}
|
}
|
||||||
if ((pmp_irq & IRQ_UEND) != 0 && (pmp_status & (NXM_ERR|CHA_ERR|SEL_ERR|UNU_END)) != 0) {
|
if ((pmp_irq & IRQ_UEND) != 0 &&
|
||||||
|
(pmp_status & (NXM_ERR|CHA_ERR|SEL_ERR|UNU_END)) != 0) {
|
||||||
sim_debug(DEBUG_DETAIL, &pmp_dev, "uend irq\n");
|
sim_debug(DEBUG_DETAIL, &pmp_dev, "uend irq\n");
|
||||||
f = 1;
|
f = 1;
|
||||||
}
|
}
|
||||||
if ((pmp_status & pmp_irq & (IRQ_NSTS|IRQ_STS)) != 0) {
|
if ((pmp_status & pmp_irq & (IRQ_NSTS|IRQ_STS)) != 0) {
|
||||||
sim_debug(DEBUG_DETAIL, &pmp_dev, "mem sts %o\n", (int)(pmp_status & pmp_irq & (IRQ_NSTS|IRQ_STS)));
|
sim_debug(DEBUG_DETAIL, &pmp_dev, "mem sts %o\n",
|
||||||
|
(int)(pmp_status & pmp_irq & (IRQ_NSTS|IRQ_STS)));
|
||||||
f = 1;
|
f = 1;
|
||||||
}
|
}
|
||||||
if (f)
|
if (f)
|
||||||
set_interrupt(PMP_DEV, pmp_pia);
|
set_interrupt(PMP_DEV, pmp_pia);
|
||||||
return f;
|
return f;
|
||||||
|
@ -597,10 +600,10 @@ chan_read_byte(uint8 *data) {
|
||||||
pmp_statusb |= TRANS_CH; /* Tranfer in progress */
|
pmp_statusb |= TRANS_CH; /* Tranfer in progress */
|
||||||
/* Read in next work if buffer is in empty status */
|
/* Read in next work if buffer is in empty status */
|
||||||
if (pmp_cnt & BUFF_EMPTY) {
|
if (pmp_cnt & BUFF_EMPTY) {
|
||||||
if (pmp_addr >= (int)MEMSIZE)
|
if (Mem_read_word(pmp_addr, &pmp_data, 0))
|
||||||
return pmp_posterror(NXM_ERR);
|
return pmp_posterror(NXM_ERR);
|
||||||
pmp_data = M[pmp_addr];
|
sim_debug(DEBUG_DETAIL, &pmp_dev, "chan_read %06o %012llo\n",
|
||||||
sim_debug(DEBUG_DETAIL, &pmp_dev, "chan_read %06o %012llo\n", pmp_addr, pmp_data);
|
pmp_addr, pmp_data);
|
||||||
pmp_addr++;
|
pmp_addr++;
|
||||||
pmp_cnt = 0;
|
pmp_cnt = 0;
|
||||||
xfer = 1; /* Read in a word */
|
xfer = 1; /* Read in a word */
|
||||||
|
@ -616,10 +619,10 @@ chan_read_byte(uint8 *data) {
|
||||||
if ((pmp_cnt & 0xf) > 0x3) {
|
if ((pmp_cnt & 0xf) > 0x3) {
|
||||||
if ((pmp_cnt & 0xf) == 0x4) { /* Split byte */
|
if ((pmp_cnt & 0xf) == 0x4) { /* Split byte */
|
||||||
byte = (pmp_data << 4) & 0xf0;
|
byte = (pmp_data << 4) & 0xf0;
|
||||||
if (pmp_addr >= (int)MEMSIZE)
|
if (Mem_read_word(pmp_addr, &pmp_data, 0))
|
||||||
return pmp_posterror(NXM_ERR);
|
return pmp_posterror(NXM_ERR);
|
||||||
pmp_data = M[pmp_addr];
|
sim_debug(DEBUG_DETAIL, &pmp_dev, "chan_read %06o %012llo\n",
|
||||||
sim_debug(DEBUG_DETAIL, &pmp_dev, "chan_read %06o %012llo\n", pmp_addr, pmp_data);
|
pmp_addr, pmp_data);
|
||||||
pmp_addr++;
|
pmp_addr++;
|
||||||
xfer = 1; /* Read in a word */
|
xfer = 1; /* Read in a word */
|
||||||
byte |= pmp_data & 0xf;
|
byte |= pmp_data & 0xf;
|
||||||
|
@ -642,27 +645,6 @@ chan_read_byte(uint8 *data) {
|
||||||
if (pmp_wc & 07000000)
|
if (pmp_wc & 07000000)
|
||||||
pmp_cnt |= BUFF_CHNEND;
|
pmp_cnt |= BUFF_CHNEND;
|
||||||
return 0;
|
return 0;
|
||||||
#if 0
|
|
||||||
next:
|
|
||||||
/* If not data channing, let device know there will be no
|
|
||||||
* more data to come
|
|
||||||
*/
|
|
||||||
if ((pmp_cmd & DATCH_ON) == 0) {
|
|
||||||
pmp_cnt = BUFF_CHNEND;
|
|
||||||
sim_debug(DEBUG_DETAIL, &pmp_dev, "chan_read_end\n");
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
if (pmp_statusb & WCMA_LD) {
|
|
||||||
pmp_statusb &= ~(WCMA_LD);
|
|
||||||
pmp_addr = pmp_addr_hold;
|
|
||||||
pmp_wc = pmp_wc_hold;
|
|
||||||
pmp_data = 0;
|
|
||||||
} else {
|
|
||||||
return pmp_posterror(CHA_ERR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
goto load;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write byte to memory */
|
/* write byte to memory */
|
||||||
|
@ -693,10 +675,10 @@ chan_write_byte(uint8 *data) {
|
||||||
pmp_cnt |= BUFF_DIRTY;
|
pmp_cnt |= BUFF_DIRTY;
|
||||||
if ((pmp_cnt & 03) == 0) {
|
if ((pmp_cnt & 03) == 0) {
|
||||||
pmp_cnt &= ~(BUFF_DIRTY|7);
|
pmp_cnt &= ~(BUFF_DIRTY|7);
|
||||||
if (pmp_addr >= (int)MEMSIZE)
|
if (Mem_write_word(pmp_addr, &pmp_data, 0))
|
||||||
return pmp_posterror(NXM_ERR);
|
return pmp_posterror(NXM_ERR);
|
||||||
M[pmp_addr] = pmp_data;
|
sim_debug(DEBUG_DETAIL, &pmp_dev, "chan_write %06o %012llo\n",
|
||||||
sim_debug(DEBUG_DETAIL, &pmp_dev, "chan_write %06o %012llo\n", pmp_addr, pmp_data);
|
pmp_addr, pmp_data);
|
||||||
pmp_addr++;
|
pmp_addr++;
|
||||||
xfer = 1;
|
xfer = 1;
|
||||||
}
|
}
|
||||||
|
@ -705,10 +687,10 @@ chan_write_byte(uint8 *data) {
|
||||||
if ((pmp_cnt & 0xf) == 0x4) { /* Split byte */
|
if ((pmp_cnt & 0xf) == 0x4) { /* Split byte */
|
||||||
pmp_data &= ~0xf;
|
pmp_data &= ~0xf;
|
||||||
pmp_data |= (uint64)((*data >> 4) & 0xf);
|
pmp_data |= (uint64)((*data >> 4) & 0xf);
|
||||||
if (pmp_addr >= (int)MEMSIZE)
|
if (Mem_write_word(pmp_addr, &pmp_data, 0))
|
||||||
return pmp_posterror(NXM_ERR);
|
return pmp_posterror(NXM_ERR);
|
||||||
M[pmp_addr] = pmp_data;
|
sim_debug(DEBUG_DETAIL, &pmp_dev, "chan_write %06o %012llo %2x\n",
|
||||||
sim_debug(DEBUG_DETAIL, &pmp_dev, "chan_write %06o %012llo %2x\n", pmp_addr, pmp_data, pmp_cnt);
|
pmp_addr, pmp_data, pmp_cnt);
|
||||||
pmp_addr++;
|
pmp_addr++;
|
||||||
xfer = 1; /* Read in a word */
|
xfer = 1; /* Read in a word */
|
||||||
pmp_data = *data & 0xf;
|
pmp_data = *data & 0xf;
|
||||||
|
@ -726,10 +708,10 @@ chan_write_byte(uint8 *data) {
|
||||||
pmp_cnt++;
|
pmp_cnt++;
|
||||||
if ((pmp_cnt & 0xf) == 9) {
|
if ((pmp_cnt & 0xf) == 9) {
|
||||||
pmp_cnt = BUFF_EMPTY;
|
pmp_cnt = BUFF_EMPTY;
|
||||||
if (pmp_addr >= (int)MEMSIZE)
|
if (Mem_write_word(pmp_addr, &pmp_data, 0))
|
||||||
return pmp_posterror(NXM_ERR);
|
return pmp_posterror(NXM_ERR);
|
||||||
M[pmp_addr] = pmp_data;
|
sim_debug(DEBUG_DETAIL, &pmp_dev, "chan_write %06o %012llo %2x\n",
|
||||||
sim_debug(DEBUG_DETAIL, &pmp_dev, "chan_write %06o %012llo %2x\n", pmp_addr, pmp_data, pmp_cnt);
|
pmp_addr, pmp_data, pmp_cnt);
|
||||||
pmp_addr++;
|
pmp_addr++;
|
||||||
xfer = 1; /* Read in a word */
|
xfer = 1; /* Read in a word */
|
||||||
}
|
}
|
||||||
|
@ -774,11 +756,10 @@ chan_end(uint8 flags) {
|
||||||
/* Flush buffer if there was any change */
|
/* Flush buffer if there was any change */
|
||||||
if (pmp_cnt & BUFF_DIRTY) {
|
if (pmp_cnt & BUFF_DIRTY) {
|
||||||
pmp_cnt = BUFF_EMPTY;
|
pmp_cnt = BUFF_EMPTY;
|
||||||
if (pmp_addr >= (int)MEMSIZE) {
|
if (Mem_write_word(pmp_addr, &pmp_data, 0)) {
|
||||||
(void) pmp_posterror(NXM_ERR);
|
(void) pmp_posterror(NXM_ERR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
M[pmp_addr] = pmp_data;
|
|
||||||
sim_debug(DEBUG_DATA, &pmp_dev, "chan_write %012llo\n", pmp_data);
|
sim_debug(DEBUG_DATA, &pmp_dev, "chan_write %012llo\n", pmp_data);
|
||||||
pmp_addr++;
|
pmp_addr++;
|
||||||
}
|
}
|
||||||
|
@ -792,7 +773,8 @@ chan_end(uint8 flags) {
|
||||||
/* If channel is also finished, then skip any more data commands. */
|
/* If channel is also finished, then skip any more data commands. */
|
||||||
if (pmp_status & (CHN_END|DEV_END)) {
|
if (pmp_status & (CHN_END|DEV_END)) {
|
||||||
pmp_cnt = BUFF_CHNEND;
|
pmp_cnt = BUFF_CHNEND;
|
||||||
sim_debug(DEBUG_DETAIL, &pmp_dev, "chan_endc %012llo %06o\n", pmp_status, pmp_cmd);
|
sim_debug(DEBUG_DETAIL, &pmp_dev, "chan_endc %012llo %06o\n",
|
||||||
|
pmp_status, pmp_cmd);
|
||||||
|
|
||||||
/* While command has chain data set, continue to skip */
|
/* While command has chain data set, continue to skip */
|
||||||
if (pmp_cmd & DATCH_ON) {
|
if (pmp_cmd & DATCH_ON) {
|
||||||
|
@ -808,7 +790,8 @@ chan_end(uint8 flags) {
|
||||||
/* Indicate that device is done */
|
/* Indicate that device is done */
|
||||||
pmp_statusb &= ~OP1;
|
pmp_statusb &= ~OP1;
|
||||||
}
|
}
|
||||||
sim_debug(DEBUG_DETAIL, &pmp_dev, "chan_endf %012llo %06o\n", pmp_status, pmp_statusb);
|
sim_debug(DEBUG_DETAIL, &pmp_dev, "chan_endf %012llo %06o\n",
|
||||||
|
pmp_status, pmp_statusb);
|
||||||
(void)pmp_checkirq();
|
(void)pmp_checkirq();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -959,7 +942,8 @@ pmp_startcmd() {
|
||||||
pmp_statusb &= ~IDLE_CH;
|
pmp_statusb &= ~IDLE_CH;
|
||||||
pmp_cur_unit->CMD &= ~(DK_PARAM);
|
pmp_cur_unit->CMD &= ~(DK_PARAM);
|
||||||
pmp_cur_unit->CMD |= cmd;
|
pmp_cur_unit->CMD |= cmd;
|
||||||
sim_debug(DEBUG_CMD, &pmp_dev, "CMD unit=%d CMD=%02x\n", unit, pmp_cur_unit->CMD);
|
sim_debug(DEBUG_CMD, &pmp_dev, "CMD unit=%d CMD=%02x\n", unit,
|
||||||
|
pmp_cur_unit->CMD);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0x0: /* Status */
|
case 0x0: /* Status */
|
||||||
|
@ -1233,8 +1217,8 @@ index:
|
||||||
/* Compute delay based of difference. */
|
/* Compute delay based of difference. */
|
||||||
/* Set next state = index */
|
/* Set next state = index */
|
||||||
i = (uptr->POS >> 8) - data->cyl;
|
i = (uptr->POS >> 8) - data->cyl;
|
||||||
sim_debug(DEBUG_DETAIL, dptr, "seek unit=%d %d %d s=%x\n", unit, uptr->POS >> 8, i,
|
sim_debug(DEBUG_DETAIL, dptr, "seek unit=%d %d %d s=%x\n", unit, uptr->POS >> 8,
|
||||||
data->state);
|
i, data->state);
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
uptr->CMD &= ~(DK_INDEX|DK_INDEX2);
|
uptr->CMD &= ~(DK_INDEX|DK_INDEX2);
|
||||||
data->state = DK_POS_INDEX;
|
data->state = DK_POS_INDEX;
|
||||||
|
@ -1256,8 +1240,8 @@ index:
|
||||||
sim_activate(uptr, 200);
|
sim_activate(uptr, 200);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sim_debug(DEBUG_DETAIL, dptr, "seek next unit=%d %d %d %x\n", unit, uptr->POS >> 8,
|
sim_debug(DEBUG_DETAIL, dptr, "seek next unit=%d %d %d %x\n", unit,
|
||||||
data->cyl, data->state);
|
uptr->POS >> 8, data->cyl, data->state);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1449,7 +1433,6 @@ sense_end:
|
||||||
uptr->CMD |= DK_PARAM;
|
uptr->CMD |= DK_PARAM;
|
||||||
data->state = DK_POS_SEEK;
|
data->state = DK_POS_SEEK;
|
||||||
sim_debug(DEBUG_DETAIL, dptr, "seek unit=%d doing\n", unit);
|
sim_debug(DEBUG_DETAIL, dptr, "seek unit=%d doing\n", unit);
|
||||||
// chan_end(SNS_CHNEND);
|
|
||||||
} else {
|
} else {
|
||||||
pmp_adjpos(uptr);
|
pmp_adjpos(uptr);
|
||||||
uptr->LASTCMD = cmd;
|
uptr->LASTCMD = cmd;
|
||||||
|
@ -1598,7 +1581,8 @@ sense_end:
|
||||||
if (state == DK_POS_CNT && count == 0) {
|
if (state == DK_POS_CNT && count == 0) {
|
||||||
sim_debug(DEBUG_DETAIL, dptr, "search ID unit=%d %x %d %x %d\n",
|
sim_debug(DEBUG_DETAIL, dptr, "search ID unit=%d %x %d %x %d\n",
|
||||||
unit, state, count, uptr->POS, data->rec);
|
unit, state, count, uptr->POS, data->rec);
|
||||||
sim_debug(DEBUG_DETAIL, dptr, "ID unit=%d %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
sim_debug(DEBUG_DETAIL, dptr,
|
||||||
|
"ID unit=%d %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||||
unit, da[0], da[1], da[2], da[3], da[4], da[5], da[6], da[7]);
|
unit, da[0], da[1], da[2], da[3], da[4], da[5], da[6], da[7]);
|
||||||
uptr->CMD &= ~(DK_SRCOK|DK_SHORTSRC|DK_NOEQ|DK_HIGH);
|
uptr->CMD &= ~(DK_SRCOK|DK_SHORTSRC|DK_NOEQ|DK_HIGH);
|
||||||
uptr->CMD |= DK_PARAM;
|
uptr->CMD |= DK_PARAM;
|
||||||
|
@ -1770,7 +1754,8 @@ sense_end:
|
||||||
if (count == 0 && state == DK_POS_CNT && data->rec != 0) {
|
if (count == 0 && state == DK_POS_CNT && data->rec != 0) {
|
||||||
uptr->CMD |= DK_PARAM;
|
uptr->CMD |= DK_PARAM;
|
||||||
uptr->CMD &= ~(DK_INDEX|DK_INDEX2);
|
uptr->CMD &= ~(DK_INDEX|DK_INDEX2);
|
||||||
sim_debug(DEBUG_DETAIL, dptr, "RD CKD unit=%d %d k=%d d=%d %02x %04x %04x\n",
|
sim_debug(DEBUG_DETAIL, dptr,
|
||||||
|
"RD CKD unit=%d %d k=%d d=%d %02x %04x %04x\n",
|
||||||
unit, data->rec, data->klen, data->dlen, data->state, data->dlen,
|
unit, data->rec, data->klen, data->dlen, data->state, data->dlen,
|
||||||
8 + data->klen + data->dlen);
|
8 + data->klen + data->dlen);
|
||||||
}
|
}
|
||||||
|
@ -2251,7 +2236,8 @@ pmp_attach(UNIT * uptr, CONST char *file)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (sim_fread(&hdr, 1, sizeof(struct pmp_header), uptr->fileref) !=
|
if (sim_fread(&hdr, 1, sizeof(struct pmp_header), uptr->fileref) !=
|
||||||
sizeof(struct pmp_header) || strncmp((CONST char *)&hdr.devid[0], "CKD_P370", 8) != 0 || flag) {
|
sizeof(struct pmp_header) || strncmp((CONST char *)&hdr.devid[0],
|
||||||
|
"CKD_P370", 8) != 0 || flag) {
|
||||||
if (pmp_format(uptr, flag)) {
|
if (pmp_format(uptr, flag)) {
|
||||||
detach_unit(uptr);
|
detach_unit(uptr);
|
||||||
return SCPE_FMT;
|
return SCPE_FMT;
|
||||||
|
@ -2292,12 +2278,14 @@ pmp_attach(UNIT * uptr, CONST char *file)
|
||||||
detach_unit(uptr);
|
detach_unit(uptr);
|
||||||
return SCPE_ARG;
|
return SCPE_ARG;
|
||||||
}
|
}
|
||||||
|
if ((sim_switches & SIM_SW_REST) == 0) {
|
||||||
(void)sim_fseek(uptr->fileref, sizeof(struct pmp_header), SEEK_SET);
|
(void)sim_fseek(uptr->fileref, sizeof(struct pmp_header), SEEK_SET);
|
||||||
(void)sim_fread(data->cbuf, 1, tsize, uptr->fileref);
|
(void)sim_fread(data->cbuf, 1, tsize, uptr->fileref);
|
||||||
data->cpos = sizeof(struct pmp_header);
|
data->cpos = sizeof(struct pmp_header);
|
||||||
data->ccyl = 0;
|
data->ccyl = 0;
|
||||||
uptr->CMD |= DK_ATTN;
|
uptr->CMD |= DK_ATTN;
|
||||||
pmp_statusb |= REQ_CH;
|
pmp_statusb |= REQ_CH;
|
||||||
|
}
|
||||||
sim_activate(uptr, 100);
|
sim_activate(uptr, 100);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -387,6 +387,7 @@ t_stat stk_devio(uint32 dev, uint64 *data)
|
||||||
|
|
||||||
static t_stat stk_reset (DEVICE *dptr)
|
static t_stat stk_reset (DEVICE *dptr)
|
||||||
{
|
{
|
||||||
|
if ((stk_dev.flags & DEV_DIS) == 0)
|
||||||
vid_display_kb_event_process = stk_keyboard;
|
vid_display_kb_event_process = stk_keyboard;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -239,7 +239,7 @@ static int transaction (unsigned char *request, unsigned char *response)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_word (int addr, int *data)
|
static int read_word (t_addr addr, int *data)
|
||||||
{
|
{
|
||||||
unsigned char request[8];
|
unsigned char request[8];
|
||||||
unsigned char response[8];
|
unsigned char response[8];
|
||||||
|
@ -285,7 +285,7 @@ static int read_word (int addr, int *data)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ten11_read (int addr, uint64 *data)
|
int ten11_read (t_addr addr, uint64 *data)
|
||||||
{
|
{
|
||||||
int offset = addr & 01777;
|
int offset = addr & 01777;
|
||||||
int word1, word2;
|
int word1, word2;
|
||||||
|
@ -328,7 +328,7 @@ int ten11_read (int addr, uint64 *data)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int write_word (int addr, uint16 data)
|
static int write_word (t_addr addr, uint16 data)
|
||||||
{
|
{
|
||||||
unsigned char request[8];
|
unsigned char request[8];
|
||||||
unsigned char response[8];
|
unsigned char response[8];
|
||||||
|
@ -366,7 +366,7 @@ static int write_word (int addr, uint16 data)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ten11_write (int addr, uint64 data)
|
int ten11_write (t_addr addr, uint64 data)
|
||||||
{
|
{
|
||||||
int offset = addr & 01777;
|
int offset = addr & 01777;
|
||||||
|
|
||||||
|
|
2484
PDP10/kl10_fe.c
Normal file
2484
PDP10/kl10_fe.c
Normal file
File diff suppressed because it is too large
Load diff
1674
PDP10/kl10_nia.c
Normal file
1674
PDP10/kl10_nia.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
||||||
/* ka10_cp.c: PDP10 Card Punch
|
/* kx10_cp.c: PDP10 Card Punch
|
||||||
|
|
||||||
Copyright (c) 2016-2017, Richard Cornwell
|
Copyright (c) 2016-2020, Richard Cornwell
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
4834
PDP10/kx10_cpu.c
4834
PDP10/kx10_cpu.c
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
||||||
/* ka10_cr.c: PDP10 Card reader.
|
/* kx10_cr.c: PDP10 Card reader.
|
||||||
|
|
||||||
Copyright (c) 2016-2017, Richard Cornwell
|
Copyright (c) 2016-2020, Richard Cornwell
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* ka10_cty.c: KA-10 front end (console terminal) simulator
|
/* kx10_cty.c: PDP6, KA-10 and KI-10 front end (console terminal) simulator
|
||||||
|
|
||||||
Copyright (c) 2013-2017, Richard Cornwell
|
Copyright (c) 2013-2020, Richard Cornwell
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -74,8 +74,13 @@ MTAB cty_mod[] = {
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
REG cty_reg[] = {
|
||||||
|
{ HRDATAD (WRU, sim_int_char, 8, "interrupt character") },
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
DEVICE cty_dev = {
|
DEVICE cty_dev = {
|
||||||
"CTY", cty_unit, NULL, cty_mod,
|
"CTY", cty_unit, cty_reg, cty_mod,
|
||||||
2, 10, 31, 1, 8, 8,
|
2, 10, 31, 1, 8, 8,
|
||||||
NULL, NULL, &cty_reset,
|
NULL, NULL, &cty_reset,
|
||||||
NULL, NULL, NULL, &cty_dib, DEV_DEBUG, 0, dev_debug,
|
NULL, NULL, NULL, &cty_dib, DEV_DEBUG, 0, dev_debug,
|
||||||
|
@ -154,6 +159,8 @@ t_stat ctyi_svc (UNIT *uptr)
|
||||||
|
|
||||||
sim_clock_coschedule (uptr, tmxr_poll);
|
sim_clock_coschedule (uptr, tmxr_poll);
|
||||||
/* continue poll */
|
/* continue poll */
|
||||||
|
if (uptr->STATUS & KEY_RDY)
|
||||||
|
return SCPE_OK;
|
||||||
if ((ch = sim_poll_kbd ()) < SCPE_KFLAG) /* no char or error? */
|
if ((ch = sim_poll_kbd ()) < SCPE_KFLAG) /* no char or error? */
|
||||||
return ch;
|
return ch;
|
||||||
if (ch & SCPE_BREAK) /* ignore break */
|
if (ch & SCPE_BREAK) /* ignore break */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* ka10_dc.c: PDP-10 DC10 communication server simulator
|
/* kx10_dc.c: PDP-10 DC10 communication server simulator
|
||||||
|
|
||||||
Copyright (c) 2011-2017, Richard Cornwell
|
Copyright (c) 2011-2020, Richard Cornwell
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* ka10_defs.h: PDP-10 simulator definitions
|
/* kx10_defs.h: PDP-10 simulator definitions
|
||||||
|
|
||||||
Copyright (c) 2011-2017, Richard Cornwell
|
Copyright (c) 2011-2020, Richard Cornwell
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -46,16 +46,12 @@
|
||||||
#define KI 0
|
#define KI 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef KLA
|
#ifndef KL
|
||||||
#define KLA 0
|
#define KL 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef KLB
|
#if KL
|
||||||
#define KLB 0
|
#define EPT440 0 /* Force KL10 to use as 440 section address */
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef KL /* Either KL10A or KL10B */
|
|
||||||
#define KL (KLA+KLB)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (PDP6 + KA + KI + KL) != 1
|
#if (PDP6 + KA + KI + KL) != 1
|
||||||
|
@ -81,10 +77,19 @@
|
||||||
#define WAITS KA
|
#define WAITS KA
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Support for ITS on KL */
|
||||||
|
#ifndef KL_ITS
|
||||||
|
#define KL_ITS KL
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef PDP6_DEV /* Include PDP6 devices */
|
#ifndef PDP6_DEV /* Include PDP6 devices */
|
||||||
#define PDP6_DEV PDP6|WAITS
|
#define PDP6_DEV PDP6|WAITS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef MAGIC_SWITCH /* Infamous MIT magic switch. */
|
||||||
|
#define MAGIC_SWITCH 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* MPX interrupt multiplexer for ITS systems */
|
/* MPX interrupt multiplexer for ITS systems */
|
||||||
#define MPX_DEV ITS
|
#define MPX_DEV ITS
|
||||||
|
@ -131,6 +136,10 @@ typedef t_uint64 uint64;
|
||||||
|
|
||||||
#define STOP_HALT 1 /* halted */
|
#define STOP_HALT 1 /* halted */
|
||||||
#define STOP_IBKPT 2 /* breakpoint */
|
#define STOP_IBKPT 2 /* breakpoint */
|
||||||
|
#define STOP_ACCESS 3 /* invalid access */
|
||||||
|
#if MAGIC_SWITCH
|
||||||
|
#define STOP_MAGIC 4 /* low on magic */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Debuging controls */
|
/* Debuging controls */
|
||||||
#define DEBUG_CMD 0x0000001 /* Show device commands */
|
#define DEBUG_CMD 0x0000001 /* Show device commands */
|
||||||
|
@ -161,12 +170,19 @@ extern DEBTAB crd_debug[];
|
||||||
#define XMASK 03777777777777LL
|
#define XMASK 03777777777777LL
|
||||||
#define EMASK 00777000000000LL
|
#define EMASK 00777000000000LL
|
||||||
#define MMASK 00000777777777LL
|
#define MMASK 00000777777777LL
|
||||||
|
#define SECTM 00007777000000LL
|
||||||
#define BIT1 00200000000000LL
|
#define BIT1 00200000000000LL
|
||||||
|
#define BIT2 00100000000000LL
|
||||||
|
#define BIT3 00040000000000LL
|
||||||
|
#define BIT4 00020000000000LL
|
||||||
|
#define BIT5 00010000000000LL
|
||||||
|
#define BIT6 00004000000000LL
|
||||||
#define BIT7 00002000000000LL
|
#define BIT7 00002000000000LL
|
||||||
#define BIT8 00001000000000LL
|
#define BIT8 00001000000000LL
|
||||||
#define BIT9 00000400000000LL
|
#define BIT9 00000400000000LL
|
||||||
#define BIT10 00000200000000LL
|
#define BIT10 00000200000000LL
|
||||||
#define BIT10_35 00000377777777LL
|
#define BIT10_35 00000377777777LL
|
||||||
|
#define BIT12 00000040000000LL
|
||||||
#define BIT17 00000001000000LL
|
#define BIT17 00000001000000LL
|
||||||
#define MANT 00000777777777LL
|
#define MANT 00000777777777LL
|
||||||
#define EXPO 00377000000000LL
|
#define EXPO 00377000000000LL
|
||||||
|
@ -181,6 +197,7 @@ extern DEBTAB crd_debug[];
|
||||||
#define FPRBIT1 00000000000200000000000LL
|
#define FPRBIT1 00000000000200000000000LL
|
||||||
|
|
||||||
#define CM(x) (FMASK ^ (x))
|
#define CM(x) (FMASK ^ (x))
|
||||||
|
#define CCM(x) ((CMASK ^ (x)) & CMASK)
|
||||||
|
|
||||||
#define INST_V_OP 27 /* opcode */
|
#define INST_V_OP 27 /* opcode */
|
||||||
#define INST_M_OP 0777
|
#define INST_M_OP 0777
|
||||||
|
@ -205,6 +222,8 @@ extern DEBTAB crd_debug[];
|
||||||
#define LRZ(x) (((x) >> 18) & RMASK)
|
#define LRZ(x) (((x) >> 18) & RMASK)
|
||||||
#define JRST1 (((uint64)OP_JRST << 27) + 1)
|
#define JRST1 (((uint64)OP_JRST << 27) + 1)
|
||||||
|
|
||||||
|
#define OP_PORTAL(x) (((x) & 00777740000000LL) == 0254040000000LL)
|
||||||
|
|
||||||
#if PDP6
|
#if PDP6
|
||||||
#define NODIV 000000
|
#define NODIV 000000
|
||||||
#define FLTUND 000000
|
#define FLTUND 000000
|
||||||
|
@ -275,6 +294,12 @@ extern DEBTAB crd_debug[];
|
||||||
#define AMASK 00000017777777LL
|
#define AMASK 00000017777777LL
|
||||||
#define WMASK 0037777LL
|
#define WMASK 0037777LL
|
||||||
#define CSHIFT 22
|
#define CSHIFT 22
|
||||||
|
#if KL
|
||||||
|
#define RH20_WMASK 003777LL
|
||||||
|
#define RH20_XFER SMASK
|
||||||
|
#define RH20_HALT BIT1
|
||||||
|
#define RH20_REV BIT2
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#define AMASK RMASK
|
#define AMASK RMASK
|
||||||
#define WMASK RMASK
|
#define WMASK RMASK
|
||||||
|
@ -285,11 +310,19 @@ extern DEBTAB crd_debug[];
|
||||||
#define PI_ENABLE 0000000010 /* Clear DONE */
|
#define PI_ENABLE 0000000010 /* Clear DONE */
|
||||||
#define BUSY 0000000020 /* STOP */
|
#define BUSY 0000000020 /* STOP */
|
||||||
#define CCW_COMP 0000000040 /* Write Final CCW */
|
#define CCW_COMP 0000000040 /* Write Final CCW */
|
||||||
|
/* RH10 / RH20 interrupt */
|
||||||
|
#define IADR_ATTN 0000000000040LL /* Interrupt on attention */
|
||||||
|
#define IARD_RAE 0000000000100LL /* Interrupt on register access error */
|
||||||
|
#define CCW_COMP_1 0000000040000LL /* Control word written. */
|
||||||
|
|
||||||
#if KI
|
#if KI
|
||||||
#define DEF_SERIAL 514 /* Default DEC test machine */
|
#define DEF_SERIAL 514 /* Default DEC test machine */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if KL
|
||||||
|
#define DEF_SERIAL 1025 /* Default DEC test machine */
|
||||||
|
#endif
|
||||||
|
|
||||||
#if BBN
|
#if BBN
|
||||||
#define BBN_PAGE 0000017777777LL
|
#define BBN_PAGE 0000017777777LL
|
||||||
#define BBN_TRPPG 0000017000000LL
|
#define BBN_TRPPG 0000017000000LL
|
||||||
|
@ -306,13 +339,36 @@ extern DEBTAB crd_debug[];
|
||||||
#define BBN_MERGE 0161740000000LL
|
#define BBN_MERGE 0161740000000LL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if KL
|
||||||
|
/* KL10 TLB paging bits */
|
||||||
|
#define KL_PAG_A 0400000 /* Access */
|
||||||
|
#define KL_PAG_P 0200000 /* Public */
|
||||||
|
#define KL_PAG_W 0100000 /* Writable (M Tops 20) */
|
||||||
|
#define KL_PAG_S 0040000 /* Software (W Writable Tops 20) */
|
||||||
|
#define KL_PAG_C 0020000 /* Cacheable */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if KI
|
||||||
|
/* KI10 TLB paging bits */
|
||||||
|
#define KI_PAG_A 0400000 /* Access */
|
||||||
|
#define KI_PAG_P 0200000 /* Public */
|
||||||
|
#define KI_PAG_W 0100000 /* Writable */
|
||||||
|
#define KI_PAG_S 0040000 /* Software */
|
||||||
|
#define KI_PAG_X 0020000 /* Reserved */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Flags for CPU unit */
|
/* Flags for CPU unit */
|
||||||
#define UNIT_V_MSIZE (UNIT_V_UF + 0)
|
#define UNIT_V_MSIZE (UNIT_V_UF + 0)
|
||||||
#define UNIT_MSIZE (0177 << UNIT_V_MSIZE)
|
#define UNIT_MSIZE (0177 << UNIT_V_MSIZE)
|
||||||
#define UNIT_V_MAOFF (UNIT_V_MSIZE + 8)
|
#define UNIT_V_MAOFF (UNIT_V_MSIZE + 8)
|
||||||
#define UNIT_V_PAGE (UNIT_V_MAOFF + 1)
|
#define UNIT_V_PAGE (UNIT_V_MAOFF + 1)
|
||||||
#define UNIT_MAOFF (1 << UNIT_V_MAOFF)
|
#define UNIT_MAOFF (1 << UNIT_V_MAOFF)
|
||||||
|
#if KL
|
||||||
|
#define UNIT_KL10B (1 << UNIT_V_PAGE)
|
||||||
|
#define UNIT_TWOSEG (0)
|
||||||
|
#else
|
||||||
#define UNIT_TWOSEG (1 << UNIT_V_PAGE)
|
#define UNIT_TWOSEG (1 << UNIT_V_PAGE)
|
||||||
|
#endif
|
||||||
#define UNIT_ITSPAGE (2 << UNIT_V_PAGE)
|
#define UNIT_ITSPAGE (2 << UNIT_V_PAGE)
|
||||||
#define UNIT_BBNPAGE (4 << UNIT_V_PAGE)
|
#define UNIT_BBNPAGE (4 << UNIT_V_PAGE)
|
||||||
#define UNIT_M_PAGE (007 << UNIT_V_PAGE)
|
#define UNIT_M_PAGE (007 << UNIT_V_PAGE)
|
||||||
|
@ -322,7 +378,29 @@ extern DEBTAB crd_debug[];
|
||||||
#define UNIT_V_MPX (UNIT_V_WAITS + 1)
|
#define UNIT_V_MPX (UNIT_V_WAITS + 1)
|
||||||
#define UNIT_M_MPX (1 << UNIT_V_MPX)
|
#define UNIT_M_MPX (1 << UNIT_V_MPX)
|
||||||
#define UNIT_MPX (UNIT_M_MPX) /* MPX Device for ITS */
|
#define UNIT_MPX (UNIT_M_MPX) /* MPX Device for ITS */
|
||||||
|
#define CNTRL_V_RH (UNIT_V_UF + 4)
|
||||||
|
#define CNTRL_M_RH 7
|
||||||
|
#define GET_CNTRL_RH(x) (((x) >> CNTRL_V_RH) & CNTRL_M_RH)
|
||||||
|
#define CNTRL_RH(x) (((x) & CNTRL_M_RH) << CNTRL_V_RH)
|
||||||
|
#define DEV_V_RH (DEV_V_UF + 1) /* Type RH20 */
|
||||||
|
#define DEV_M_RH (1 << DEV_V_RH)
|
||||||
|
#define TYPE_RH10 (0 << DEV_V_RH)
|
||||||
|
#define TYPE_RH20 (1 << DEV_V_RH)
|
||||||
|
|
||||||
|
#if KL
|
||||||
|
/* DTE memory access functions, n = DTE# */
|
||||||
|
extern int Mem_examine_word(int n, int wrd, uint64 *data);
|
||||||
|
extern int Mem_deposit_word(int n, int wrd, uint64 *data);
|
||||||
|
extern int Mem_read_byte(int n, uint16 *data, int byte);
|
||||||
|
extern int Mem_write_byte(int n, uint16 *data);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Access main memory. Returns 0 if access ok, 1 if out of memory range.
|
||||||
|
* On KI10 and KL10, optional EPT flag indicates address relative to ept.
|
||||||
|
*/
|
||||||
|
extern int Mem_read_word(t_addr addr, uint64 *data, int ept);
|
||||||
|
extern int Mem_write_word(t_addr addr, uint64 *data, int ept);
|
||||||
|
|
||||||
#if MPX_DEV
|
#if MPX_DEV
|
||||||
extern void set_interrupt_mpx(int dev, int lvl, int mpx);
|
extern void set_interrupt_mpx(int dev, int lvl, int mpx);
|
||||||
|
@ -337,9 +415,15 @@ extern void restore_pi_hold();
|
||||||
extern void set_pi_hold();
|
extern void set_pi_hold();
|
||||||
extern UNIT cpu_unit[];
|
extern UNIT cpu_unit[];
|
||||||
extern UNIT ten11_unit[];
|
extern UNIT ten11_unit[];
|
||||||
extern UNIT auxcpu_unit[];
|
#if KL
|
||||||
extern DEVICE cpu_dev;
|
extern DEVICE dte_dev;
|
||||||
|
extern DEVICE lp20_dev;
|
||||||
|
extern DEVICE tty_dev;
|
||||||
|
extern DEVICE nia_dev;
|
||||||
|
#else
|
||||||
extern DEVICE cty_dev;
|
extern DEVICE cty_dev;
|
||||||
|
#endif
|
||||||
|
extern DEVICE cpu_dev;
|
||||||
extern DEVICE mt_dev;
|
extern DEVICE mt_dev;
|
||||||
extern DEVICE dpa_dev;
|
extern DEVICE dpa_dev;
|
||||||
extern DEVICE dpb_dev;
|
extern DEVICE dpb_dev;
|
||||||
|
@ -365,6 +449,7 @@ extern DEVICE pmp_dev;
|
||||||
extern DEVICE dk_dev;
|
extern DEVICE dk_dev;
|
||||||
extern DEVICE pd_dev;
|
extern DEVICE pd_dev;
|
||||||
extern DEVICE dpy_dev;
|
extern DEVICE dpy_dev;
|
||||||
|
extern DEVICE iii_dev;
|
||||||
extern DEVICE imx_dev;
|
extern DEVICE imx_dev;
|
||||||
extern DEVICE imp_dev;
|
extern DEVICE imp_dev;
|
||||||
extern DEVICE ch10_dev;
|
extern DEVICE ch10_dev;
|
||||||
|
@ -374,8 +459,10 @@ extern DEVICE mty_dev;
|
||||||
extern DEVICE ten11_dev;
|
extern DEVICE ten11_dev;
|
||||||
extern DEVICE dkb_dev;
|
extern DEVICE dkb_dev;
|
||||||
extern DEVICE auxcpu_dev;
|
extern DEVICE auxcpu_dev;
|
||||||
|
extern DEVICE slave_dev;
|
||||||
extern DEVICE dpk_dev;
|
extern DEVICE dpk_dev;
|
||||||
extern DEVICE wcnsls_dev; /* MIT Spacewar Consoles */
|
extern DEVICE wcnsls_dev; /* MIT Spacewar Consoles */
|
||||||
|
extern DEVICE ocnsls_dev; /* Old MIT Spacewar Consoles */
|
||||||
extern DEVICE ai_dev;
|
extern DEVICE ai_dev;
|
||||||
extern DEVICE dct_dev; /* PDP6 devices. */
|
extern DEVICE dct_dev; /* PDP6 devices. */
|
||||||
extern DEVICE dtc_dev;
|
extern DEVICE dtc_dev;
|
||||||
|
@ -387,41 +474,67 @@ extern t_stat (*dev_tab[128])(uint32 dev, t_uint64 *data);
|
||||||
|
|
||||||
#define VEC_DEVMAX 8 /* max device vec */
|
#define VEC_DEVMAX 8 /* max device vec */
|
||||||
|
|
||||||
|
/* DF10 Interface */
|
||||||
|
struct df10 {
|
||||||
|
uint32 status; /* DF10 status word */
|
||||||
|
uint32 cia; /* Initial transfer address */
|
||||||
|
uint32 ccw; /* Next control word address */
|
||||||
|
uint32 wcr; /* CUrrent word count */
|
||||||
|
uint32 cda; /* Current transfer address */
|
||||||
|
uint32 devnum; /* Device number */
|
||||||
|
t_uint64 buf; /* Data buffer */
|
||||||
|
uint8 nxmerr; /* Bit to set for NXM */
|
||||||
|
uint8 ccw_comp; /* Have we written out CCW */
|
||||||
|
} ;
|
||||||
|
|
||||||
|
/* RH10/RH20 Interface */
|
||||||
|
struct rh_if {
|
||||||
|
void (*dev_write)(DEVICE *dptr, struct rh_if *rh, int reg, uint32 data);
|
||||||
|
uint32 (*dev_read)(DEVICE *dptr, struct rh_if *rh, int reg);
|
||||||
|
void (*dev_reset)(DEVICE *dptr);
|
||||||
|
t_uint64 buf; /* Data buffer */
|
||||||
|
uint32 status; /* DF10 status word */
|
||||||
|
uint32 cia; /* Initial transfer address */
|
||||||
|
uint32 ccw; /* Current word count */
|
||||||
|
uint32 wcr;
|
||||||
|
uint32 cda; /* Current transfer address */
|
||||||
|
uint32 devnum; /* Device number */
|
||||||
|
int ivect; /* Interrupt vector */
|
||||||
|
uint8 imode; /* Mode of vector */
|
||||||
|
int cop; /* RH20 Channel operator */
|
||||||
|
uint32 sbar; /* RH20 Starting address */
|
||||||
|
uint32 stcr; /* RH20 Count */
|
||||||
|
uint32 pbar;
|
||||||
|
uint32 ptcr;
|
||||||
|
int reg; /* Last register selected */
|
||||||
|
int drive; /* Last drive selected */
|
||||||
|
int rae; /* Access register error */
|
||||||
|
int attn; /* Attention bits */
|
||||||
|
int xfer_drive; /* Current transfering drive */
|
||||||
|
};
|
||||||
|
|
||||||
/* Device context block */
|
/* Device context block */
|
||||||
struct pdp_dib {
|
struct pdp_dib {
|
||||||
uint32 dev_num; /* device address */
|
uint32 dev_num; /* device address */
|
||||||
uint32 num_devs; /* length */
|
uint32 num_devs; /* length */
|
||||||
t_stat (*io)(uint32 dev, t_uint64 *data);
|
t_stat (*io)(uint32 dev, t_uint64 *data);
|
||||||
int (*irq)(uint32 dev, int addr);
|
t_addr (*irq)(uint32 dev, t_addr addr);
|
||||||
|
struct rh_if *rh;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define RH10_DEV 01000
|
#define RH10_DEV 01000
|
||||||
|
#define RH20_DEV 02000
|
||||||
struct rh_dev {
|
struct rh_dev {
|
||||||
uint32 dev_num;
|
uint32 dev_num;
|
||||||
DEVICE *dev;
|
DEVICE *dev;
|
||||||
|
struct rh_if *rh;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef struct pdp_dib DIB;
|
typedef struct pdp_dib DIB;
|
||||||
|
|
||||||
|
void df10_setirq(struct df10 *df);
|
||||||
/* DF10 Interface */
|
void df10_writecw(struct df10 *df);
|
||||||
struct df10 {
|
void df10_finish_op(struct df10 *df, int flags);
|
||||||
uint32 status;
|
|
||||||
uint32 cia;
|
|
||||||
uint32 ccw;
|
|
||||||
uint32 wcr;
|
|
||||||
uint32 cda;
|
|
||||||
uint32 devnum;
|
|
||||||
t_uint64 buf;
|
|
||||||
uint8 nxmerr;
|
|
||||||
uint8 ccw_comp;
|
|
||||||
} ;
|
|
||||||
|
|
||||||
|
|
||||||
void df10_setirq(struct df10 *df) ;
|
|
||||||
void df10_writecw(struct df10 *df) ;
|
|
||||||
void df10_finish_op(struct df10 *df, int flags) ;
|
|
||||||
void df10_setup(struct df10 *df, uint32 addr);
|
void df10_setup(struct df10 *df, uint32 addr);
|
||||||
int df10_fetch(struct df10 *df);
|
int df10_fetch(struct df10 *df);
|
||||||
int df10_read(struct df10 *df);
|
int df10_read(struct df10 *df);
|
||||||
|
@ -432,8 +545,27 @@ int dct_write(int u, t_uint64 *data, int c);
|
||||||
int dct_is_connect(int u);
|
int dct_is_connect(int u);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int ten11_read (int addr, t_uint64 *data);
|
/* Define RH10/RH20 functions */
|
||||||
int ten11_write (int addr, t_uint64 data);
|
t_stat rh_set_type(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
||||||
|
t_stat rh_show_type (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
||||||
|
t_stat rh_devio(uint32 dev, t_uint64 *data);
|
||||||
|
t_addr rh_devirq(uint32 dev, t_addr addr);
|
||||||
|
#if KL
|
||||||
|
void rh20_setup(struct rh_if *rhc);
|
||||||
|
#endif
|
||||||
|
void rh_setup(struct rh_if *rh, uint32 addr);
|
||||||
|
void rh_setattn(struct rh_if *rh, int unit);
|
||||||
|
void rh_error(struct rh_if *rh);
|
||||||
|
int rh_blkend(struct rh_if *rh);
|
||||||
|
void rh_setirq(struct rh_if *rh);
|
||||||
|
void rh_writecw(struct rh_if *rh, int nxm);
|
||||||
|
void rh_finish_op(struct rh_if *rh, int flags);
|
||||||
|
int rh_read(struct rh_if *rh);
|
||||||
|
int rh_write(struct rh_if *rh);
|
||||||
|
|
||||||
|
|
||||||
|
int ten11_read (t_addr addr, t_uint64 *data);
|
||||||
|
int ten11_write (t_addr addr, t_uint64 data);
|
||||||
|
|
||||||
/* Console lights. */
|
/* Console lights. */
|
||||||
extern void ka10_lights_init (void);
|
extern void ka10_lights_init (void);
|
||||||
|
@ -441,36 +573,57 @@ extern void ka10_lights_main (t_uint64);
|
||||||
extern void ka10_lights_set_aux (int);
|
extern void ka10_lights_set_aux (int);
|
||||||
extern void ka10_lights_clear_aux (int);
|
extern void ka10_lights_clear_aux (int);
|
||||||
|
|
||||||
int auxcpu_read (int addr, t_uint64 *);
|
|
||||||
int auxcpu_write (int addr, t_uint64);
|
|
||||||
|
|
||||||
/* I/O system parameters */
|
/* I/O system parameters */
|
||||||
#define NUM_DEVS_LP 1
|
#define NUM_DEVS_LP 1
|
||||||
|
#if KL
|
||||||
|
#define NUM_DEVS_PT 0
|
||||||
|
#define NUM_DEVS_CR 0
|
||||||
|
#define NUM_DEVS_CP 0
|
||||||
|
#else
|
||||||
#define NUM_DEVS_PT 1
|
#define NUM_DEVS_PT 1
|
||||||
#define NUM_DEVS_CR 1
|
#define NUM_DEVS_CR 1
|
||||||
#define NUM_DEVS_CP 1
|
#define NUM_DEVS_CP 1
|
||||||
|
#endif
|
||||||
#define NUM_DEVS_DPY USE_DISPLAY
|
#define NUM_DEVS_DPY USE_DISPLAY
|
||||||
#define NUM_DEVS_WCNSLS USE_DISPLAY
|
#define NUM_DEVS_WCNSLS USE_DISPLAY
|
||||||
|
#define NUM_DEVS_OCNSLS USE_DISPLAY
|
||||||
#if PDP6_DEV
|
#if PDP6_DEV
|
||||||
#define NUM_DEVS_DTC 1
|
#define NUM_DEVS_DTC 1
|
||||||
#define NUM_DEVS_DCT 2
|
#define NUM_DEVS_DCT 2
|
||||||
#define NUM_DEVS_MTC 1
|
#define NUM_DEVS_MTC 1
|
||||||
#define NUM_DEVS_DSK 1
|
#define NUM_DEVS_DSK 1
|
||||||
#define NUM_DEVS_DCS 1
|
#define NUM_DEVS_DCS 1
|
||||||
|
#define NUM_DEVS_SLAVE PDP6
|
||||||
#endif
|
#endif
|
||||||
#if !PDP6
|
#if !PDP6
|
||||||
#define NUM_DEVS_DC 1
|
#define NUM_DEVS_DC 1
|
||||||
#define NUM_DEVS_MT 1
|
#define NUM_DEVS_MT 1
|
||||||
|
#if KL
|
||||||
|
#define NUM_DEVS_RC 0
|
||||||
|
#define NUM_DEVS_DT 0
|
||||||
|
#define NUM_DEVS_DK 0
|
||||||
|
#define NUM_DEVS_DP 0
|
||||||
|
#define NUM_DEVS_LP20 1
|
||||||
|
#define NUM_DEVS_TTY 1
|
||||||
|
#define NUM_LINES_TTY 40
|
||||||
|
#define NUM_DEVS_NIA 1
|
||||||
|
#else
|
||||||
#define NUM_DEVS_RC 1
|
#define NUM_DEVS_RC 1
|
||||||
#define NUM_DEVS_DT 1
|
#define NUM_DEVS_DT 1
|
||||||
#define NUM_DEVS_DK 1
|
#define NUM_DEVS_DK 1
|
||||||
#define NUM_DEVS_DP 2
|
#define NUM_DEVS_DP 2
|
||||||
|
#define NUM_DEVS_LP20 0
|
||||||
|
#define NUM_DEVS_TTY 0
|
||||||
|
#define NUM_DEVS_NIA 0
|
||||||
|
#endif
|
||||||
#define NUM_DEVS_RP 4
|
#define NUM_DEVS_RP 4
|
||||||
#define NUM_DEVS_RS 1
|
#define NUM_DEVS_RS 1
|
||||||
#define NUM_DEVS_TU 1
|
#define NUM_DEVS_TU 1
|
||||||
#define NUM_DEVS_PMP WAITS
|
#define NUM_DEVS_PMP WAITS
|
||||||
#define NUM_DEVS_DKB WAITS
|
#define NUM_DEVS_DKB (WAITS * USE_DISPLAY)
|
||||||
#define NUM_DEVS_PD ITS
|
#define NUM_DEVS_III (WAITS * USE_DISPLAY)
|
||||||
|
#define NUM_DEVS_PD ITS | KL_ITS
|
||||||
#define NUM_DEVS_IMX ITS
|
#define NUM_DEVS_IMX ITS
|
||||||
#define NUM_DEVS_STK ITS
|
#define NUM_DEVS_STK ITS
|
||||||
#define NUM_DEVS_TK10 ITS
|
#define NUM_DEVS_TK10 ITS
|
||||||
|
@ -478,10 +631,14 @@ int auxcpu_write (int addr, t_uint64);
|
||||||
#define NUM_DEVS_TEN11 ITS
|
#define NUM_DEVS_TEN11 ITS
|
||||||
#define NUM_DEVS_AUXCPU ITS
|
#define NUM_DEVS_AUXCPU ITS
|
||||||
#define NUM_DEVS_IMP 1
|
#define NUM_DEVS_IMP 1
|
||||||
#define NUM_DEVS_CH10 ITS
|
#define NUM_DEVS_CH10 ITS | KL_ITS
|
||||||
#define NUM_DEVS_DPK ITS
|
#define NUM_DEVS_DPK ITS
|
||||||
#define NUM_DEVS_AI ITS
|
#define NUM_DEVS_AI ITS
|
||||||
#endif
|
#endif
|
||||||
|
#if MAGIC_SWITCH && !KA && !ITS
|
||||||
|
#error "Magic switch only valid on KA10 with ITS mods"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Global data */
|
/* Global data */
|
||||||
|
|
||||||
|
|
||||||
|
@ -492,4 +649,16 @@ extern t_uint64 FM[];
|
||||||
extern uint32 PC;
|
extern uint32 PC;
|
||||||
extern uint32 FLAGS;
|
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
|
#endif
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* ka10_df.c: DF10 common routines.
|
/* kx10_df.c: DF10 common routines.
|
||||||
|
|
||||||
Copyright (c) 2015-2017, Richard Cornwell
|
Copyright (c) 2015-2020, Richard Cornwell
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -23,18 +23,24 @@
|
||||||
|
|
||||||
#include "kx10_defs.h"
|
#include "kx10_defs.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Set an IRQ for a DF10 device */
|
||||||
void df10_setirq(struct df10 *df) {
|
void df10_setirq(struct df10 *df) {
|
||||||
df->status |= PI_ENABLE;
|
df->status |= PI_ENABLE;
|
||||||
set_interrupt(df->devnum, df->status);
|
set_interrupt(df->devnum, df->status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Generate the DF10 complete word */
|
||||||
void df10_writecw(struct df10 *df) {
|
void df10_writecw(struct df10 *df) {
|
||||||
|
uint64 wrd;
|
||||||
df->status |= 1 << df->ccw_comp;
|
df->status |= 1 << df->ccw_comp;
|
||||||
if (df->wcr != 0)
|
if (df->wcr != 0)
|
||||||
df->cda++;
|
df->cda++;
|
||||||
M[df->cia|1] = ((uint64)(df->ccw & WMASK) << CSHIFT) | ((uint64)(df->cda) & AMASK);
|
wrd = ((uint64)(df->ccw & WMASK) << CSHIFT) | ((uint64)(df->cda) & AMASK);
|
||||||
|
(void)Mem_write_word(df->cia|1, &wrd, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Finish off a DF10 transfer */
|
||||||
void df10_finish_op(struct df10 *df, int flags) {
|
void df10_finish_op(struct df10 *df, int flags) {
|
||||||
df->status &= ~BUSY;
|
df->status &= ~BUSY;
|
||||||
df->status |= flags;
|
df->status |= flags;
|
||||||
|
@ -42,6 +48,7 @@ void df10_finish_op(struct df10 *df, int flags) {
|
||||||
df10_setirq(df);
|
df10_setirq(df);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Setup for a DF10 transfer */
|
||||||
void df10_setup(struct df10 *df, uint32 addr) {
|
void df10_setup(struct df10 *df, uint32 addr) {
|
||||||
df->cia = addr & ICWA;
|
df->cia = addr & ICWA;
|
||||||
df->ccw = df->cia;
|
df->ccw = df->cia;
|
||||||
|
@ -50,24 +57,23 @@ void df10_setup(struct df10 *df, uint32 addr) {
|
||||||
df->status &= ~(1 << df->ccw_comp);
|
df->status &= ~(1 << df->ccw_comp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fetch the next IO control word */
|
||||||
int df10_fetch(struct df10 *df) {
|
int df10_fetch(struct df10 *df) {
|
||||||
uint64 data;
|
uint64 data;
|
||||||
if (df->ccw > MEMSIZE) {
|
if (Mem_read_word(df->ccw, &data, 0)) {
|
||||||
df10_finish_op(df, df->nxmerr);
|
df10_finish_op(df, df->nxmerr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
data = M[df->ccw];
|
|
||||||
while((data & (WMASK << CSHIFT)) == 0) {
|
while((data & (WMASK << CSHIFT)) == 0) {
|
||||||
if ((data & AMASK) == 0 || (uint32)(data & AMASK) == df->ccw) {
|
if ((data & AMASK) == 0 || (uint32)(data & AMASK) == df->ccw) {
|
||||||
df10_finish_op(df,0);
|
df10_finish_op(df,0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
df->ccw = (uint32)(data & AMASK);
|
df->ccw = (uint32)(data & AMASK);
|
||||||
if (df->ccw > MEMSIZE) {
|
if (Mem_read_word(df->ccw, &data, 0)) {
|
||||||
df10_finish_op(df, 1<<df->nxmerr);
|
df10_finish_op(df, 1<<df->nxmerr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
data = M[df->ccw];
|
|
||||||
}
|
}
|
||||||
#if KA & ITS
|
#if KA & ITS
|
||||||
if (cpu_unit[0].flags & UNIT_ITSPAGE) {
|
if (cpu_unit[0].flags & UNIT_ITSPAGE) {
|
||||||
|
@ -84,6 +90,7 @@ int df10_fetch(struct df10 *df) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Read next word */
|
||||||
int df10_read(struct df10 *df) {
|
int df10_read(struct df10 *df) {
|
||||||
uint64 data;
|
uint64 data;
|
||||||
if (df->wcr == 0) {
|
if (df->wcr == 0) {
|
||||||
|
@ -102,7 +109,10 @@ int df10_read(struct df10 *df) {
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
df->cda = (uint32)((df->cda + 1) & AMASK);
|
df->cda = (uint32)((df->cda + 1) & AMASK);
|
||||||
data = M[df->cda];
|
if (Mem_read_word(df->cda, &data, 0)) {
|
||||||
|
df10_finish_op(df, 1<<df->nxmerr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
data = 0;
|
data = 0;
|
||||||
}
|
}
|
||||||
|
@ -113,6 +123,7 @@ int df10_read(struct df10 *df) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Write next word */
|
||||||
int df10_write(struct df10 *df) {
|
int df10_write(struct df10 *df) {
|
||||||
if (df->wcr == 0) {
|
if (df->wcr == 0) {
|
||||||
if (!df10_fetch(df))
|
if (!df10_fetch(df))
|
||||||
|
@ -130,7 +141,10 @@ int df10_write(struct df10 *df) {
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
df->cda = (uint32)((df->cda + 1) & AMASK);
|
df->cda = (uint32)((df->cda + 1) & AMASK);
|
||||||
M[df->cda] = df->buf;
|
if (Mem_write_word(df->cda, &df->buf, 0)) {
|
||||||
|
df10_finish_op(df, 1<<df->nxmerr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (df->wcr == 0) {
|
if (df->wcr == 0) {
|
||||||
return df10_fetch(df);
|
return df10_fetch(df);
|
||||||
|
|
289
PDP10/kx10_disk.c
Normal file
289
PDP10/kx10_disk.c
Normal file
|
@ -0,0 +1,289 @@
|
||||||
|
/* kx10_disk.c: Disk translator.
|
||||||
|
|
||||||
|
Copyright (c) 2020, Richard Cornwell
|
||||||
|
|
||||||
|
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
|
||||||
|
RICHARD CORNWELL 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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "kx10_defs.h"
|
||||||
|
#include "kx10_disk.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SIMH format is number words per sector stored as a 64 bit word.
|
||||||
|
*
|
||||||
|
* DBD9 format is: 9 character per pair of words.
|
||||||
|
*
|
||||||
|
* 0 - B0 1 2 3 4 5 6 7
|
||||||
|
* 0 - 8 9 10 11 12 13 14 15
|
||||||
|
* 0 - 16 17 18 19 20 21 22 23
|
||||||
|
* 0 - 24 25 26 27 28 29 30 31
|
||||||
|
* 0 - 32 33 34 35 B0 1 2 3
|
||||||
|
* 1 - 4 5 6 7 8 9 10 11
|
||||||
|
* 1 - 12 13 14 15 16 17 18 19
|
||||||
|
* 1 - 20 21 22 23 24 25 26 27
|
||||||
|
* 1 - 28 29 30 31 32 33 34 35
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* DLD9 format is: 9 character per pair of words.
|
||||||
|
*
|
||||||
|
* 0 - 28 29 30 31 32 33 34 35
|
||||||
|
* 0 - 20 21 22 23 24 25 26 27
|
||||||
|
* 0 - 12 13 14 15 16 17 18 19
|
||||||
|
* 0 - 4 5 6 7 8 9 10 11
|
||||||
|
* 0 - 32 33 34 35 B0 1 2 3
|
||||||
|
* 1 - 24 25 26 27 28 29 30 31
|
||||||
|
* 1 - 16 17 18 19 20 21 22 23
|
||||||
|
* 1 - 8 9 10 11 12 13 14 15
|
||||||
|
* 1 - B0 1 2 3 4 5 6 7
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
struct disk_formats {
|
||||||
|
uint32 mode;
|
||||||
|
const char *name;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct disk_formats fmts[] = {
|
||||||
|
{SIMH, "SIMH"},
|
||||||
|
{DBD9, "DBD9"},
|
||||||
|
{DLD9, "DLD9"},
|
||||||
|
{0, 0},
|
||||||
|
};
|
||||||
|
|
||||||
|
t_stat
|
||||||
|
disk_read(UNIT *uptr, uint64 *buffer, int sector, int wps)
|
||||||
|
{
|
||||||
|
int da;
|
||||||
|
int wc;
|
||||||
|
int bc;
|
||||||
|
int wp;
|
||||||
|
uint64 temp;
|
||||||
|
uint8 conv_buff[2048];
|
||||||
|
switch(GET_FMT(uptr->flags)) {
|
||||||
|
case SIMH:
|
||||||
|
da = sector * wps;
|
||||||
|
(void)sim_fseek(uptr->fileref, da * sizeof(uint64), SEEK_SET);
|
||||||
|
wc = sim_fread (buffer, sizeof(uint64), wps, uptr->fileref);
|
||||||
|
while (wc < wps)
|
||||||
|
buffer[wc++] = 0;
|
||||||
|
break;
|
||||||
|
case DBD9:
|
||||||
|
bc = (wps / 2) * 9;
|
||||||
|
da = sector * bc;
|
||||||
|
(void)sim_fseek(uptr->fileref, da, SEEK_SET);
|
||||||
|
wc = sim_fread (&conv_buff, 1, bc, uptr->fileref);
|
||||||
|
while (wc < bc)
|
||||||
|
conv_buff[wc++] = 0;
|
||||||
|
for (wp = wc = 0; wp < wps;) {
|
||||||
|
temp = ((uint64)conv_buff[wc++]) << 28;
|
||||||
|
temp |= ((uint64)conv_buff[wc++]) << 20;
|
||||||
|
temp |= ((uint64)conv_buff[wc++]) << 12;
|
||||||
|
temp |= ((uint64)conv_buff[wc++]) << 4;
|
||||||
|
temp |= ((uint64)conv_buff[wc]) >> 4;
|
||||||
|
buffer[wp++] = temp;
|
||||||
|
temp = ((uint64)conv_buff[wc++] & 0xf) << 32;
|
||||||
|
temp |= ((uint64)conv_buff[wc++]) << 24;
|
||||||
|
temp |= ((uint64)conv_buff[wc++]) << 16;
|
||||||
|
temp |= ((uint64)conv_buff[wc++]) << 8;
|
||||||
|
temp |= ((uint64)conv_buff[wc++]);
|
||||||
|
buffer[wp++] = temp;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DLD9:
|
||||||
|
bc = (wps / 2) * 9;
|
||||||
|
da = sector * bc;
|
||||||
|
(void)sim_fseek(uptr->fileref, da, SEEK_SET);
|
||||||
|
wc = sim_fread (&conv_buff, 1, bc, uptr->fileref);
|
||||||
|
while (wc < bc)
|
||||||
|
conv_buff[wc++] = 0;
|
||||||
|
for (wp = wc = 0; wp < wps;) {
|
||||||
|
temp = ((uint64)conv_buff[wc++]);
|
||||||
|
temp |= ((uint64)conv_buff[wc++]) << 8;
|
||||||
|
temp |= ((uint64)conv_buff[wc++]) << 16;
|
||||||
|
temp |= ((uint64)conv_buff[wc++]) << 24;
|
||||||
|
temp |= ((uint64)conv_buff[wc] & 0xf) << 32;
|
||||||
|
buffer[wp++] = temp;
|
||||||
|
temp = ((uint64)conv_buff[wc++] & 0xf0) >> 4;
|
||||||
|
temp |= ((uint64)conv_buff[wc++]) << 4;
|
||||||
|
temp |= ((uint64)conv_buff[wc++]) << 12;
|
||||||
|
temp |= ((uint64)conv_buff[wc++]) << 20;
|
||||||
|
temp |= ((uint64)conv_buff[wc++]) << 28;
|
||||||
|
buffer[wp++] = temp;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat
|
||||||
|
disk_write(UNIT *uptr, uint64 *buffer, int sector, int wps)
|
||||||
|
{
|
||||||
|
int da;
|
||||||
|
int wc;
|
||||||
|
int bc;
|
||||||
|
int wp;
|
||||||
|
uint64 temp;
|
||||||
|
uint8 conv_buff[2048];
|
||||||
|
switch(GET_FMT(uptr->flags)) {
|
||||||
|
case SIMH:
|
||||||
|
da = sector * wps;
|
||||||
|
(void)sim_fseek(uptr->fileref, da * sizeof(uint64), SEEK_SET);
|
||||||
|
wc = sim_fwrite (buffer, sizeof(uint64), wps, uptr->fileref);
|
||||||
|
break;
|
||||||
|
case DBD9:
|
||||||
|
bc = (wps / 2) * 9;
|
||||||
|
for (wp = wc = 0; wp < wps;) {
|
||||||
|
temp = buffer[wp++];
|
||||||
|
conv_buff[wc++] = (uint8)((temp >> 28) & 0xff);
|
||||||
|
conv_buff[wc++] = (uint8)((temp >> 20) & 0xff);
|
||||||
|
conv_buff[wc++] = (uint8)((temp >> 12) & 0xff);
|
||||||
|
conv_buff[wc++] = (uint8)((temp >> 4) & 0xff);
|
||||||
|
conv_buff[wc] = (uint8)((temp & 0xf) << 4);
|
||||||
|
temp = buffer[wp++];
|
||||||
|
conv_buff[wc++] |= (uint8)((temp >> 32) & 0xf);
|
||||||
|
conv_buff[wc++] = (uint8)((temp >> 24) & 0xff);
|
||||||
|
conv_buff[wc++] = (uint8)((temp >> 16) & 0xff);
|
||||||
|
conv_buff[wc++] = (uint8)((temp >> 8) & 0xff);
|
||||||
|
conv_buff[wc++] = (uint8)(temp & 0xff);
|
||||||
|
}
|
||||||
|
da = sector * bc;
|
||||||
|
(void)sim_fseek(uptr->fileref, da, SEEK_SET);
|
||||||
|
wc = sim_fwrite (&conv_buff, 1, bc, uptr->fileref);
|
||||||
|
return SCPE_OK;
|
||||||
|
case DLD9:
|
||||||
|
bc = (wps / 2) * 9;
|
||||||
|
for (wp = wc = 0; wp < wps;) {
|
||||||
|
temp = buffer[wp++];
|
||||||
|
conv_buff[wc++] = (uint8)(temp & 0xff);
|
||||||
|
conv_buff[wc++] = (uint8)((temp >> 8) & 0xff);
|
||||||
|
conv_buff[wc++] = (uint8)((temp >> 16) & 0xff);
|
||||||
|
conv_buff[wc++] = (uint8)((temp >> 24) & 0xff);
|
||||||
|
conv_buff[wc] = (uint8)((temp >> 32) & 0xf);
|
||||||
|
temp = buffer[wp++];
|
||||||
|
conv_buff[wc++] |= (uint8)((temp << 4) & 0xf0);
|
||||||
|
conv_buff[wc++] = (uint8)((temp >> 4) & 0xff);
|
||||||
|
conv_buff[wc++] = (uint8)((temp >> 12) & 0xff);
|
||||||
|
conv_buff[wc++] = (uint8)((temp >> 20) & 0xff);
|
||||||
|
conv_buff[wc++] = (uint8)((temp >> 28) & 0xff);
|
||||||
|
}
|
||||||
|
da = sector * bc;
|
||||||
|
(void)sim_fseek(uptr->fileref, da, SEEK_SET);
|
||||||
|
wc = sim_fwrite (&conv_buff, 1, bc, uptr->fileref);
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Set disk format */
|
||||||
|
t_stat disk_set_fmt (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
|
||||||
|
{
|
||||||
|
int f;
|
||||||
|
|
||||||
|
if (uptr == NULL) return SCPE_IERR;
|
||||||
|
if (cptr == NULL) return SCPE_ARG;
|
||||||
|
for (f = 0; fmts[f].name != 0; f++) {
|
||||||
|
if (strcmp (cptr, fmts[f].name) == 0) {
|
||||||
|
uptr->flags &= ~UNIT_FMT;
|
||||||
|
uptr->flags |= SET_FMT(fmts[f].mode);
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SCPE_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Show disk format */
|
||||||
|
|
||||||
|
t_stat disk_show_fmt (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
|
||||||
|
{
|
||||||
|
int fmt = GET_FMT(uptr->flags);
|
||||||
|
int f;
|
||||||
|
|
||||||
|
for (f = 0; fmts[f].name != 0; f++) {
|
||||||
|
if (fmt == fmts[f].mode) {
|
||||||
|
fprintf (st, "%s format", fmts[f].name);
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf (st, "invalid format");
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Device attach */
|
||||||
|
t_stat disk_attach (UNIT *uptr, CONST char *cptr)
|
||||||
|
{
|
||||||
|
t_stat r;
|
||||||
|
char gbuf[30];
|
||||||
|
|
||||||
|
/* Reset to SIMH format on attach */
|
||||||
|
uptr->flags &= ~UNIT_FMT;
|
||||||
|
/* Pickup optional format specifier during RESTORE */
|
||||||
|
cptr = get_sim_sw (cptr);
|
||||||
|
if (sim_switches & SWMASK ('F')) { /* format spec? */
|
||||||
|
cptr = get_glyph (cptr, gbuf, 0); /* get spec */
|
||||||
|
if (*cptr == 0) return SCPE_2FARG; /* must be more */
|
||||||
|
if (disk_set_fmt (uptr, 0, gbuf, NULL) != SCPE_OK)
|
||||||
|
return SCPE_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = attach_unit (uptr, cptr);
|
||||||
|
if (r != SCPE_OK)
|
||||||
|
return r;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Device detach */
|
||||||
|
|
||||||
|
t_stat disk_detach (UNIT *uptr)
|
||||||
|
{
|
||||||
|
return detach_unit (uptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat disk_attach_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
||||||
|
{
|
||||||
|
fprintf (st, "%s Disk Attach Help\n\n", dptr->name);
|
||||||
|
|
||||||
|
fprintf (st, "Disk container files can be one of 3 different types:\n\n");
|
||||||
|
fprintf (st, " SIMH A disk is an unstructured binary file of 64bit integers\n");
|
||||||
|
fprintf (st, " DBD9 Compatible with KLH10 is a packed big endian word\n");
|
||||||
|
fprintf (st, " DLD9 Compatible with KLH10 is a packed little endian word\n");
|
||||||
|
|
||||||
|
if (dptr->numunits > 1) {
|
||||||
|
uint32 i;
|
||||||
|
|
||||||
|
for (i=0; (i < dptr->numunits); ++i)
|
||||||
|
if ((dptr->units[i].flags & UNIT_ATTABLE) &&
|
||||||
|
!(dptr->units[i].flags & UNIT_DIS)) {
|
||||||
|
fprintf (st, " sim> ATTACH {switches} %s%d diskfile\n", dptr->name, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fprintf (st, " sim> ATTACH {switches} %s diskfile\n", dptr->name);
|
||||||
|
fprintf (st, "\n%s attach command switches\n", dptr->name);
|
||||||
|
fprintf (st, " -R Attach Read Only.\n");
|
||||||
|
fprintf (st, " -E Must Exist (if not specified an attempt to create the indicated\n");
|
||||||
|
fprintf (st, " disk container will be attempted).\n");
|
||||||
|
fprintf (st, " -F Open the indicated disk container in a specific format (default\n");
|
||||||
|
fprintf (st, " is SIMH), other options are DBD9 and DLD9\n");
|
||||||
|
fprintf (st, " -Y Answer Yes to prompt to overwrite last track (on disk create)\n");
|
||||||
|
fprintf (st, " -N Answer No to prompt to overwrite last track (on disk create)\n");
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
81
PDP10/kx10_disk.h
Normal file
81
PDP10/kx10_disk.h
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
/* kx10_disk.h: Disk translator.
|
||||||
|
|
||||||
|
Copyright (c) 2020, Richard Cornwell
|
||||||
|
|
||||||
|
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
|
||||||
|
RICHARD CORNWELL 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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Flags in the unit flags word */
|
||||||
|
|
||||||
|
#define UNIT_V_WLK (UNIT_V_UF + 0) /* write locked */
|
||||||
|
#define UNIT_WLK (1 << UNIT_V_WLK)
|
||||||
|
#define UNIT_WPRT (UNIT_WLK | UNIT_RO) /* write protect */
|
||||||
|
#define UNIT_V_FMT (UNIT_V_UF + 8)
|
||||||
|
#define UNIT_M_FMT 7
|
||||||
|
#define GET_FMT(x) (((x) >> UNIT_V_FMT) & UNIT_M_FMT)
|
||||||
|
#define SET_FMT(x) (((x) & UNIT_M_FMT) << UNIT_V_FMT)
|
||||||
|
#define UNIT_FMT (UNIT_M_FMT << UNIT_V_FMT)
|
||||||
|
|
||||||
|
#define SIMH 0 /* Default raw uint64 word format */
|
||||||
|
#define DBD9 1 /* KLH10 Disb Big End Double */
|
||||||
|
#define DLD9 2 /* KLH10 Disb Little End Double */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SIMH format is number words per sector stored as a 64 bit word.
|
||||||
|
*
|
||||||
|
* DBD9 format is: 9 character per pair of words.
|
||||||
|
*
|
||||||
|
* 0 - B0 1 2 3 4 5 6 7
|
||||||
|
* 0 - 8 9 10 11 12 13 14 15
|
||||||
|
* 0 - 16 17 18 19 20 21 22 23
|
||||||
|
* 0 - 24 25 26 27 28 29 30 31
|
||||||
|
* 0 - 32 33 34 35 B0 1 2 3
|
||||||
|
* 1 - 4 5 6 7 8 9 10 11
|
||||||
|
* 1 - 12 13 14 15 16 17 18 19
|
||||||
|
* 1 - 20 21 22 23 24 25 26 27
|
||||||
|
* 1 - 28 29 30 31 32 33 34 35
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* DLD9 format is: 9 character per pair of words.
|
||||||
|
*
|
||||||
|
* 0 - 28 29 30 31 32 33 34 35
|
||||||
|
* 0 - 20 21 22 23 24 25 26 27
|
||||||
|
* 0 - 12 13 14 15 16 17 18 19
|
||||||
|
* 0 - 4 5 6 7 8 9 10 11
|
||||||
|
* 0 - 32 33 34 35 B0 1 2 3
|
||||||
|
* 1 - 24 25 26 27 28 29 30 31
|
||||||
|
* 1 - 16 17 18 19 20 21 22 23
|
||||||
|
* 1 - 8 9 10 11 12 13 14 15
|
||||||
|
* 1 - B0 1 2 3 4 5 6 7
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
t_stat disk_read(UNIT *uptr, uint64 *buffer, int sector, int wps);
|
||||||
|
t_stat disk_write(UNIT *uptr, uint64 *buffer, int sector, int wps);
|
||||||
|
/* Set disk format */
|
||||||
|
t_stat disk_set_fmt (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
||||||
|
/* Show disk format */
|
||||||
|
t_stat disk_show_fmt (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
||||||
|
/* Device attach */
|
||||||
|
t_stat disk_attach (UNIT *uptr, CONST char *cptr);
|
||||||
|
/* Device detach */
|
||||||
|
t_stat disk_detach (UNIT *uptr);
|
||||||
|
/* Print attach help */
|
||||||
|
t_stat disk_attach_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
|
|
@ -1,6 +1,6 @@
|
||||||
/* ka10_dk.c: PDP-10 DK subsystem simulator
|
/* kx10_dk.c: PDP-10 DK subsystem simulator
|
||||||
|
|
||||||
Copyright (c) 2013-2017, Richard Cornwell
|
Copyright (c) 2013-2020, Richard Cornwell
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* ka10_dp.c: Dec Data Products Disk Drive.
|
/* kx10_dp.c: Dec Data Products Disk Drive.
|
||||||
|
|
||||||
Copyright (c) 2013-2017, Richard Cornwell
|
Copyright (c) 2013-2020, Richard Cornwell
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -22,6 +22,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "kx10_defs.h"
|
#include "kx10_defs.h"
|
||||||
|
#include "kx10_disk.h"
|
||||||
|
|
||||||
#ifndef NUM_DEVS_DP
|
#ifndef NUM_DEVS_DP
|
||||||
#define NUM_DEVS_DP 0
|
#define NUM_DEVS_DP 0
|
||||||
|
@ -39,13 +40,10 @@
|
||||||
/* Flags in the unit flags word */
|
/* Flags in the unit flags word */
|
||||||
|
|
||||||
#define DEV_WHDR (1 << DEV_V_UF) /* Enable write headers */
|
#define DEV_WHDR (1 << DEV_V_UF) /* Enable write headers */
|
||||||
#define UNIT_V_WLK (UNIT_V_UF + 0) /* write locked */
|
|
||||||
#define UNIT_V_DTYPE (UNIT_V_UF + 1) /* disk type */
|
#define UNIT_V_DTYPE (UNIT_V_UF + 1) /* disk type */
|
||||||
#define UNIT_M_DTYPE 3
|
#define UNIT_M_DTYPE 3
|
||||||
#define UNIT_WLK (1 << UNIT_V_WLK)
|
|
||||||
#define UNIT_DTYPE (UNIT_M_DTYPE << UNIT_V_DTYPE)
|
#define UNIT_DTYPE (UNIT_M_DTYPE << UNIT_V_DTYPE)
|
||||||
#define GET_DTYPE(x) (((x) >> UNIT_V_DTYPE) & UNIT_M_DTYPE)
|
#define GET_DTYPE(x) (((x) >> UNIT_V_DTYPE) & UNIT_M_DTYPE)
|
||||||
#define UNIT_WPRT (UNIT_WLK | UNIT_RO) /* write protect */
|
|
||||||
|
|
||||||
/* Parameters in the unit descriptor */
|
/* Parameters in the unit descriptor */
|
||||||
|
|
||||||
|
@ -271,6 +269,7 @@ MTAB dp_mod[] = {
|
||||||
{UNIT_DTYPE, (RP03_DTYPE << UNIT_V_DTYPE), "RP03", "RP03", &dp_set_type },
|
{UNIT_DTYPE, (RP03_DTYPE << UNIT_V_DTYPE), "RP03", "RP03", &dp_set_type },
|
||||||
{UNIT_DTYPE, (RP02_DTYPE << UNIT_V_DTYPE), "RP02", "RP02", &dp_set_type },
|
{UNIT_DTYPE, (RP02_DTYPE << UNIT_V_DTYPE), "RP02", "RP02", &dp_set_type },
|
||||||
{UNIT_DTYPE, (RP01_DTYPE << UNIT_V_DTYPE), "RP01", "RP01", &dp_set_type },
|
{UNIT_DTYPE, (RP01_DTYPE << UNIT_V_DTYPE), "RP01", "RP01", &dp_set_type },
|
||||||
|
{MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT", NULL, &disk_show_fmt },
|
||||||
{0},
|
{0},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -301,7 +300,7 @@ DEVICE dpa_dev = {
|
||||||
#if (NUM_DEVS_DP > 1)
|
#if (NUM_DEVS_DP > 1)
|
||||||
REG dpb_reg[] = {
|
REG dpb_reg[] = {
|
||||||
{BRDATA(BUFF, dp_buf[1], 16, 64, RP_NUMWD), REG_HRO},
|
{BRDATA(BUFF, dp_buf[1], 16, 64, RP_NUMWD), REG_HRO},
|
||||||
{HRDATA(UNIT, dp_cur_unit[1], 32), REG_HRO},
|
{HRDATA(DF10, dp_cur_unit[1], 32), REG_HRO},
|
||||||
{ORDATA(STATUS, dp_df10[1].status, 18), REG_RO},
|
{ORDATA(STATUS, dp_df10[1].status, 18), REG_RO},
|
||||||
{ORDATA(CIA, dp_df10[1].cia, 18)},
|
{ORDATA(CIA, dp_df10[1].cia, 18)},
|
||||||
{ORDATA(CCW, dp_df10[1].ccw, 18)},
|
{ORDATA(CCW, dp_df10[1].ccw, 18)},
|
||||||
|
@ -325,7 +324,7 @@ DEVICE dpb_dev = {
|
||||||
#if (NUM_DEVS_DP > 2)
|
#if (NUM_DEVS_DP > 2)
|
||||||
REG dpc_reg[] = {
|
REG dpc_reg[] = {
|
||||||
{BRDATA(BUFF, dp_buf[2], 16, 64, RP_NUMWD), REG_HRO},
|
{BRDATA(BUFF, dp_buf[2], 16, 64, RP_NUMWD), REG_HRO},
|
||||||
{BRDATA(DF10, &dp_cur_unit[2], 16, 8, 1), REG_HRO},
|
{HRDATA(DF10, dp_cur_unit[2], 32), REG_HRO},
|
||||||
{ORDATA(STATUS, dp_df10[2].status, 18), REG_RO},
|
{ORDATA(STATUS, dp_df10[2].status, 18), REG_RO},
|
||||||
{ORDATA(CIA, dp_df10[2].cia, 18)},
|
{ORDATA(CIA, dp_df10[2].cia, 18)},
|
||||||
{ORDATA(CCW, dp_df10[2].ccw, 18)},
|
{ORDATA(CCW, dp_df10[2].ccw, 18)},
|
||||||
|
@ -348,8 +347,8 @@ DEVICE dpc_dev = {
|
||||||
|
|
||||||
#if (NUM_DEVS_DP > 3)
|
#if (NUM_DEVS_DP > 3)
|
||||||
REG dpd_reg[] = {
|
REG dpd_reg[] = {
|
||||||
{BRDATA(BUFF, dp_buf[3], 16, 64, RP_NUMWD), REG_HRO},
|
{BRDATA(BUFF, &dp_buf[3][0], 16, 64, RP_NUMWD), REG_HRO},
|
||||||
{BRDATA(DF10, &dp_cur_unit[3], 16, 8, 1), REG_HRO},
|
{BRDATA(DF10, dp_cur_unit[3], 32), REG_HRO},
|
||||||
{ORDATA(STATUS, dp_df10[3].status, 18), REG_RO},
|
{ORDATA(STATUS, dp_df10[3].status, 18), REG_RO},
|
||||||
{ORDATA(CIA, dp_df10[3].cia, 18)},
|
{ORDATA(CIA, dp_df10[3].cia, 18)},
|
||||||
{ORDATA(CCW, dp_df10[3].ccw, 18)},
|
{ORDATA(CCW, dp_df10[3].ccw, 18)},
|
||||||
|
@ -423,7 +422,6 @@ t_stat dp_devio(uint32 dev, uint64 *data) {
|
||||||
if (*data & BUSY) {
|
if (*data & BUSY) {
|
||||||
/* Stop controller */
|
/* Stop controller */
|
||||||
sim_cancel(uptr);
|
sim_cancel(uptr);
|
||||||
uptr->STATUS &= ~BUSY;
|
|
||||||
df10_finish_op(df10, 0);
|
df10_finish_op(df10, 0);
|
||||||
}
|
}
|
||||||
/* Clear flags */
|
/* Clear flags */
|
||||||
|
@ -603,7 +601,7 @@ t_stat dp_svc (UNIT *uptr)
|
||||||
int cyl = (uptr->UFLAGS >> 20) & 0777;
|
int cyl = (uptr->UFLAGS >> 20) & 0777;
|
||||||
DEVICE *dptr = dp_devs[ctlr];
|
DEVICE *dptr = dp_devs[ctlr];
|
||||||
struct df10 *df10 = &dp_df10[ctlr];
|
struct df10 *df10 = &dp_df10[ctlr];
|
||||||
int diff, diffs, wc;
|
int diff, diffs;
|
||||||
int r;
|
int r;
|
||||||
sect &= 017;
|
sect &= 017;
|
||||||
|
|
||||||
|
@ -647,12 +645,8 @@ t_stat dp_svc (UNIT *uptr)
|
||||||
if (cmd != WR) {
|
if (cmd != WR) {
|
||||||
/* Read the block */
|
/* Read the block */
|
||||||
int da = ((cyl * dp_drv_tab[dtype].surf + surf)
|
int da = ((cyl * dp_drv_tab[dtype].surf + surf)
|
||||||
* dp_drv_tab[dtype].sect + sect) * RP_NUMWD;
|
* dp_drv_tab[dtype].sect + sect);
|
||||||
(void)sim_fseek(uptr->fileref, da * sizeof(uint64), SEEK_SET);
|
(void)disk_read(uptr, &dp_buf[ctlr][0], da, RP_NUMWD);
|
||||||
wc = sim_fread (&dp_buf[ctlr][0], sizeof(uint64), RP_NUMWD,
|
|
||||||
uptr->fileref);
|
|
||||||
for (; wc < RP_NUMWD; wc++)
|
|
||||||
dp_buf[ctlr][wc] = 0;
|
|
||||||
uptr->hwmark = RP_NUMWD;
|
uptr->hwmark = RP_NUMWD;
|
||||||
uptr->DATAPTR = 0;
|
uptr->DATAPTR = 0;
|
||||||
sect = sect + 1;
|
sect = sect + 1;
|
||||||
|
@ -695,13 +689,11 @@ t_stat dp_svc (UNIT *uptr)
|
||||||
if (uptr->DATAPTR >= RP_NUMWD || r == 0 ) {
|
if (uptr->DATAPTR >= RP_NUMWD || r == 0 ) {
|
||||||
if (cmd == WR) {
|
if (cmd == WR) {
|
||||||
int da = ((cyl * dp_drv_tab[dtype].surf + surf)
|
int da = ((cyl * dp_drv_tab[dtype].surf + surf)
|
||||||
* dp_drv_tab[dtype].sect + sect) * RP_NUMWD;
|
* dp_drv_tab[dtype].sect + sect);
|
||||||
/* write block the block */
|
/* write block the block */
|
||||||
for (; uptr->DATAPTR < RP_NUMWD; uptr->DATAPTR++)
|
for (; uptr->DATAPTR < RP_NUMWD; uptr->DATAPTR++)
|
||||||
dp_buf[ctlr][uptr->DATAPTR] = 0;
|
dp_buf[ctlr][uptr->DATAPTR] = 0;
|
||||||
(void)sim_fseek(uptr->fileref, da * sizeof(uint64), SEEK_SET);
|
(void)disk_write(uptr, &dp_buf[ctlr][0], da, RP_NUMWD);
|
||||||
wc = sim_fwrite(&dp_buf[ctlr][0],sizeof(uint64), RP_NUMWD,
|
|
||||||
uptr->fileref);
|
|
||||||
uptr->STATUS |= SRC_DONE;
|
uptr->STATUS |= SRC_DONE;
|
||||||
sect = sect + 1;
|
sect = sect + 1;
|
||||||
if (sect >= dp_drv_tab[dtype].sect) {
|
if (sect >= dp_drv_tab[dtype].sect) {
|
||||||
|
@ -722,7 +714,7 @@ t_stat dp_svc (UNIT *uptr)
|
||||||
CLR_BUF(uptr);
|
CLR_BUF(uptr);
|
||||||
}
|
}
|
||||||
if (r)
|
if (r)
|
||||||
sim_activate(uptr, 25);
|
sim_activate(uptr, 40);
|
||||||
else {
|
else {
|
||||||
uptr->STATUS &= ~(SRC_DONE|END_CYL|BUSY);
|
uptr->STATUS &= ~(SRC_DONE|END_CYL|BUSY);
|
||||||
uptr->UFLAGS |= DONE;
|
uptr->UFLAGS |= DONE;
|
||||||
|
@ -780,13 +772,11 @@ t_stat dp_svc (UNIT *uptr)
|
||||||
uptr->DATAPTR++;
|
uptr->DATAPTR++;
|
||||||
if (uptr->DATAPTR >= RP_NUMWD || r == 0 ) {
|
if (uptr->DATAPTR >= RP_NUMWD || r == 0 ) {
|
||||||
int da = ((cyl * dp_drv_tab[dtype].surf + surf)
|
int da = ((cyl * dp_drv_tab[dtype].surf + surf)
|
||||||
* dp_drv_tab[dtype].sect + sect) * RP_NUMWD;
|
* dp_drv_tab[dtype].sect + sect);
|
||||||
/* write block the block */
|
/* write block the block */
|
||||||
for (; uptr->DATAPTR < RP_NUMWD; uptr->DATAPTR++)
|
for (; uptr->DATAPTR < RP_NUMWD; uptr->DATAPTR++)
|
||||||
dp_buf[ctlr][uptr->DATAPTR] = 0;
|
dp_buf[ctlr][uptr->DATAPTR] = 0;
|
||||||
(void)sim_fseek(uptr->fileref, da * sizeof(uint64), SEEK_SET);
|
(void)disk_write(uptr, &dp_buf[ctlr][0], da, RP_NUMWD);
|
||||||
wc = sim_fwrite(&dp_buf[ctlr][0],sizeof(uint64), RP_NUMWD,
|
|
||||||
uptr->fileref);
|
|
||||||
uptr->STATUS |= SRC_DONE;
|
uptr->STATUS |= SRC_DONE;
|
||||||
sect = sect + 1;
|
sect = sect + 1;
|
||||||
if (sect >= dp_drv_tab[dtype].sect) {
|
if (sect >= dp_drv_tab[dtype].sect) {
|
||||||
|
@ -931,8 +921,7 @@ dp_boot(int32 unit_num, DEVICE * dptr)
|
||||||
|
|
||||||
addr = (MEMSIZE - 512) & RMASK;
|
addr = (MEMSIZE - 512) & RMASK;
|
||||||
for (sect = 4; sect <= 7; sect++) {
|
for (sect = 4; sect <= 7; sect++) {
|
||||||
(void)sim_fseek(uptr->fileref, (sect * RP_NUMWD) * sizeof(uint64), SEEK_SET);
|
(void)disk_read(uptr, &dp_buf[0][0], sect, RP_NUMWD);
|
||||||
(void)sim_fread (&dp_buf[0][0], sizeof(uint64), RP_NUMWD, uptr->fileref);
|
|
||||||
ptr = 0;
|
ptr = 0;
|
||||||
for(wc = RP_NUMWD; wc > 0; wc--)
|
for(wc = RP_NUMWD; wc > 0; wc--)
|
||||||
M[addr++] = dp_buf[0][ptr++];
|
M[addr++] = dp_buf[0][ptr++];
|
||||||
|
@ -950,10 +939,10 @@ t_stat dp_attach (UNIT *uptr, CONST char *cptr)
|
||||||
DIB *dib;
|
DIB *dib;
|
||||||
int ctlr;
|
int ctlr;
|
||||||
|
|
||||||
uptr->capac = dp_drv_tab[GET_DTYPE (uptr->flags)].size;
|
r = disk_attach (uptr, cptr);
|
||||||
r = attach_unit (uptr, cptr);
|
if (r != SCPE_OK || (sim_switches & SIM_SW_REST) != 0)
|
||||||
if (r != SCPE_OK)
|
|
||||||
return r;
|
return r;
|
||||||
|
uptr->capac = dp_drv_tab[GET_DTYPE (uptr->flags)].size;
|
||||||
dptr = find_dev_from_unit(uptr);
|
dptr = find_dev_from_unit(uptr);
|
||||||
if (dptr == 0)
|
if (dptr == 0)
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
@ -962,7 +951,7 @@ t_stat dp_attach (UNIT *uptr, CONST char *cptr)
|
||||||
uptr->CUR_CYL = 0;
|
uptr->CUR_CYL = 0;
|
||||||
uptr->UFLAGS = (NO << 3) | SEEK_DONE | (ctlr >> 2);
|
uptr->UFLAGS = (NO << 3) | SEEK_DONE | (ctlr >> 2);
|
||||||
dp_df10[ctlr].status |= PI_ENABLE;
|
dp_df10[ctlr].status |= PI_ENABLE;
|
||||||
set_interrupt(DP_DEVNUM + (ctlr), dp_df10[ctlr >> 2].status);
|
set_interrupt(DP_DEVNUM + (ctlr), dp_df10[ctlr].status);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -974,7 +963,7 @@ t_stat dp_detach (UNIT *uptr)
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
if (sim_is_active (uptr)) /* unit active? */
|
if (sim_is_active (uptr)) /* unit active? */
|
||||||
sim_cancel (uptr); /* cancel operation */
|
sim_cancel (uptr); /* cancel operation */
|
||||||
return detach_unit (uptr);
|
return disk_detach (uptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
t_stat dp_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
t_stat dp_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
||||||
|
@ -983,6 +972,7 @@ fprintf (st, "RP10 RP01/2/3 Disk Pack Drives (DP)\n\n");
|
||||||
fprintf (st, "The DP controller implements the RP10 disk drives. RP\n");
|
fprintf (st, "The DP controller implements the RP10 disk drives. RP\n");
|
||||||
fprintf (st, "options include the ability to set units write enabled or write locked, to\n");
|
fprintf (st, "options include the ability to set units write enabled or write locked, to\n");
|
||||||
fprintf (st, "set the drive type to one of three disk types.\n");
|
fprintf (st, "set the drive type to one of three disk types.\n");
|
||||||
|
disk_attach_help(st, dptr, uptr, flag, cptr);
|
||||||
fprint_set_help (st, dptr);
|
fprint_set_help (st, dptr);
|
||||||
fprint_show_help (st, dptr);
|
fprint_show_help (st, dptr);
|
||||||
fprintf (st, "\nThe type options can be used only when a unit is not attached to a file.\n");
|
fprintf (st, "\nThe type options can be used only when a unit is not attached to a file.\n");
|
||||||
|
|
233
PDP10/kx10_dpy.c
233
PDP10/kx10_dpy.c
|
@ -85,6 +85,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "kx10_defs.h"
|
#include "kx10_defs.h"
|
||||||
|
#include "sim_video.h"
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#ifndef NUM_DEVS_DPY
|
#ifndef NUM_DEVS_DPY
|
||||||
|
@ -296,13 +297,40 @@ t_stat dpy_svc (UNIT *uptr)
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define JOY_MAX_UNITS 4
|
||||||
|
#define JOY_MAX_AXES 4
|
||||||
|
#define JOY_MAX_BUTTONS 4
|
||||||
|
|
||||||
|
static int joy_axes[JOY_MAX_UNITS * JOY_MAX_AXES];
|
||||||
|
static int joy_buttons[JOY_MAX_UNITS * JOY_MAX_BUTTONS];
|
||||||
|
|
||||||
|
static void dpy_joy_motion(int which, int axis, int value)
|
||||||
|
{
|
||||||
|
int result = FALSE;
|
||||||
|
if (which < JOY_MAX_UNITS && axis < JOY_MAX_AXES) {
|
||||||
|
joy_axes[which * JOY_MAX_AXES + axis] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dpy_joy_button(int which, int button, int state)
|
||||||
|
{
|
||||||
|
int result = FALSE;
|
||||||
|
if (which < JOY_MAX_UNITS && button < JOY_MAX_BUTTONS) {
|
||||||
|
joy_buttons[which * JOY_MAX_UNITS + button] = state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Reset routine */
|
/* Reset routine */
|
||||||
|
|
||||||
t_stat dpy_reset (DEVICE *dptr)
|
t_stat dpy_reset (DEVICE *dptr)
|
||||||
{
|
{
|
||||||
if (!(dptr->flags & DEV_DIS)) {
|
if (dptr->flags & DEV_DIS) {
|
||||||
|
display_close(dptr);
|
||||||
|
} else {
|
||||||
display_reset();
|
display_reset();
|
||||||
ty340_reset(dptr);
|
ty340_reset(dptr);
|
||||||
|
vid_register_gamepad_motion_callback (dpy_joy_motion);
|
||||||
|
vid_register_gamepad_button_callback (dpy_joy_button);
|
||||||
}
|
}
|
||||||
sim_cancel (&dpy_unit[0]); /* deactivate unit */
|
sim_cancel (&dpy_unit[0]); /* deactivate unit */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
@ -367,17 +395,25 @@ cpu_set_switches(unsigned long w1, unsigned long w2) {
|
||||||
#if NUM_DEVS_WCNSLS > 0
|
#if NUM_DEVS_WCNSLS > 0
|
||||||
#define WCNSLS_DEVNUM 0420
|
#define WCNSLS_DEVNUM 0420
|
||||||
|
|
||||||
|
#define UNIT_JOY (1 << DEV_V_UF)
|
||||||
|
|
||||||
t_stat wcnsls_devio(uint32 dev, uint64 *data);
|
t_stat wcnsls_devio(uint32 dev, uint64 *data);
|
||||||
const char *wcnsls_description (DEVICE *dptr);
|
const char *wcnsls_description (DEVICE *dptr);
|
||||||
|
|
||||||
DIB wcnsls_dib[] = {
|
DIB wcnsls_dib[] = {
|
||||||
{ WCNSLS_DEVNUM, 1, &wcnsls_devio, NULL }};
|
{ WCNSLS_DEVNUM, 1, &wcnsls_devio, NULL }};
|
||||||
|
|
||||||
|
MTAB wcnsls_mod[] = {
|
||||||
|
{ UNIT_JOY, UNIT_JOY, "JOYSTICK", "JOYSTICK", NULL, NULL, NULL,
|
||||||
|
"Use USB joysticks"},
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
UNIT wcnsls_unit[] = {
|
UNIT wcnsls_unit[] = {
|
||||||
{ UDATA (NULL, UNIT_IDLE, 0) }};
|
{ UDATA (NULL, UNIT_IDLE, 0) }};
|
||||||
|
|
||||||
DEVICE wcnsls_dev = {
|
DEVICE wcnsls_dev = {
|
||||||
"WCNSLS", wcnsls_unit, NULL, NULL,
|
"WCNSLS", wcnsls_unit, NULL, wcnsls_mod,
|
||||||
NUM_DEVS_WCNSLS, 0, 0, 0, 0, 0,
|
NUM_DEVS_WCNSLS, 0, 0, 0, 0, 0,
|
||||||
NULL, NULL, NULL,
|
NULL, NULL, NULL,
|
||||||
NULL, NULL, NULL,
|
NULL, NULL, NULL,
|
||||||
|
@ -390,27 +426,16 @@ const char *wcnsls_description (DEVICE *dptr)
|
||||||
return "MIT Spacewar Consoles";
|
return "MIT Spacewar Consoles";
|
||||||
}
|
}
|
||||||
|
|
||||||
t_stat wcnsls_devio(uint32 dev, uint64 *data) {
|
|
||||||
uint64 switches;
|
|
||||||
|
|
||||||
switch (dev & 3) {
|
|
||||||
case CONO:
|
|
||||||
/* CONO WCNSLS,40 ;enable spacewar consoles */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DATAI:
|
|
||||||
switches = 0777777777777LL; /* 1 is off */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* map 32-bit "spacewar_switches" value to what PDP-6/10 game expects
|
* map 32-bit "spacewar_switches" value to what PDP-6/10 game expects
|
||||||
* (four 9-bit bytes)
|
* (four 9-bit bytes)
|
||||||
*/
|
*/
|
||||||
/* bits inside the bytes */
|
/* bits inside the bytes */
|
||||||
#define CCW 0400 /* counter clockwise (L) */
|
#define CCW 0400LL /* counter clockwise (L) */
|
||||||
#define CW 0200 /* clockwise (R) */
|
#define CW 0200LL /* clockwise (R) */
|
||||||
#define THRUST 0100
|
#define THRUST 0100LL
|
||||||
#define HYPER 040
|
#define HYPER 040LL
|
||||||
#define FIRE 020
|
#define FIRE 020LL
|
||||||
|
|
||||||
/* shift values for the players' bytes */
|
/* shift values for the players' bytes */
|
||||||
#define UR 0 /* upper right: enterprise "top plug" */
|
#define UR 0 /* upper right: enterprise "top plug" */
|
||||||
|
@ -418,6 +443,71 @@ t_stat wcnsls_devio(uint32 dev, uint64 *data) {
|
||||||
#define LL 18 /* lower left: thin ship "third plug" */
|
#define LL 18 /* lower left: thin ship "third plug" */
|
||||||
#define UL 27 /* upper left: fat ship "bottom plug" */
|
#define UL 27 /* upper left: fat ship "bottom plug" */
|
||||||
|
|
||||||
|
#define JOY_TRIG 5000
|
||||||
|
#define JOY0 (JOY_MAX_AXES*0)
|
||||||
|
#define JOY1 (JOY_MAX_AXES*1)
|
||||||
|
#define JOY2 (JOY_MAX_AXES*2)
|
||||||
|
#define JOY3 (JOY_MAX_AXES*3)
|
||||||
|
#define BUT0 (JOY_MAX_BUTTONS*0)
|
||||||
|
#define BUT1 (JOY_MAX_BUTTONS*1)
|
||||||
|
#define BUT2 (JOY_MAX_BUTTONS*2)
|
||||||
|
#define BUT3 (JOY_MAX_BUTTONS*3)
|
||||||
|
|
||||||
|
static uint64 joystick_switches (void)
|
||||||
|
{
|
||||||
|
uint64 switches = 0777777777777LL;
|
||||||
|
|
||||||
|
if (joy_axes[JOY0] > JOY_TRIG)
|
||||||
|
switches &= ~(CCW << UR);
|
||||||
|
else if (joy_axes[JOY0] < -JOY_TRIG)
|
||||||
|
switches &= ~(CW << UR);
|
||||||
|
if (joy_axes[JOY0+1] < -JOY_TRIG)
|
||||||
|
switches &= ~(THRUST << UR);
|
||||||
|
if (joy_buttons[BUT0])
|
||||||
|
switches &= ~(FIRE << UR);
|
||||||
|
if (joy_buttons[BUT0+1])
|
||||||
|
switches &= ~(HYPER << UR);
|
||||||
|
|
||||||
|
if (joy_axes[JOY1] > JOY_TRIG)
|
||||||
|
switches &= ~(CCW << LR);
|
||||||
|
else if (joy_axes[JOY1] < -JOY_TRIG)
|
||||||
|
switches &= ~(CW << LR);
|
||||||
|
if (joy_axes[JOY1+1] < -JOY_TRIG)
|
||||||
|
switches &= ~(THRUST << LR);
|
||||||
|
if (joy_buttons[BUT1])
|
||||||
|
switches &= ~(FIRE << LR);
|
||||||
|
if (joy_buttons[BUT1+1])
|
||||||
|
switches &= ~(HYPER << LR);
|
||||||
|
|
||||||
|
if (joy_axes[JOY2] > JOY_TRIG)
|
||||||
|
switches &= ~(CCW << LL);
|
||||||
|
else if (joy_axes[JOY2] < -JOY_TRIG)
|
||||||
|
switches &= ~(CW << LL);
|
||||||
|
if (joy_axes[JOY2+1] < -JOY_TRIG)
|
||||||
|
switches &= ~(THRUST << LL);
|
||||||
|
if (joy_buttons[BUT2])
|
||||||
|
switches &= ~(FIRE << LL);
|
||||||
|
if (joy_buttons[BUT2+1])
|
||||||
|
switches &= ~(HYPER << LL);
|
||||||
|
|
||||||
|
if (joy_axes[JOY3] > JOY_TRIG)
|
||||||
|
switches &= ~((uint64)CCW << UL);
|
||||||
|
else if (joy_axes[JOY3] < -JOY_TRIG)
|
||||||
|
switches &= ~((uint64)CW << UL);
|
||||||
|
if (joy_axes[JOY3+1] < -JOY_TRIG)
|
||||||
|
switches &= ~((uint64)THRUST << UL);
|
||||||
|
if (joy_buttons[BUT3])
|
||||||
|
switches &= ~((uint64)FIRE << UL);
|
||||||
|
if (joy_buttons[BUT3+1])
|
||||||
|
switches &= ~(HYPER << UL);
|
||||||
|
|
||||||
|
return switches;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint64 keyboard_switches (void)
|
||||||
|
{
|
||||||
|
uint64 switches = 0777777777777LL; /* 1 is off */
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
#define DEBUGSW(X) (void)0
|
#define DEBUGSW(X) (void)0
|
||||||
#else
|
#else
|
||||||
|
@ -436,12 +526,115 @@ t_stat wcnsls_devio(uint32 dev, uint64 *data) {
|
||||||
if (spacewar_switches)
|
if (spacewar_switches)
|
||||||
DEBUGSW(("in %#lo out %#llo\r\n", spacewar_switches, switches));
|
DEBUGSW(("in %#lo out %#llo\r\n", spacewar_switches, switches));
|
||||||
|
|
||||||
*data = switches;
|
|
||||||
|
return switches;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat wcnsls_devio(uint32 dev, uint64 *data) {
|
||||||
|
switch (dev & 3) {
|
||||||
|
case CONO:
|
||||||
|
/* CONO WCNSLS,40 ;enable spacewar consoles */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DATAI:
|
||||||
|
if (wcnsls_unit->flags & UNIT_JOY) {
|
||||||
|
*data = joystick_switches ();
|
||||||
|
} else {
|
||||||
|
*data = keyboard_switches ();
|
||||||
|
}
|
||||||
|
|
||||||
sim_debug(DEBUG_DATAIO, &wcnsls_dev, "WCNSLS %03o DATI %012llo PC=%06o\n",
|
sim_debug(DEBUG_DATAIO, &wcnsls_dev, "WCNSLS %03o DATI %012llo PC=%06o\n",
|
||||||
dev, switches, PC);
|
dev, *data, PC);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Old MIT Spacewar console switches
|
||||||
|
*/
|
||||||
|
#if NUM_DEVS_OCNSLS > 0
|
||||||
|
#define OCNSLS_DEVNUM 0724
|
||||||
|
|
||||||
|
t_stat ocnsls_devio(uint32 dev, uint64 *data);
|
||||||
|
const char *ocnsls_description (DEVICE *dptr);
|
||||||
|
|
||||||
|
DIB ocnsls_dib[] = {
|
||||||
|
{ OCNSLS_DEVNUM, 1, &ocnsls_devio, NULL }};
|
||||||
|
|
||||||
|
UNIT ocnsls_unit[] = {
|
||||||
|
{ UDATA (NULL, UNIT_IDLE, 0) }};
|
||||||
|
|
||||||
|
DEVICE ocnsls_dev = {
|
||||||
|
"OCNSLS", ocnsls_unit, NULL, NULL,
|
||||||
|
NUM_DEVS_OCNSLS, 0, 0, 0, 0, 0,
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
&ocnsls_dib, DEV_DISABLE | DEV_DIS | DEV_DEBUG, 0, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, &ocnsls_description
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *ocnsls_description (DEVICE *dptr)
|
||||||
|
{
|
||||||
|
return "Old MIT Spacewar Consoles";
|
||||||
|
}
|
||||||
|
|
||||||
|
#define OHYPER 0004LL /* Hyperspace. */
|
||||||
|
#define OFIRE 0010LL /* Fire torpedo. */
|
||||||
|
#define OCW 0020LL /* Turn clockwise. */
|
||||||
|
#define OCCW 0040LL /* Turn counter clockwise. */
|
||||||
|
#define SLOW 0100LL /* Weak thrust. */
|
||||||
|
#define FAST 0200LL /* Strong thrust. */
|
||||||
|
#define BEACON 020000LL /* Aiming beacon. */
|
||||||
|
|
||||||
|
static uint64 old_switches (void)
|
||||||
|
{
|
||||||
|
uint64 switches = 0;
|
||||||
|
|
||||||
|
if (joy_axes[JOY0] > JOY_TRIG)
|
||||||
|
switches |= OCCW;
|
||||||
|
else if (joy_axes[JOY0] < -JOY_TRIG)
|
||||||
|
switches |= OCW;
|
||||||
|
if (joy_axes[JOY0+1] < -JOY_TRIG)
|
||||||
|
switches |= FAST;
|
||||||
|
if (joy_axes[JOY0+1] > JOY_TRIG)
|
||||||
|
switches |= SLOW;
|
||||||
|
if (joy_buttons[BUT0])
|
||||||
|
switches |= OFIRE;
|
||||||
|
if (joy_buttons[BUT0+1])
|
||||||
|
switches |= OHYPER;
|
||||||
|
if (joy_buttons[BUT0+2])
|
||||||
|
switches |= BEACON;
|
||||||
|
|
||||||
|
if (joy_axes[JOY1] > JOY_TRIG)
|
||||||
|
switches |= OCCW << 18;
|
||||||
|
else if (joy_axes[JOY1] < -JOY_TRIG)
|
||||||
|
switches |= OCW << 18;
|
||||||
|
if (joy_axes[JOY1+1] < -JOY_TRIG)
|
||||||
|
switches |= FAST << 18;
|
||||||
|
if (joy_axes[JOY1+1] > JOY_TRIG)
|
||||||
|
switches |= SLOW << 18;
|
||||||
|
if (joy_buttons[BUT1])
|
||||||
|
switches |= OFIRE << 18;
|
||||||
|
if (joy_buttons[BUT1+1])
|
||||||
|
switches |= OHYPER << 18;
|
||||||
|
if (joy_buttons[BUT1+2])
|
||||||
|
switches |= BEACON << 18;
|
||||||
|
|
||||||
|
return switches;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat ocnsls_devio(uint32 dev, uint64 *data) {
|
||||||
|
switch (dev & 3) {
|
||||||
|
case DATAI:
|
||||||
|
*data = old_switches ();
|
||||||
|
break;
|
||||||
|
case CONI:
|
||||||
|
*data = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
246
PDP10/kx10_dt.c
246
PDP10/kx10_dt.c
|
@ -1,6 +1,9 @@
|
||||||
/* pdp10_dt.c: 18b DECtape simulator
|
/* kx10_dt.c: 18b DECtape simulator
|
||||||
|
|
||||||
Copyright (c) 2017 Richard Cornwell
|
Copyright (c) 2017-2020 Richard Cornwell based on work by Bob Supnik
|
||||||
|
|
||||||
|
Based on PDP18B/pdp18b_dt.c by:
|
||||||
|
Copyright (c) 1993-2017, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -19,6 +22,10 @@
|
||||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
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.
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
Except as contained in this notice, the name of Robert M Supnik shall not be
|
||||||
|
used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
Except as contained in this notice, the name of Richard Cornwell shall not be
|
Except as contained in this notice, the name of Richard Cornwell shall not be
|
||||||
used in advertising or otherwise to promote the sale, use or other dealings
|
used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
in this Software without prior written authorization from Richard Cornwell.
|
in this Software without prior written authorization from Richard Cornwell.
|
||||||
|
@ -169,6 +176,7 @@
|
||||||
#define DTC_FWDRV 0200000 /* Move unit forward */
|
#define DTC_FWDRV 0200000 /* Move unit forward */
|
||||||
#define DTC_STSTOP 0400000 /* Stop unit */
|
#define DTC_STSTOP 0400000 /* Stop unit */
|
||||||
|
|
||||||
|
#define CMD u3
|
||||||
/* Flags in lower bits of u3 */
|
/* Flags in lower bits of u3 */
|
||||||
#define DTC_FNC_STOP 001 /* Unit stopping */
|
#define DTC_FNC_STOP 001 /* Unit stopping */
|
||||||
#define DTC_FNC_START 002 /* Start unit motion */
|
#define DTC_FNC_START 002 /* Start unit motion */
|
||||||
|
@ -250,7 +258,9 @@
|
||||||
|
|
||||||
#define ABS(x) (((x) < 0)? (-(x)): (x))
|
#define ABS(x) (((x) < 0)? (-(x)): (x))
|
||||||
|
|
||||||
#define DT_WRDTIM 15000
|
#define DT_WRDTIM 10000
|
||||||
|
|
||||||
|
#define WRITTEN u6 /* Set when tape modified */
|
||||||
|
|
||||||
int32 dtsa = 0; /* status A */
|
int32 dtsa = 0; /* status A */
|
||||||
uint64 dtsb = 0; /* status B */
|
uint64 dtsb = 0; /* status B */
|
||||||
|
@ -262,6 +272,7 @@ t_stat dt_svc (UNIT *uptr);
|
||||||
t_stat dt_boot(int32 unit_num, DEVICE * dptr);
|
t_stat dt_boot(int32 unit_num, DEVICE * dptr);
|
||||||
t_stat dt_reset (DEVICE *dptr);
|
t_stat dt_reset (DEVICE *dptr);
|
||||||
t_stat dt_attach (UNIT *uptr, CONST char *cptr);
|
t_stat dt_attach (UNIT *uptr, CONST char *cptr);
|
||||||
|
void dt_flush (UNIT *uptr);
|
||||||
t_stat dt_detach (UNIT *uptr);
|
t_stat dt_detach (UNIT *uptr);
|
||||||
#if MPX_DEV
|
#if MPX_DEV
|
||||||
t_stat dt_set_mpx (UNIT *uptr, int32 val, CONST char *cptr, void *desc) ;
|
t_stat dt_set_mpx (UNIT *uptr, int32 val, CONST char *cptr, void *desc) ;
|
||||||
|
@ -369,7 +380,7 @@ t_stat dt_devio(uint32 dev, uint64 *data) {
|
||||||
/* Stop all drives and clear drive unit */
|
/* Stop all drives and clear drive unit */
|
||||||
dtsa &= 0770777;
|
dtsa &= 0770777;
|
||||||
for (i = 0; i < DT_NUMDR; i++) {
|
for (i = 0; i < DT_NUMDR; i++) {
|
||||||
dt_unit[i].u3 &= ~0700;
|
dt_unit[i].CMD &= ~0700;
|
||||||
}
|
}
|
||||||
if ((*data & DTC_SEL) == 0)
|
if ((*data & DTC_SEL) == 0)
|
||||||
break;
|
break;
|
||||||
|
@ -426,14 +437,14 @@ t_stat dt_devio(uint32 dev, uint64 *data) {
|
||||||
}
|
}
|
||||||
if (*data & DTC_STSTOP) {
|
if (*data & DTC_STSTOP) {
|
||||||
if ((dt_unit[i].DSTATE & (DTC_MOT)) != 0) {
|
if ((dt_unit[i].DSTATE & (DTC_MOT)) != 0) {
|
||||||
dt_unit[i].u3 |= DTC_FNC_STOP;
|
dt_unit[i].CMD |= DTC_FNC_STOP;
|
||||||
}
|
}
|
||||||
dtsa &=~ (DTC_FWDRV|DTC_RVDRV);
|
dtsa &=~ (DTC_FWDRV|DTC_RVDRV);
|
||||||
} else {
|
} else {
|
||||||
/* Start the unit if not already running */
|
/* Start the unit if not already running */
|
||||||
dt_unit[i].u3 &= ~DTC_FNC_STOP;
|
dt_unit[i].CMD &= ~DTC_FNC_STOP;
|
||||||
if ((dt_unit[i].DSTATE & (DTC_MOT)) == 0) {
|
if ((dt_unit[i].DSTATE & (DTC_MOT)) == 0) {
|
||||||
dt_unit[i].u3 |= DTC_FNC_START;
|
dt_unit[i].CMD |= DTC_FNC_START;
|
||||||
dtsb |= DTB_DLY;
|
dtsb |= DTB_DLY;
|
||||||
if (!sim_is_active(&dt_unit[i]))
|
if (!sim_is_active(&dt_unit[i]))
|
||||||
sim_activate(&dt_unit[i], 10000);
|
sim_activate(&dt_unit[i], 10000);
|
||||||
|
@ -442,20 +453,20 @@ t_stat dt_devio(uint32 dev, uint64 *data) {
|
||||||
switch(*data & (DTC_FWDRV|DTC_RVDRV)) {
|
switch(*data & (DTC_FWDRV|DTC_RVDRV)) {
|
||||||
case DTC_FWDRV:
|
case DTC_FWDRV:
|
||||||
if (dt_unit[i].DSTATE & DTC_REV) {
|
if (dt_unit[i].DSTATE & DTC_REV) {
|
||||||
dt_unit[i].u3 |= DTC_FNC_REV;
|
dt_unit[i].CMD |= DTC_FNC_REV;
|
||||||
dtsa |= (DTC_RVDRV);
|
dtsa |= (DTC_RVDRV);
|
||||||
} else
|
} else
|
||||||
dtsa |= (DTC_FWDRV);
|
dtsa |= (DTC_FWDRV);
|
||||||
break;
|
break;
|
||||||
case DTC_RVDRV:
|
case DTC_RVDRV:
|
||||||
if ((dt_unit[i].DSTATE & DTC_REV) == 0) {
|
if ((dt_unit[i].DSTATE & DTC_REV) == 0) {
|
||||||
dt_unit[i].u3 |= DTC_FNC_REV;
|
dt_unit[i].CMD |= DTC_FNC_REV;
|
||||||
dtsa |= (DTC_RVDRV);
|
dtsa |= (DTC_RVDRV);
|
||||||
} else
|
} else
|
||||||
dtsa |= (DTC_FWDRV);
|
dtsa |= (DTC_FWDRV);
|
||||||
break;
|
break;
|
||||||
case DTC_FWDRV|DTC_RVDRV:
|
case DTC_FWDRV|DTC_RVDRV:
|
||||||
dt_unit[i].u3 |= DTC_FNC_REV;
|
dt_unit[i].CMD |= DTC_FNC_REV;
|
||||||
if ((dt_unit[i].DSTATE & DTC_REV) == 0)
|
if ((dt_unit[i].DSTATE & DTC_REV) == 0)
|
||||||
dtsa |= (DTC_RVDRV);
|
dtsa |= (DTC_RVDRV);
|
||||||
else
|
else
|
||||||
|
@ -500,7 +511,7 @@ t_stat dt_devio(uint32 dev, uint64 *data) {
|
||||||
for (i = 0; i < DT_NUMDR; i++) {
|
for (i = 0; i < DT_NUMDR; i++) {
|
||||||
if (i != DTC_GETUNI(dtsa) &&
|
if (i != DTC_GETUNI(dtsa) &&
|
||||||
(dt_unit[i].DSTATE & DTC_MOT) != 0)
|
(dt_unit[i].DSTATE & DTC_MOT) != 0)
|
||||||
dt_unit[i].u3 |= DTC_FNC_STOP;
|
dt_unit[i].CMD |= DTC_FNC_STOP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dtsb = (uint64)((*data & (DTS_PAR_ERR|DTS_DATA_MISS|DTS_JOB_DONE| \
|
dtsb = (uint64)((*data & (DTS_PAR_ERR|DTS_DATA_MISS|DTS_JOB_DONE| \
|
||||||
|
@ -569,11 +580,11 @@ t_stat dt_svc (UNIT *uptr)
|
||||||
*/
|
*/
|
||||||
if (uptr->DSTATE & DTC_MOT) {
|
if (uptr->DSTATE & DTC_MOT) {
|
||||||
/* Check if stoping */
|
/* Check if stoping */
|
||||||
if (uptr->u3 & DTC_FNC_STOP) {
|
if (uptr->CMD & DTC_FNC_STOP) {
|
||||||
/* Stop delay */
|
/* Stop delay */
|
||||||
sim_debug(DEBUG_DETAIL, &dt_dev, "DTA %o stopping\n", u);
|
sim_debug(DEBUG_DETAIL, &dt_dev, "DTA %o stopping\n", u);
|
||||||
sim_activate(uptr, DT_WRDTIM*10);
|
sim_activate(uptr, DT_WRDTIM*10);
|
||||||
uptr->u3 &= ~DTC_FNC_STOP;
|
uptr->CMD &= ~DTC_FNC_STOP;
|
||||||
uptr->DSTATE &= ~(DTC_MOT);
|
uptr->DSTATE &= ~(DTC_MOT);
|
||||||
blk = (uptr->DSTATE >> DTC_V_BLK) & DTC_M_BLK;
|
blk = (uptr->DSTATE >> DTC_V_BLK) & DTC_M_BLK;
|
||||||
uptr->DSTATE = (0100 << DTC_V_WORD) | DTC_BLOCK | (DTC_MOTMASK & uptr->DSTATE);
|
uptr->DSTATE = (0100 << DTC_V_WORD) | DTC_BLOCK | (DTC_MOTMASK & uptr->DSTATE);
|
||||||
|
@ -591,10 +602,10 @@ if (uptr->DSTATE & DTC_MOT) {
|
||||||
uptr->DSTATE |= (blk << DTC_V_BLK);
|
uptr->DSTATE |= (blk << DTC_V_BLK);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
if (uptr->u3 & DTC_FNC_REV) {
|
if (uptr->CMD & DTC_FNC_REV) {
|
||||||
sim_activate(uptr, DT_WRDTIM*10);
|
sim_activate(uptr, DT_WRDTIM*10);
|
||||||
sim_debug(DEBUG_DETAIL, &dt_dev, "DTA %o reversing\n", u);
|
sim_debug(DEBUG_DETAIL, &dt_dev, "DTA %o reversing\n", u);
|
||||||
uptr->u3 &= ~DTC_FNC_REV;
|
uptr->CMD &= ~DTC_FNC_REV;
|
||||||
uptr->DSTATE ^= DTC_REV;
|
uptr->DSTATE ^= DTC_REV;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
@ -614,7 +625,7 @@ if (uptr->DSTATE & DTC_MOT) {
|
||||||
case DTC_FEND: /* Tape in endzone */
|
case DTC_FEND: /* Tape in endzone */
|
||||||
/* Set stop */
|
/* Set stop */
|
||||||
sim_debug(DEBUG_DETAIL, &dt_dev, "DTA %o rev forward end\n", u);
|
sim_debug(DEBUG_DETAIL, &dt_dev, "DTA %o rev forward end\n", u);
|
||||||
uptr->u3 |= DTC_FNC_STOP;
|
uptr->CMD |= DTC_FNC_STOP;
|
||||||
uptr->u6 = 0;
|
uptr->u6 = 0;
|
||||||
dtsb |= DTB_END;
|
dtsb |= DTB_END;
|
||||||
dtsb &= ~DTB_IDL;
|
dtsb &= ~DTB_IDL;
|
||||||
|
@ -636,7 +647,7 @@ if (uptr->DSTATE & DTC_MOT) {
|
||||||
if (dtsb & DTB_STOP)
|
if (dtsb & DTB_STOP)
|
||||||
dtsa &= ~0700; /* Clear command */
|
dtsa &= ~0700; /* Clear command */
|
||||||
sim_debug(DEBUG_DETAIL, &dt_dev, "DTA %o rev forward block\n", u);
|
sim_debug(DEBUG_DETAIL, &dt_dev, "DTA %o rev forward block\n", u);
|
||||||
switch (DTC_GETFNC(uptr->u3)) {
|
switch (DTC_GETFNC(uptr->CMD)) {
|
||||||
case FNC_MOVE:
|
case FNC_MOVE:
|
||||||
case FNC_SRCH:
|
case FNC_SRCH:
|
||||||
case FNC_WBLK:
|
case FNC_WBLK:
|
||||||
|
@ -647,7 +658,7 @@ if (uptr->DSTATE & DTC_MOT) {
|
||||||
case FNC_RALL:
|
case FNC_RALL:
|
||||||
case FNC_WRIT:
|
case FNC_WRIT:
|
||||||
case FNC_READ:
|
case FNC_READ:
|
||||||
uptr->u3 &= 077077;
|
uptr->CMD &= 077077;
|
||||||
dtsb |= DTB_DONE;
|
dtsb |= DTB_DONE;
|
||||||
if (dtsb & DTB_JOBENB)
|
if (dtsb & DTB_JOBENB)
|
||||||
set_interrupt(DT_DEVNUM, dtsa);
|
set_interrupt(DT_DEVNUM, dtsa);
|
||||||
|
@ -661,11 +672,11 @@ if (uptr->DSTATE & DTC_MOT) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (dtsb & (DTB_PAR|DTB_MIS|DTB_ILL|DTB_END|DTB_INCBLK|DTB_MRKERR)) {
|
if (dtsb & (DTB_PAR|DTB_MIS|DTB_ILL|DTB_END|DTB_INCBLK|DTB_MRKERR)) {
|
||||||
uptr->u3 |= DTC_FNC_STOP;
|
uptr->CMD |= DTC_FNC_STOP;
|
||||||
}
|
}
|
||||||
if (DTC_GETUNI(dtsa) == u) {
|
if (DTC_GETUNI(dtsa) == u) {
|
||||||
uptr->u3 &= 077077;
|
uptr->CMD &= 077077;
|
||||||
uptr->u3 |= dtsa & 0700; /* Copy command */
|
uptr->CMD |= dtsa & 0700; /* Copy command */
|
||||||
}
|
}
|
||||||
if (word <= 0) {
|
if (word <= 0) {
|
||||||
uptr->DSTATE = DTC_FEND | (DTC_MOTMASK & uptr->DSTATE);
|
uptr->DSTATE = DTC_FEND | (DTC_MOTMASK & uptr->DSTATE);
|
||||||
|
@ -698,7 +709,7 @@ if (uptr->DSTATE & DTC_MOT) {
|
||||||
uptr->DSTATE |= (word - 1) << DTC_V_WORD;
|
uptr->DSTATE |= (word - 1) << DTC_V_WORD;
|
||||||
}
|
}
|
||||||
uptr->u6-=2;
|
uptr->u6-=2;
|
||||||
switch (DTC_GETFNC(uptr->u3)) {
|
switch (DTC_GETFNC(uptr->CMD)) {
|
||||||
case FNC_MOVE:
|
case FNC_MOVE:
|
||||||
case FNC_SRCH:
|
case FNC_SRCH:
|
||||||
case FNC_WBLK:
|
case FNC_WBLK:
|
||||||
|
@ -724,6 +735,7 @@ if (uptr->DSTATE & DTC_MOT) {
|
||||||
data = dtdb;
|
data = dtdb;
|
||||||
fbuf[off] = (data >> 18) & RMASK;
|
fbuf[off] = (data >> 18) & RMASK;
|
||||||
fbuf[off+1] = data & RMASK;
|
fbuf[off+1] = data & RMASK;
|
||||||
|
uptr->WRITTEN = 1;
|
||||||
uptr->hwmark = uptr->capac;
|
uptr->hwmark = uptr->capac;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -740,15 +752,16 @@ if (uptr->DSTATE & DTC_MOT) {
|
||||||
sim_activate(uptr,DT_WRDTIM*2);
|
sim_activate(uptr,DT_WRDTIM*2);
|
||||||
sim_debug(DEBUG_DETAIL, &dt_dev, "DTA %o rev reverse check\n", u);
|
sim_debug(DEBUG_DETAIL, &dt_dev, "DTA %o rev reverse check\n", u);
|
||||||
word = (uptr->DSTATE >> DTC_V_BLK) & DTC_M_BLK;
|
word = (uptr->DSTATE >> DTC_V_BLK) & DTC_M_BLK;
|
||||||
uptr->DSTATE = DTC_BLOCK|(word << DTC_V_BLK)|(DTC_M_WORD << DTC_V_WORD) | (DTC_MOTMASK & uptr->DSTATE);
|
uptr->DSTATE = DTC_BLOCK|(word << DTC_V_BLK)|(DTC_M_WORD << DTC_V_WORD) |
|
||||||
|
(DTC_MOTMASK & uptr->DSTATE);
|
||||||
if (dtsb & DTB_STOP)
|
if (dtsb & DTB_STOP)
|
||||||
dtsa &= ~0700; /* Clear command */
|
dtsa &= ~0700; /* Clear command */
|
||||||
if (DTC_GETUNI(dtsa) == u) {
|
if (DTC_GETUNI(dtsa) == u) {
|
||||||
uptr->u3 &= 077077;
|
uptr->CMD &= 077077;
|
||||||
uptr->u3 |= dtsa & 0700; /* Copy command */
|
uptr->CMD |= dtsa & 0700; /* Copy command */
|
||||||
}
|
}
|
||||||
dtsb &= ~DTB_BLKRD;
|
dtsb &= ~DTB_BLKRD;
|
||||||
switch (DTC_GETFNC(uptr->u3)) {
|
switch (DTC_GETFNC(uptr->CMD)) {
|
||||||
case FNC_WRIT:
|
case FNC_WRIT:
|
||||||
case FNC_WALL:
|
case FNC_WALL:
|
||||||
dtsb |= DTB_DATREQ;
|
dtsb |= DTB_DATREQ;
|
||||||
|
@ -772,7 +785,7 @@ if (uptr->DSTATE & DTC_MOT) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (dtsb & (DTB_PAR|DTB_MIS|DTB_ILL|DTB_END|DTB_INCBLK|DTB_MRKERR)) {
|
if (dtsb & (DTB_PAR|DTB_MIS|DTB_ILL|DTB_END|DTB_INCBLK|DTB_MRKERR)) {
|
||||||
uptr->u3 |= DTC_FNC_STOP;
|
uptr->CMD |= DTC_FNC_STOP;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -780,15 +793,16 @@ if (uptr->DSTATE & DTC_MOT) {
|
||||||
sim_activate(uptr,DT_WRDTIM*2);
|
sim_activate(uptr,DT_WRDTIM*2);
|
||||||
word = (uptr->DSTATE >> DTC_V_BLK) & DTC_M_BLK;
|
word = (uptr->DSTATE >> DTC_V_BLK) & DTC_M_BLK;
|
||||||
data = (uint64)word;
|
data = (uint64)word;
|
||||||
uptr->DSTATE = DTC_RCHK|(word << DTC_V_BLK)|(DTC_M_WORD << DTC_V_WORD) | (DTC_MOTMASK & uptr->DSTATE);
|
uptr->DSTATE = DTC_RCHK|(word << DTC_V_BLK)|(DTC_M_WORD << DTC_V_WORD) |
|
||||||
|
(DTC_MOTMASK & uptr->DSTATE);
|
||||||
sim_debug(DEBUG_DETAIL, &dt_dev, "DTA %o rev reverse block %04o\n", u, word);
|
sim_debug(DEBUG_DETAIL, &dt_dev, "DTA %o rev reverse block %04o\n", u, word);
|
||||||
dtsb &= ~DTB_END;
|
dtsb &= ~DTB_END;
|
||||||
dtsb |= DTB_BLKRD;
|
dtsb |= DTB_BLKRD;
|
||||||
if (DTC_GETUNI(dtsa) == u) {
|
if (DTC_GETUNI(dtsa) == u) {
|
||||||
uptr->u3 &= 077077;
|
uptr->CMD &= 077077;
|
||||||
uptr->u3 |= dtsa & 0700; /* Copy command */
|
uptr->CMD |= dtsa & 0700; /* Copy command */
|
||||||
}
|
}
|
||||||
switch (DTC_GETFNC(uptr->u3)) {
|
switch (DTC_GETFNC(uptr->CMD)) {
|
||||||
case FNC_MOVE:
|
case FNC_MOVE:
|
||||||
case FNC_READ:
|
case FNC_READ:
|
||||||
case FNC_WMRK:
|
case FNC_WMRK:
|
||||||
|
@ -839,10 +853,10 @@ if (uptr->DSTATE & DTC_MOT) {
|
||||||
sim_debug(DEBUG_DETAIL, &dt_dev, "DTA %o forward block %04o\n", u, word);
|
sim_debug(DEBUG_DETAIL, &dt_dev, "DTA %o forward block %04o\n", u, word);
|
||||||
data = (uint64)word;
|
data = (uint64)word;
|
||||||
if (DTC_GETUNI(dtsa) == u) {
|
if (DTC_GETUNI(dtsa) == u) {
|
||||||
uptr->u3 &= 077077;
|
uptr->CMD &= 077077;
|
||||||
uptr->u3 |= dtsa & 0700; /* Copy command */
|
uptr->CMD |= dtsa & 0700; /* Copy command */
|
||||||
}
|
}
|
||||||
switch (DTC_GETFNC(uptr->u3)) {
|
switch (DTC_GETFNC(uptr->CMD)) {
|
||||||
case FNC_RALL:
|
case FNC_RALL:
|
||||||
case FNC_SRCH:
|
case FNC_SRCH:
|
||||||
dt_putword(&data);
|
dt_putword(&data);
|
||||||
|
@ -872,10 +886,10 @@ if (uptr->DSTATE & DTC_MOT) {
|
||||||
if (dtsb & DTB_STOP)
|
if (dtsb & DTB_STOP)
|
||||||
dtsa &= ~0700; /* Clear command */
|
dtsa &= ~0700; /* Clear command */
|
||||||
if (DTC_GETUNI(dtsa) == u) {
|
if (DTC_GETUNI(dtsa) == u) {
|
||||||
uptr->u3 &= 077077;
|
uptr->CMD &= 077077;
|
||||||
uptr->u3 |= dtsa & 0700; /* Copy command */
|
uptr->CMD |= dtsa & 0700; /* Copy command */
|
||||||
}
|
}
|
||||||
switch (DTC_GETFNC(uptr->u3)) {
|
switch (DTC_GETFNC(uptr->CMD)) {
|
||||||
case FNC_WRIT:
|
case FNC_WRIT:
|
||||||
case FNC_WALL:
|
case FNC_WALL:
|
||||||
dtsb |= DTB_DATREQ;
|
dtsb |= DTB_DATREQ;
|
||||||
|
@ -899,7 +913,7 @@ if (uptr->DSTATE & DTC_MOT) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (dtsb & (DTB_PAR|DTB_MIS|DTB_ILL|DTB_END|DTB_INCBLK|DTB_MRKERR)) {
|
if (dtsb & (DTB_PAR|DTB_MIS|DTB_ILL|DTB_END|DTB_INCBLK|DTB_MRKERR)) {
|
||||||
uptr->u3 |= DTC_FNC_STOP;
|
uptr->CMD |= DTC_FNC_STOP;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -918,7 +932,7 @@ if (uptr->DSTATE & DTC_MOT) {
|
||||||
uptr->DSTATE &= ~(DTC_M_WORD << DTC_V_WORD);
|
uptr->DSTATE &= ~(DTC_M_WORD << DTC_V_WORD);
|
||||||
uptr->DSTATE |= (word + 1) << DTC_V_WORD;
|
uptr->DSTATE |= (word + 1) << DTC_V_WORD;
|
||||||
}
|
}
|
||||||
switch (DTC_GETFNC(uptr->u3)) {
|
switch (DTC_GETFNC(uptr->CMD)) {
|
||||||
case FNC_MOVE:
|
case FNC_MOVE:
|
||||||
case FNC_SRCH:
|
case FNC_SRCH:
|
||||||
case FNC_WALL:
|
case FNC_WALL:
|
||||||
|
@ -931,17 +945,18 @@ if (uptr->DSTATE & DTC_MOT) {
|
||||||
if ((dtsb & DTB_STOP) == 0)
|
if ((dtsb & DTB_STOP) == 0)
|
||||||
dt_putword(&data);
|
dt_putword(&data);
|
||||||
else
|
else
|
||||||
uptr->u3 &= 077077;
|
uptr->CMD &= 077077;
|
||||||
break;
|
break;
|
||||||
case FNC_WRIT:
|
case FNC_WRIT:
|
||||||
if ((dtsb & DTB_STOP) == 0)
|
if ((dtsb & DTB_STOP) == 0)
|
||||||
dt_getword(&data, (word != DTC_M_WORD));
|
dt_getword(&data, (word != DTC_M_WORD));
|
||||||
else {
|
else {
|
||||||
uptr->u3 &= 077077;
|
uptr->CMD &= 077077;
|
||||||
data = dtdb;
|
data = dtdb;
|
||||||
}
|
}
|
||||||
fbuf[off] = (data >> 18) & RMASK;
|
fbuf[off] = (data >> 18) & RMASK;
|
||||||
fbuf[off+1] = data & RMASK;
|
fbuf[off+1] = data & RMASK;
|
||||||
|
uptr->WRITTEN = 1;
|
||||||
uptr->hwmark = uptr->capac;
|
uptr->hwmark = uptr->capac;
|
||||||
break;
|
break;
|
||||||
case FNC_WMRK:
|
case FNC_WMRK:
|
||||||
|
@ -972,20 +987,21 @@ if (uptr->DSTATE & DTC_MOT) {
|
||||||
dtsb &= ~(DTB_CHK);
|
dtsb &= ~(DTB_CHK);
|
||||||
dtsb |= DTB_IDL;
|
dtsb |= DTB_IDL;
|
||||||
if (DTC_GETUNI(dtsa) == u) {
|
if (DTC_GETUNI(dtsa) == u) {
|
||||||
uptr->u3 &= 077077;
|
uptr->CMD &= 077077;
|
||||||
uptr->u3 |= dtsa & 0700; /* Copy command */
|
uptr->CMD |= dtsa & 0700; /* Copy command */
|
||||||
}
|
}
|
||||||
word = (uptr->DSTATE >> DTC_V_BLK) & DTC_M_BLK;
|
word = (uptr->DSTATE >> DTC_V_BLK) & DTC_M_BLK;
|
||||||
word++;
|
word++;
|
||||||
if (word > 01101) {
|
if (word > 01101) {
|
||||||
uptr->DSTATE = DTC_REND|(word << DTC_V_BLK)|(DTC_M_WORD << DTC_V_WORD) | (DTC_MOTMASK & uptr->DSTATE);
|
uptr->DSTATE = DTC_REND|(word << DTC_V_BLK)|(DTC_M_WORD << DTC_V_WORD) |
|
||||||
|
(DTC_MOTMASK & uptr->DSTATE);
|
||||||
} else {
|
} else {
|
||||||
uptr->DSTATE = DTC_FBLK|(word << DTC_V_BLK) | (DTC_MOTMASK & uptr->DSTATE);
|
uptr->DSTATE = DTC_FBLK|(word << DTC_V_BLK) | (DTC_MOTMASK & uptr->DSTATE);
|
||||||
}
|
}
|
||||||
if (dtsb & DTB_STOP)
|
if (dtsb & DTB_STOP)
|
||||||
dtsa &= ~0700; /* Clear command */
|
dtsa &= ~0700; /* Clear command */
|
||||||
sim_debug(DEBUG_DETAIL, &dt_dev, "DTA %o reverse block %o\n", u, word);
|
sim_debug(DEBUG_DETAIL, &dt_dev, "DTA %o reverse block %o\n", u, word);
|
||||||
switch (DTC_GETFNC(uptr->u3)) {
|
switch (DTC_GETFNC(uptr->CMD)) {
|
||||||
case FNC_MOVE:
|
case FNC_MOVE:
|
||||||
case FNC_WBLK:
|
case FNC_WBLK:
|
||||||
case FNC_SRCH:
|
case FNC_SRCH:
|
||||||
|
@ -997,7 +1013,7 @@ if (uptr->DSTATE & DTC_MOT) {
|
||||||
case FNC_WRIT:
|
case FNC_WRIT:
|
||||||
case FNC_READ:
|
case FNC_READ:
|
||||||
case FNC_WMRK:
|
case FNC_WMRK:
|
||||||
uptr->u3 &= 077077;
|
uptr->CMD &= 077077;
|
||||||
dtsb |= DTB_DONE;
|
dtsb |= DTB_DONE;
|
||||||
if (dtsb & DTB_JOBENB)
|
if (dtsb & DTB_JOBENB)
|
||||||
set_interrupt(DT_DEVNUM, dtsa);
|
set_interrupt(DT_DEVNUM, dtsa);
|
||||||
|
@ -1006,13 +1022,13 @@ if (uptr->DSTATE & DTC_MOT) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (dtsb & (DTB_PAR|DTB_MIS|DTB_ILL|DTB_END|DTB_INCBLK|DTB_MRKERR)) {
|
if (dtsb & (DTB_PAR|DTB_MIS|DTB_ILL|DTB_END|DTB_INCBLK|DTB_MRKERR)) {
|
||||||
uptr->u3 |= DTC_FNC_STOP;
|
uptr->CMD |= DTC_FNC_STOP;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DTC_REND: /* In final endzone */
|
case DTC_REND: /* In final endzone */
|
||||||
/* Set stop */
|
/* Set stop */
|
||||||
uptr->u3 |= DTC_FNC_STOP;
|
uptr->CMD |= DTC_FNC_STOP;
|
||||||
sim_debug(DEBUG_DETAIL, &dt_dev, "DTA %o reverse end\n", u);
|
sim_debug(DEBUG_DETAIL, &dt_dev, "DTA %o reverse end\n", u);
|
||||||
dtsb &= ~DTB_IDL;
|
dtsb &= ~DTB_IDL;
|
||||||
dtsb |= DTB_END;
|
dtsb |= DTB_END;
|
||||||
|
@ -1023,18 +1039,18 @@ if (uptr->DSTATE & DTC_MOT) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Check if starting */
|
/* Check if starting */
|
||||||
} else if (uptr->u3 & DTC_FNC_START) {
|
} else if (uptr->CMD & DTC_FNC_START) {
|
||||||
/* Start up delay */
|
/* Start up delay */
|
||||||
sim_activate(uptr, DT_WRDTIM*10);
|
sim_activate(uptr, DT_WRDTIM*10);
|
||||||
uptr->u3 &= ~(0700 | DTC_FNC_START);
|
uptr->CMD &= ~(0700 | DTC_FNC_START);
|
||||||
if (DTC_GETUNI(dtsa) == u)
|
if (DTC_GETUNI(dtsa) == u)
|
||||||
uptr->u3 |= dtsa & 0700; /* Copy command */
|
uptr->CMD |= dtsa & 0700; /* Copy command */
|
||||||
uptr->DSTATE |= DTC_MOT;
|
uptr->DSTATE |= DTC_MOT;
|
||||||
if (uptr->u3 & DTC_FNC_REV) {
|
if (uptr->CMD & DTC_FNC_REV) {
|
||||||
uptr->u3 &= ~DTC_FNC_REV;
|
uptr->CMD &= ~DTC_FNC_REV;
|
||||||
uptr->DSTATE ^= DTC_REV;
|
uptr->DSTATE ^= DTC_REV;
|
||||||
}
|
}
|
||||||
sim_debug(DEBUG_DETAIL, &dt_dev, "DTA %o start %06o\n", u, uptr->u3);
|
sim_debug(DEBUG_DETAIL, &dt_dev, "DTA %o start %06o\n", u, uptr->CMD);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
@ -1111,7 +1127,7 @@ t_stat dt_reset (DEVICE *dptr)
|
||||||
dtsb = dtsa = 0; /* clear status */
|
dtsb = dtsa = 0; /* clear status */
|
||||||
for (i = 0; i < DT_NUMDR; i++) {
|
for (i = 0; i < DT_NUMDR; i++) {
|
||||||
if ((dt_unit[i].DSTATE & DTC_MOT) != 0)
|
if ((dt_unit[i].DSTATE & DTC_MOT) != 0)
|
||||||
dt_unit[i].u3 |= DTC_FNC_STOP;
|
dt_unit[i].CMD |= DTC_FNC_STOP;
|
||||||
}
|
}
|
||||||
clr_interrupt(DT_DEVNUM);
|
clr_interrupt(DT_DEVNUM);
|
||||||
clr_interrupt(DT_DEVNUM|4);
|
clr_interrupt(DT_DEVNUM|4);
|
||||||
|
@ -1129,16 +1145,16 @@ t_stat dt_reset (DEVICE *dptr)
|
||||||
|
|
||||||
t_stat dt_attach (UNIT *uptr, CONST char *cptr)
|
t_stat dt_attach (UNIT *uptr, CONST char *cptr)
|
||||||
{
|
{
|
||||||
uint16 pdp8b[D8_NBSIZE];
|
uint16 pdp8b[D8_NBSIZE];
|
||||||
uint16 pdp11b[D18_BSIZE];
|
uint16 pdp11b[D18_BSIZE];
|
||||||
uint32 ba, sz, k, *fbuf;
|
uint32 ba, sz, k, *fbuf;
|
||||||
int32 u = uptr - dt_dev.units;
|
int32 u = uptr - dt_dev.units;
|
||||||
t_stat r;
|
t_stat r;
|
||||||
|
|
||||||
r = attach_unit (uptr, cptr); /* attach */
|
r = attach_unit (uptr, cptr); /* attach */
|
||||||
if (r != SCPE_OK) /* error? */
|
if (r != SCPE_OK) /* error? */
|
||||||
return r;
|
return r;
|
||||||
if ((sim_switches & SIM_SW_REST) == 0) { /* not from rest? */
|
if ((sim_switches & SIM_SW_REST) == 0) { /* not from rest? */
|
||||||
uptr->flags = uptr->flags & ~(UNIT_8FMT | UNIT_11FMT); /* default 18b */
|
uptr->flags = uptr->flags & ~(UNIT_8FMT | UNIT_11FMT); /* default 18b */
|
||||||
if (sim_switches & SWMASK ('T')) /* att 12b? */
|
if (sim_switches & SWMASK ('T')) /* att 12b? */
|
||||||
uptr->flags = uptr->flags | UNIT_8FMT;
|
uptr->flags = uptr->flags | UNIT_8FMT;
|
||||||
|
@ -1152,21 +1168,22 @@ if ((sim_switches & SIM_SW_REST) == 0) { /* not from rest? */
|
||||||
uptr->flags = uptr->flags | UNIT_11FMT;
|
uptr->flags = uptr->flags | UNIT_11FMT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uptr->capac = DTU_CAPAC (uptr); /* set capacity */
|
uptr->capac = DTU_CAPAC (uptr); /* set capacity */
|
||||||
uptr->filebuf = calloc (uptr->capac, sizeof (uint32));
|
uptr->filebuf = calloc (uptr->capac, sizeof (uint32));
|
||||||
if (uptr->filebuf == NULL) { /* can't alloc? */
|
if (uptr->filebuf == NULL) { /* can't alloc? */
|
||||||
detach_unit (uptr);
|
detach_unit (uptr);
|
||||||
return SCPE_MEM;
|
return SCPE_MEM;
|
||||||
}
|
}
|
||||||
fbuf = (uint32 *) uptr->filebuf; /* file buffer */
|
fbuf = (uint32 *) uptr->filebuf; /* file buffer */
|
||||||
printf ("%s%d: ", sim_dname (&dt_dev), u);
|
sim_printf ("%s%d: ", sim_dname (&dt_dev), u);
|
||||||
if (uptr->flags & UNIT_8FMT)
|
if (uptr->flags & UNIT_8FMT)
|
||||||
printf ("12b format");
|
sim_printf ("12b format");
|
||||||
else if (uptr->flags & UNIT_11FMT)
|
else if (uptr->flags & UNIT_11FMT)
|
||||||
printf ("16b format");
|
sim_printf ("16b format");
|
||||||
else printf ("18b/36b format");
|
else sim_printf ("18b/36b format");
|
||||||
printf (", buffering file in memory\n");
|
sim_printf (", buffering file in memory\n");
|
||||||
if (uptr->flags & UNIT_8FMT) { /* 12b? */
|
uptr->io_flush = dt_flush;
|
||||||
|
if (uptr->flags & UNIT_8FMT) { /* 12b? */
|
||||||
for (ba = 0; ba < uptr->capac; ) { /* loop thru file */
|
for (ba = 0; ba < uptr->capac; ) { /* loop thru file */
|
||||||
k = fxread (pdp8b, sizeof (uint16), D8_NBSIZE, uptr->fileref);
|
k = fxread (pdp8b, sizeof (uint16), D8_NBSIZE, uptr->fileref);
|
||||||
if (k == 0)
|
if (k == 0)
|
||||||
|
@ -1182,8 +1199,7 @@ if (uptr->flags & UNIT_8FMT) { /* 12b? */
|
||||||
}
|
}
|
||||||
} /* end file loop */
|
} /* end file loop */
|
||||||
uptr->hwmark = ba;
|
uptr->hwmark = ba;
|
||||||
} /* end if */
|
} else if (uptr->flags & UNIT_11FMT) { /* 16b? */
|
||||||
else if (uptr->flags & UNIT_11FMT) { /* 16b? */
|
|
||||||
for (ba = 0; ba < uptr->capac; ) { /* loop thru file */
|
for (ba = 0; ba < uptr->capac; ) { /* loop thru file */
|
||||||
k = fxread (pdp11b, sizeof (uint16), D18_BSIZE, uptr->fileref);
|
k = fxread (pdp11b, sizeof (uint16), D18_BSIZE, uptr->fileref);
|
||||||
if (k == 0)
|
if (k == 0)
|
||||||
|
@ -1194,15 +1210,15 @@ else if (uptr->flags & UNIT_11FMT) { /* 16b? */
|
||||||
fbuf[ba++] = pdp11b[k];
|
fbuf[ba++] = pdp11b[k];
|
||||||
}
|
}
|
||||||
uptr->hwmark = ba;
|
uptr->hwmark = ba;
|
||||||
} /* end elif */
|
} else uptr->hwmark = fxread (uptr->filebuf, sizeof (uint32),
|
||||||
else uptr->hwmark = fxread (uptr->filebuf, sizeof (uint32),
|
|
||||||
uptr->capac, uptr->fileref);
|
uptr->capac, uptr->fileref);
|
||||||
uptr->flags = uptr->flags | UNIT_BUF; /* set buf flag */
|
uptr->flags = uptr->flags | UNIT_BUF; /* set buf flag */
|
||||||
uptr->pos = DT_EZLIN; /* beyond leader */
|
uptr->pos = DT_EZLIN; /* beyond leader */
|
||||||
return SCPE_OK;
|
uptr->WRITTEN = 0;
|
||||||
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Detach routine
|
/* Flush tape image to disk
|
||||||
|
|
||||||
Cancel in progress operation
|
Cancel in progress operation
|
||||||
If 12b, convert 18b buffer to 12b and write to file
|
If 12b, convert 18b buffer to 12b and write to file
|
||||||
|
@ -1211,23 +1227,16 @@ return SCPE_OK;
|
||||||
Deallocate buffer
|
Deallocate buffer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
t_stat dt_detach (UNIT* uptr)
|
void dt_flush (UNIT* uptr)
|
||||||
{
|
{
|
||||||
uint16 pdp8b[D8_NBSIZE];
|
uint16 pdp8b[D8_NBSIZE];
|
||||||
uint16 pdp11b[D18_BSIZE];
|
uint16 pdp11b[D18_BSIZE];
|
||||||
uint32 ba, k, *fbuf;
|
uint32 ba, k, *fbuf;
|
||||||
int32 u = uptr - dt_dev.units;
|
int32 u = uptr - dt_dev.units;
|
||||||
|
|
||||||
if (!(uptr->flags & UNIT_ATT))
|
if (uptr->WRITTEN && uptr->hwmark && ((uptr->flags & UNIT_RO) == 0)) { /* any data? */
|
||||||
return SCPE_OK;
|
|
||||||
if (sim_is_active (uptr)) {
|
|
||||||
sim_cancel (uptr);
|
|
||||||
uptr->u3 = uptr->pos = 0;
|
|
||||||
}
|
|
||||||
fbuf = (uint32 *) uptr->filebuf; /* file buffer */
|
|
||||||
if (uptr->hwmark && ((uptr->flags & UNIT_RO) == 0)) { /* any data? */
|
|
||||||
printf ("%s%d: writing buffer to file\n", sim_dname (&dt_dev), u);
|
|
||||||
rewind (uptr->fileref); /* start of file */
|
rewind (uptr->fileref); /* start of file */
|
||||||
|
fbuf = (uint32 *) uptr->filebuf; /* file buffer */
|
||||||
if (uptr->flags & UNIT_8FMT) { /* 12b? */
|
if (uptr->flags & UNIT_8FMT) { /* 12b? */
|
||||||
for (ba = 0; ba < uptr->hwmark; ) { /* loop thru file */
|
for (ba = 0; ba < uptr->hwmark; ) { /* loop thru file */
|
||||||
for (k = 0; k < D8_NBSIZE; k = k + 3) { /* loop blk */
|
for (k = 0; k < D8_NBSIZE; k = k + 3) { /* loop blk */
|
||||||
|
@ -1241,8 +1250,7 @@ if (uptr->hwmark && ((uptr->flags & UNIT_RO) == 0)) { /* any data? */
|
||||||
if (ferror (uptr->fileref))
|
if (ferror (uptr->fileref))
|
||||||
break;
|
break;
|
||||||
} /* end loop file */
|
} /* end loop file */
|
||||||
} /* end if 12b */
|
} else if (uptr->flags & UNIT_11FMT) { /* 16b? */
|
||||||
else if (uptr->flags & UNIT_11FMT) { /* 16b? */
|
|
||||||
for (ba = 0; ba < uptr->hwmark; ) { /* loop thru file */
|
for (ba = 0; ba < uptr->hwmark; ) { /* loop thru file */
|
||||||
for (k = 0; k < D18_BSIZE; k++) /* loop blk */
|
for (k = 0; k < D18_BSIZE; k++) /* loop blk */
|
||||||
pdp11b[k] = fbuf[ba++] & 0177777;
|
pdp11b[k] = fbuf[ba++] & 0177777;
|
||||||
|
@ -1254,13 +1262,39 @@ if (uptr->hwmark && ((uptr->flags & UNIT_RO) == 0)) { /* any data? */
|
||||||
else fxwrite (uptr->filebuf, sizeof (uint32), /* write file */
|
else fxwrite (uptr->filebuf, sizeof (uint32), /* write file */
|
||||||
uptr->hwmark, uptr->fileref);
|
uptr->hwmark, uptr->fileref);
|
||||||
if (ferror (uptr->fileref))
|
if (ferror (uptr->fileref))
|
||||||
perror ("I/O error");
|
sim_perror ("I/O error");
|
||||||
} /* end if hwmark */
|
} /* end if hwmark */
|
||||||
free (uptr->filebuf); /* release buf */
|
uptr->WRITTEN = 0;
|
||||||
uptr->flags = uptr->flags & ~UNIT_BUF; /* clear buf flag */
|
}
|
||||||
uptr->filebuf = NULL; /* clear buf ptr */
|
|
||||||
uptr->flags = uptr->flags & ~(UNIT_8FMT | UNIT_11FMT); /* default fmt */
|
/* Detach routine
|
||||||
uptr->capac = DT_CAPAC; /* default size */
|
|
||||||
return detach_unit (uptr);
|
Cancel in progress operation
|
||||||
|
If 12b, convert 18b buffer to 12b and write to file
|
||||||
|
If 16b, convert 18b buffer to 16b and write to file
|
||||||
|
If 18b/36b, write buffer to file
|
||||||
|
Deallocate buffer
|
||||||
|
*/
|
||||||
|
|
||||||
|
t_stat dt_detach (UNIT* uptr)
|
||||||
|
{
|
||||||
|
int32 u = uptr - dt_dev.units;
|
||||||
|
|
||||||
|
if (!(uptr->flags & UNIT_ATT))
|
||||||
|
return SCPE_OK;
|
||||||
|
if (sim_is_active (uptr)) {
|
||||||
|
sim_cancel (uptr);
|
||||||
|
uptr->CMD = uptr->pos = 0;
|
||||||
|
}
|
||||||
|
if (uptr->hwmark && ((uptr->flags & UNIT_RO) == 0)) { /* any data? */
|
||||||
|
sim_printf ("%s%d: writing buffer to file\n", sim_dname (&dt_dev), u);
|
||||||
|
dt_flush(uptr);
|
||||||
|
} /* end if hwmark */
|
||||||
|
free (uptr->filebuf); /* release buf */
|
||||||
|
uptr->flags = uptr->flags & ~UNIT_BUF; /* clear buf flag */
|
||||||
|
uptr->filebuf = NULL; /* clear buf ptr */
|
||||||
|
uptr->flags = uptr->flags & ~(UNIT_8FMT | UNIT_11FMT); /* default fmt */
|
||||||
|
uptr->capac = DT_CAPAC; /* default size */
|
||||||
|
return detach_unit (uptr);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* ka10_imp.c: IMP, interface message processor.
|
/* kx10_imp.c: IMP, interface message processor.
|
||||||
|
|
||||||
Copyright (c) 2018, Richard Cornwell based on code provided by
|
Copyright (c) 2018-2020, Richard Cornwell based on code provided by
|
||||||
Lars Brinkhoff and Danny Gasparovski.
|
Lars Brinkhoff and Danny Gasparovski.
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
@ -451,6 +451,7 @@ static CONST ETH_MAC broadcast_ethaddr = {0xff,0xff,0xff,0xff,0xff,0xff};
|
||||||
static CONST in_addr_T broadcast_ipaddr = {0xffffffff};
|
static CONST in_addr_T broadcast_ipaddr = {0xffffffff};
|
||||||
|
|
||||||
t_stat imp_devio(uint32 dev, uint64 *data);
|
t_stat imp_devio(uint32 dev, uint64 *data);
|
||||||
|
t_addr imp_devirq(uint32 dev, t_addr addr);
|
||||||
t_stat imp_srv(UNIT *);
|
t_stat imp_srv(UNIT *);
|
||||||
t_stat imp_eth_srv(UNIT *);
|
t_stat imp_eth_srv(UNIT *);
|
||||||
t_stat imp_tim_srv(UNIT *);
|
t_stat imp_tim_srv(UNIT *);
|
||||||
|
@ -503,7 +504,13 @@ UNIT imp_unit[] = {
|
||||||
{UDATA(imp_eth_srv, UNIT_IDLE+UNIT_DIS, 0)}, /* 0 */
|
{UDATA(imp_eth_srv, UNIT_IDLE+UNIT_DIS, 0)}, /* 0 */
|
||||||
{UDATA(imp_tim_srv, UNIT_IDLE+UNIT_DIS, 0)}, /* 0 */
|
{UDATA(imp_tim_srv, UNIT_IDLE+UNIT_DIS, 0)}, /* 0 */
|
||||||
};
|
};
|
||||||
DIB imp_dib = {IMP_DEVNUM, 1, &imp_devio, NULL};
|
DIB imp_dib = {IMP_DEVNUM, 1, &imp_devio,
|
||||||
|
#if KL
|
||||||
|
&imp_devirq,
|
||||||
|
#else
|
||||||
|
NULL
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
MTAB imp_mod[] = {
|
MTAB imp_mod[] = {
|
||||||
{ MTAB_XTD|MTAB_VDV|MTAB_VALR|MTAB_NC, 0, "MAC", "MAC=xx:xx:xx:xx:xx:xx",
|
{ MTAB_XTD|MTAB_VDV|MTAB_VALR|MTAB_NC, 0, "MAC", "MAC=xx:xx:xx:xx:xx:xx",
|
||||||
|
@ -562,10 +569,13 @@ DEBTAB imp_debug[] = {
|
||||||
{0, 0}
|
{0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
REG imp_reg[] = {
|
||||||
|
{SAVEDATA(DATA, imp_data) },
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
DEVICE imp_dev = {
|
DEVICE imp_dev = {
|
||||||
"IMP", imp_unit, NULL, imp_mod,
|
"IMP", imp_unit, imp_reg, imp_mod,
|
||||||
3, 8, 0, 1, 8, 36,
|
3, 8, 0, 1, 8, 36,
|
||||||
NULL, NULL, &imp_reset, NULL, &imp_attach, &imp_detach,
|
NULL, NULL, &imp_reset, NULL, &imp_attach, &imp_detach,
|
||||||
&imp_dib, DEV_DISABLE | DEV_DIS | DEV_DEBUG, 0, imp_debug,
|
&imp_dib, DEV_DISABLE | DEV_DIS | DEV_DEBUG, 0, imp_debug,
|
||||||
|
@ -635,6 +645,7 @@ t_stat imp_devio(uint32 dev, uint64 *data)
|
||||||
uptr->STATUS |= IMPIHE;
|
uptr->STATUS |= IMPIHE;
|
||||||
if (*data & IMPLHW) /* Last host word. */
|
if (*data & IMPLHW) /* Last host word. */
|
||||||
uptr->STATUS |= IMPLHW;
|
uptr->STATUS |= IMPLHW;
|
||||||
|
check_interrupts(uptr);
|
||||||
break;
|
break;
|
||||||
case TYPE_BBN:
|
case TYPE_BBN:
|
||||||
break;
|
break;
|
||||||
|
@ -731,6 +742,20 @@ t_stat imp_devio(uint32 dev, uint64 *data)
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if KL
|
||||||
|
/* Handle KL style interrupt vectors for ITS */
|
||||||
|
t_addr
|
||||||
|
imp_devirq(uint32 dev, t_addr addr) {
|
||||||
|
if ((cpu_unit[0].flags & UNIT_ITSPAGE) != 0 && (imp_data.pia & 7) == 1) {
|
||||||
|
if (imp_unit[0].STATUS & IMPID && (imp_unit[0].STATUS & IMPLW) == 0)
|
||||||
|
return 070|RSIGN;
|
||||||
|
if (imp_unit[0].STATUS & IMPOD)
|
||||||
|
return 072|RSIGN;
|
||||||
|
}
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
t_stat imp_srv(UNIT * uptr)
|
t_stat imp_srv(UNIT * uptr)
|
||||||
{
|
{
|
||||||
DEVICE *dptr = find_dev_from_unit(uptr);
|
DEVICE *dptr = find_dev_from_unit(uptr);
|
||||||
|
@ -2669,6 +2694,7 @@ t_stat imp_attach(UNIT* uptr, CONST char* cptr)
|
||||||
if (tptr == NULL) return SCPE_MEM;
|
if (tptr == NULL) return SCPE_MEM;
|
||||||
strcpy(tptr, cptr);
|
strcpy(tptr, cptr);
|
||||||
|
|
||||||
|
memset(&imp_data.ReadQ, 0, sizeof(ETH_QUE));
|
||||||
status = eth_open(&imp_data.etherface, cptr, &imp_dev, DEBUG_ETHER);
|
status = eth_open(&imp_data.etherface, cptr, &imp_dev, DEBUG_ETHER);
|
||||||
if (status != SCPE_OK) {
|
if (status != SCPE_OK) {
|
||||||
free(tptr);
|
free(tptr);
|
||||||
|
@ -2747,12 +2773,12 @@ t_stat imp_detach(UNIT* uptr)
|
||||||
if (uptr->flags & UNIT_DHCP) {
|
if (uptr->flags & UNIT_DHCP) {
|
||||||
imp_dhcp_release(&imp_data);
|
imp_dhcp_release(&imp_data);
|
||||||
}
|
}
|
||||||
|
sim_cancel (uptr+1); /* stop the packet timing services */
|
||||||
|
sim_cancel (uptr+2); /* stop the clock timer services */
|
||||||
eth_close (&imp_data.etherface);
|
eth_close (&imp_data.etherface);
|
||||||
free(uptr->filename);
|
free(uptr->filename);
|
||||||
uptr->filename = NULL;
|
uptr->filename = NULL;
|
||||||
uptr->flags &= ~UNIT_ATT;
|
uptr->flags &= ~UNIT_ATT;
|
||||||
sim_cancel (uptr+1); /* stop the packet timing services */
|
|
||||||
sim_cancel (uptr+2); /* stop the clock timer services */
|
|
||||||
}
|
}
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* ka10_lp.c: PDP-10 line printer simulator
|
/* kx10_lp.c: PDP-10 line printer simulator
|
||||||
|
|
||||||
Copyright (c) 2011-2017, Richard Cornwell
|
Copyright (c) 2011-2020, Richard Cornwell
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -394,6 +394,8 @@ t_stat lpt_attach (UNIT *uptr, CONST char *cptr)
|
||||||
t_stat reason;
|
t_stat reason;
|
||||||
|
|
||||||
reason = attach_unit (uptr, cptr);
|
reason = attach_unit (uptr, cptr);
|
||||||
|
if (sim_switches & SIM_SW_REST)
|
||||||
|
return reason;
|
||||||
uptr->STATUS &= ~ERR_FLG;
|
uptr->STATUS &= ~ERR_FLG;
|
||||||
clr_interrupt(LP_DEVNUM);
|
clr_interrupt(LP_DEVNUM);
|
||||||
return reason;
|
return reason;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* ka10_mt.c: TM10A/B Magnetic tape controller
|
/* kx10_mt.c: TM10A/B Magnetic tape controller
|
||||||
|
|
||||||
Copyright (c) 2013-2017, Richard Cornwell
|
Copyright (c) 2013-2020, Richard Cornwell
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* ka10_pt.c: PDP-10 reader/punch simulator
|
/* kx10_pt.c: PDP-10 paper tape reader/punch simulator
|
||||||
|
|
||||||
Copyright (c) 2011-2017, Richard Cornwell
|
Copyright (c) 2011-2020, Richard Cornwell
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* ka10_rc.c: RC10 Disk Controller.
|
/* kx10_rc.c: RC10 Disk Controller.
|
||||||
|
|
||||||
Copyright (c) 2013-2017, Richard Cornwell
|
Copyright (c) 2013-2020, Richard Cornwell
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -187,7 +187,7 @@ DEVICE rca_dev = {
|
||||||
|
|
||||||
#if (NUM_DEVS_RC > 1)
|
#if (NUM_DEVS_RC > 1)
|
||||||
REG rcb_reg[] = {
|
REG rcb_reg[] = {
|
||||||
{BRDATA(BUFF, rc_buf[1], 16, 64, RM10_WDS), REG_HRO},
|
{BRDATA(BUFF, &rc_buf[1][0], 16, 64, RM10_WDS), REG_HRO},
|
||||||
{ORDATA(IPR, rc_ipr[1], 2), REG_HRO},
|
{ORDATA(IPR, rc_ipr[1], 2), REG_HRO},
|
||||||
{ORDATA(STATUS, rc_df10[1].status, 18), REG_RO},
|
{ORDATA(STATUS, rc_df10[1].status, 18), REG_RO},
|
||||||
{ORDATA(CIA, rc_df10[1].cia, 18)},
|
{ORDATA(CIA, rc_df10[1].cia, 18)},
|
||||||
|
@ -533,7 +533,7 @@ t_stat r;
|
||||||
|
|
||||||
uptr->capac = rc_drv_tab[GET_DTYPE (uptr->flags)].size;
|
uptr->capac = rc_drv_tab[GET_DTYPE (uptr->flags)].size;
|
||||||
r = attach_unit (uptr, cptr);
|
r = attach_unit (uptr, cptr);
|
||||||
if (r != SCPE_OK)
|
if (r != SCPE_OK || (sim_switches & SIM_SW_REST) != 0)
|
||||||
return r;
|
return r;
|
||||||
uptr->CUR_CYL = 0;
|
uptr->CUR_CYL = 0;
|
||||||
uptr->UFLAGS = 0;
|
uptr->UFLAGS = 0;
|
||||||
|
|
801
PDP10/kx10_rh.c
Normal file
801
PDP10/kx10_rh.c
Normal file
|
@ -0,0 +1,801 @@
|
||||||
|
/* kx10_rh.c: RH10/RH20 interace routines.
|
||||||
|
|
||||||
|
Copyright (c) 2019-2020, Richard Cornwell
|
||||||
|
|
||||||
|
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
|
||||||
|
RICHARD CORNWELL 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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "kx10_defs.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* CONI Flags */
|
||||||
|
#define IADR_ATTN 0000000000040LL /* Interrupt on attention */
|
||||||
|
#define IARD_RAE 0000000000100LL /* Interrupt on register access error */
|
||||||
|
#define DIB_CBOV 0000000000200LL /* Control bus overrun */
|
||||||
|
#define CXR_PS_FAIL 0000000002000LL /* Power supply fail (not implemented) */
|
||||||
|
#define CXR_ILC 0000000004000LL /* Illegal function code */
|
||||||
|
#define CR_DRE 0000000010000LL /* Or Data and Control Timeout */
|
||||||
|
#define DTC_OVER 0000000020000LL /* DF10 did not supply word on time (not implemented) */
|
||||||
|
#define CCW_COMP_1 0000000040000LL /* Control word written. */
|
||||||
|
#define CXR_CHAN_ER 0000000100000LL /* Channel Error */
|
||||||
|
#define CXR_EXC 0000000200000LL /* Error in drive transfer */
|
||||||
|
#define CXR_DBPE 0000000400000LL /* Device Parity error (not implemented) */
|
||||||
|
#define CXR_NXM 0000001000000LL /* Channel non-existent memory (not implemented) */
|
||||||
|
#define CXR_CWPE 0000002000000LL /* Channel Control word parity error (not implemented) */
|
||||||
|
#define CXR_CDPE 0000004000000LL /* Channel Data Parity Error (not implemented) */
|
||||||
|
#define CXR_SD_RAE 0000200000000LL /* Register access error */
|
||||||
|
#define CXR_ILFC 0000400000000LL /* Illegal CXR function code */
|
||||||
|
#define B22_FLAG 0004000000000LL /* 22 bit channel */
|
||||||
|
#define CC_CHAN_PLS 0010000000000LL /* Channel transfer pulse (not implemented) */
|
||||||
|
#define CC_CHAN_ACT 0020000000000LL /* Channel in use */
|
||||||
|
#define CC_INH 0040000000000LL /* Disconnect channel */
|
||||||
|
#define CB_FULL 0200000000000LL /* Set when channel buffer is full (not implemented) */
|
||||||
|
#define AR_FULL 0400000000000LL /* Set when AR is full (not implemented) */
|
||||||
|
|
||||||
|
/* RH20 CONI Flags */
|
||||||
|
#define RH20_PCR_FULL 0000000000020LL /* Primary command file full */
|
||||||
|
#define RH20_ATTN_ENA 0000000000040LL /* Attention enable */
|
||||||
|
#define RH20_SCR_FULL 0000000000100LL /* Secondary command full */
|
||||||
|
#define RH20_ATTN 0000000000200LL /* Attention */
|
||||||
|
#define RH20_MASS_ENA 0000000000400LL /* Mass bus enable */
|
||||||
|
#define RH20_DATA_OVR 0000000001000LL /* Data overrun */
|
||||||
|
#define RH20_CHAN_RDY 0000000002000LL /* Channel ready to start */
|
||||||
|
#define RH20_RAE 0000000004000LL /* Register access error */
|
||||||
|
#define RH20_DR_RESP 0000000010000LL /* Drive no response */
|
||||||
|
#define RH20_CHAN_ERR 0000000020000LL /* Channel error */
|
||||||
|
#define RH20_SHRT_WC 0000000040000LL /* Short word count */
|
||||||
|
#define RH20_LONG_WC 0000000100000LL /* Long word count */
|
||||||
|
#define RH20_DR_EXC 0000000200000LL /* Exception */
|
||||||
|
#define RH20_DATA_PRI 0000000400000LL /* Data parity error */
|
||||||
|
#define RH20_SBAR 0000001000000LL /* SBAR set */
|
||||||
|
#define RH20_XEND 0000002000000LL /* Transfer ended */
|
||||||
|
|
||||||
|
/* CONO Flags */
|
||||||
|
#define ATTN_EN 0000000000040LL /* enable attention interrupt. */
|
||||||
|
#define REA_EN 0000000000100LL /* enable register error interrupt */
|
||||||
|
#define CBOV_CLR 0000000000200LL /* Clear CBOV */
|
||||||
|
#define CONT_RESET 0000000002000LL /* Clear All error bits */
|
||||||
|
#define ILC_CLR 0000000004000LL /* Clear ILC and SD RAE */
|
||||||
|
#define DRE_CLR 0000000010000LL /* Clear CR_CBTO and CR_DBTO */
|
||||||
|
#define OVER_CLR 0000000020000LL /* Clear DTC overrun */
|
||||||
|
#define WRT_CW 0000000040000LL /* Write control word */
|
||||||
|
#define CHN_CLR 0000000100000LL /* Clear Channel Error */
|
||||||
|
#define DR_EXC_CLR 0000000200000LL /* Clear DR_EXC */
|
||||||
|
#define DBPE_CLR 0000000400000LL /* Clear CXR_DBPE */
|
||||||
|
|
||||||
|
/* RH20 CONO Flags */
|
||||||
|
#define RH20_DELETE_SCR 0000000000100LL /* Clear SCR */
|
||||||
|
#define RH20_RCLP 0000000000200LL /* Reset command list */
|
||||||
|
#define RH20_MASS_EN 0000000000400LL /* Mass bus enable */
|
||||||
|
#define RH20_XFER_CLR 0000000001000LL /* Clear XFER error */
|
||||||
|
#define RH20_CLR_MBC 0000000002000LL /* Clear MBC */
|
||||||
|
#define RH20_CLR_RAE 0000000004000LL /* Clear RAE error */
|
||||||
|
|
||||||
|
/* DATAO/DATAI */
|
||||||
|
#define CR_REG 0770000000000LL /* Register number */
|
||||||
|
#define LOAD_REG 0004000000000LL /* Load register */
|
||||||
|
#define CR_MAINT_MODE 0000100000000LL /* Maint mode... not implemented */
|
||||||
|
#define CR_DRIVE 0000007000000LL
|
||||||
|
#define CR_GEN_EVD 0000000400000LL /* Enable Parity */
|
||||||
|
#define CR_DXES 0000000200000LL /* Disable DXES errors */
|
||||||
|
#define CR_INAD 0000000077600LL
|
||||||
|
#define CR_WTEVM 0000000000100LL /* Verify Parity */
|
||||||
|
#define CR_FUNC 0000000000076LL
|
||||||
|
#define CR_GO 0000000000001LL
|
||||||
|
|
||||||
|
#define IRQ_VECT 0000000000777LL /* Interupt vector */
|
||||||
|
#define IRQ_KI10 0000002000000LL
|
||||||
|
#define IRQ_KA10 0000001000000LL
|
||||||
|
#define FNC_XFER 024 /* >=? data xfr */
|
||||||
|
|
||||||
|
/* Status register settings */
|
||||||
|
#define DS_OFF 0000001 /* offset mode */
|
||||||
|
#define DS_VV 0000100 /* volume valid */
|
||||||
|
#define DS_DRY 0000200 /* drive ready */
|
||||||
|
#define DS_DPR 0000400 /* drive present */
|
||||||
|
#define DS_PGM 0001000 /* programable NI */
|
||||||
|
#define DS_LST 0002000 /* last sector */
|
||||||
|
#define DS_WRL 0004000 /* write locked */
|
||||||
|
#define DS_MOL 0010000 /* medium online */
|
||||||
|
#define DS_PIP 0020000 /* pos in progress */
|
||||||
|
#define DS_ERR 0040000 /* error */
|
||||||
|
#define DS_ATA 0100000 /* attention active */
|
||||||
|
|
||||||
|
/* RH20 channel status flags */
|
||||||
|
#define RH20_MEM_PAR 00200000000000LL /* Memory parity error */
|
||||||
|
#define RH20_NADR_PAR 00100000000000LL /* Address parity error */
|
||||||
|
#define RH20_NOT_WC0 00040000000000LL /* Word count not zero */
|
||||||
|
#define RH20_NXM_ERR 00020000000000LL /* Non existent memory */
|
||||||
|
#define RH20_LAST_ERR 00000400000000LL /* Last transfer error */
|
||||||
|
#define RH20_ERROR 00000200000000LL /* RH20 error */
|
||||||
|
#define RH20_LONG_STS 00000100000000LL /* Did not reach wc */
|
||||||
|
#define RH20_SHRT_STS 00000040000000LL /* WC reached zero */
|
||||||
|
#define RH20_OVER 00000020000000LL /* Overrun error */
|
||||||
|
|
||||||
|
/* 0-37 mass bus register.
|
||||||
|
70 SBAR, block address.
|
||||||
|
71 STCR, neg block count, func
|
||||||
|
72 PBAR
|
||||||
|
73 PTCR
|
||||||
|
74 IVIR Interrupt vector address.
|
||||||
|
75 Diags read.
|
||||||
|
76 Diags write.
|
||||||
|
77 Status (tra,cb test, bar test, ev par, r/w, exc,ebl, 0, attn, sclk
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CCW 000..... New channel comand list pointer HALT.
|
||||||
|
010..... Next CCW Address JUMP
|
||||||
|
1xycount-address. x=halt last xfer, y=reverse
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern uint32 eb_ptr;
|
||||||
|
|
||||||
|
t_stat
|
||||||
|
rh_set_type(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
|
||||||
|
{
|
||||||
|
DEVICE *dptr;
|
||||||
|
DIB *dibp;
|
||||||
|
dptr = find_dev_from_unit (uptr);
|
||||||
|
if (dptr == NULL)
|
||||||
|
return SCPE_IERR;
|
||||||
|
dibp = (DIB *) dptr->ctxt;
|
||||||
|
dptr->flags &= ~DEV_M_RH;
|
||||||
|
dptr->flags |= val;
|
||||||
|
dibp->dev_num &= ~(RH10_DEV|RH20_DEV);
|
||||||
|
dibp->dev_num |= (val) ? RH20_DEV: RH10_DEV;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat rh_show_type (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
|
||||||
|
{
|
||||||
|
DEVICE *dptr;
|
||||||
|
|
||||||
|
if (uptr == NULL)
|
||||||
|
return SCPE_IERR;
|
||||||
|
|
||||||
|
dptr = find_dev_from_unit(uptr);
|
||||||
|
if (dptr == NULL)
|
||||||
|
return SCPE_IERR;
|
||||||
|
fprintf (st, "%s", (dptr->flags & TYPE_RH20) ? "RH20" : "RH10");
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
t_stat rh_devio(uint32 dev, uint64 *data) {
|
||||||
|
DEVICE *dptr = NULL;
|
||||||
|
struct rh_if *rhc = NULL;
|
||||||
|
int drive;
|
||||||
|
|
||||||
|
for (drive = 0; rh[drive].dev_num != 0; drive++) {
|
||||||
|
if (rh[drive].dev_num == (dev & 0774)) {
|
||||||
|
rhc = rh[drive].rh;
|
||||||
|
dptr = rh[drive].dev;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rhc == NULL)
|
||||||
|
return SCPE_OK;
|
||||||
|
#if KL
|
||||||
|
if (dptr->flags & TYPE_RH20) {
|
||||||
|
switch(dev & 3) {
|
||||||
|
case CONI:
|
||||||
|
*data = rhc->status & RMASK;
|
||||||
|
if (rhc->attn != 0)
|
||||||
|
*data |= RH20_ATTN;
|
||||||
|
if (rhc->rae != 0)
|
||||||
|
*data |= RH20_RAE;
|
||||||
|
sim_debug(DEBUG_CONI, dptr, "%s %03o CONI %06o PC=%o %o\n",
|
||||||
|
dptr->name, dev, (uint32)*data, PC, rhc->attn);
|
||||||
|
return SCPE_OK;
|
||||||
|
|
||||||
|
case CONO:
|
||||||
|
clr_interrupt(dev);
|
||||||
|
/* Clear flags */
|
||||||
|
if (*data & RH20_CLR_MBC) {
|
||||||
|
if (rhc->dev_reset != NULL)
|
||||||
|
rhc->dev_reset(dptr);
|
||||||
|
rhc->attn = 0;
|
||||||
|
rhc->imode = 2;
|
||||||
|
}
|
||||||
|
rhc->status &= ~(07LL|IADR_ATTN|RH20_MASS_EN);
|
||||||
|
rhc->status |= *data & (07LL|IADR_ATTN|RH20_MASS_EN);
|
||||||
|
if (*data & RH20_DELETE_SCR)
|
||||||
|
rhc->status &= ~(RH20_SBAR|RH20_SCR_FULL);
|
||||||
|
if (*data & (RH20_RCLP|RH20_CLR_MBC))
|
||||||
|
rhc->cia = eb_ptr | (rhc->devnum - 0540);
|
||||||
|
if (*data & (RH20_CLR_RAE|RH20_CLR_MBC))
|
||||||
|
rhc->rae = 0;
|
||||||
|
if (*data & PI_ENABLE)
|
||||||
|
rhc->status &= ~PI_ENABLE;
|
||||||
|
if (((rhc->status & IADR_ATTN) != 0 && rhc->attn != 0)
|
||||||
|
|| (rhc->status & PI_ENABLE))
|
||||||
|
set_interrupt(rhc->devnum, rhc->status);
|
||||||
|
sim_debug(DEBUG_CONO, dptr, "%s %03o CONO %06o PC=%06o %06o\n",
|
||||||
|
dptr->name, dev, (uint32)*data, PC, rhc->status);
|
||||||
|
return SCPE_OK;
|
||||||
|
|
||||||
|
case DATAI:
|
||||||
|
*data = 0;
|
||||||
|
if (rhc->status & BUSY && rhc->reg != 04) {
|
||||||
|
rhc->status |= CC_CHAN_ACT;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
if (rhc->reg < 040) {
|
||||||
|
int parity;
|
||||||
|
*data = (uint64)(rhc->dev_read(dptr, rhc, rhc->reg) & 0177777);
|
||||||
|
parity = (int)((*data >> 8) ^ *data);
|
||||||
|
parity = (parity >> 4) ^ parity;
|
||||||
|
parity = (parity >> 2) ^ parity;
|
||||||
|
parity = ((parity >> 1) ^ parity) & 1;
|
||||||
|
*data |= ((uint64)(!parity)) << 16;
|
||||||
|
*data |= ((uint64)(rhc->drive)) << 18;
|
||||||
|
*data |= BIT10;
|
||||||
|
} else if ((rhc->reg & 070) != 070) {
|
||||||
|
rhc->rae = 1;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
switch(rhc->reg & 07) {
|
||||||
|
case 0: *data = rhc->sbar; break;
|
||||||
|
case 1: *data = rhc->stcr; break;
|
||||||
|
case 2: *data = rhc->pbar; break;
|
||||||
|
case 3: *data = rhc->ptcr; break;
|
||||||
|
case 4: *data = rhc->ivect; break;
|
||||||
|
case 5:
|
||||||
|
case 6: break;
|
||||||
|
case 7: *data = 0; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*data |= ((uint64)(rhc->reg)) << 30;
|
||||||
|
sim_debug(DEBUG_DATAIO, dptr, "%s %03o DATI %012llo %d PC=%06o\n",
|
||||||
|
dptr->name, dev, *data, rhc->drive, PC);
|
||||||
|
return SCPE_OK;
|
||||||
|
|
||||||
|
case DATAO:
|
||||||
|
sim_debug(DEBUG_DATAIO, dptr, "%s %03o DATO %012llo PC=%06o %06o\n",
|
||||||
|
dptr->name, dev, *data, PC, rhc->status);
|
||||||
|
rhc->reg = ((int)(*data >> 30)) & 077;
|
||||||
|
rhc->imode |= 2;
|
||||||
|
if (rhc->reg < 040)
|
||||||
|
rhc->drive = (int)(*data >> 18) & 07;
|
||||||
|
if (*data & LOAD_REG) {
|
||||||
|
if (rhc->reg < 040) {
|
||||||
|
clr_interrupt(dev);
|
||||||
|
/* Check if access error */
|
||||||
|
if (rhc->rae & (1 << rhc->drive) && (*data & BIT9) == 0) {
|
||||||
|
set_interrupt(rhc->devnum, rhc->status);
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
rhc->dev_write(dptr, rhc, rhc->reg & 037, (int)(*data & 0777777));
|
||||||
|
if (((rhc->status & IADR_ATTN) != 0 && rhc->attn != 0)
|
||||||
|
|| (rhc->status & PI_ENABLE))
|
||||||
|
set_interrupt(rhc->devnum, rhc->status);
|
||||||
|
/* Check if access error */
|
||||||
|
if (rhc->rae & (1 << rhc->drive) && (*data & BIT9) == 0)
|
||||||
|
set_interrupt(rhc->devnum, rhc->status);
|
||||||
|
else
|
||||||
|
rhc->rae &= ~(1 << rhc->drive);
|
||||||
|
} else if ((rhc->reg & 070) != 070) {
|
||||||
|
if ((*data & BIT9) == 0) {
|
||||||
|
rhc->rae = (1 << rhc->drive);
|
||||||
|
set_interrupt(rhc->devnum, rhc->status);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch(rhc->reg & 07) {
|
||||||
|
case 0:
|
||||||
|
rhc->sbar = (*data) & (CR_DRIVE|RMASK);
|
||||||
|
rhc->status |= RH20_SBAR;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
rhc->stcr = (*data) & (BIT10|BIT7|CR_DRIVE|RMASK);
|
||||||
|
rhc->status |= RH20_SCR_FULL;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
rhc->ivect = (*data & IRQ_VECT);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
case 5:
|
||||||
|
case 6:
|
||||||
|
case 7:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((rhc->status & (RH20_SCR_FULL|RH20_PCR_FULL)) == (RH20_SCR_FULL))
|
||||||
|
rh20_setup(rhc);
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
switch(dev & 3) {
|
||||||
|
case CONI:
|
||||||
|
*data = rhc->status & ~(IADR_ATTN|IARD_RAE);
|
||||||
|
if (rhc->attn != 0 && (rhc->status & IADR_ATTN))
|
||||||
|
*data |= IADR_ATTN;
|
||||||
|
if (rhc->rae != 0 && (rhc->status & IARD_RAE))
|
||||||
|
*data |= IARD_RAE;
|
||||||
|
#if KI_22BIT
|
||||||
|
*data |= B22_FLAG;
|
||||||
|
#endif
|
||||||
|
sim_debug(DEBUG_CONI, dptr, "%s %03o CONI %06o PC=%o %o\n",
|
||||||
|
dptr->name, dev, (uint32)*data, PC, rhc->attn);
|
||||||
|
return SCPE_OK;
|
||||||
|
|
||||||
|
case CONO:
|
||||||
|
clr_interrupt(dev);
|
||||||
|
rhc->status &= ~(07LL|IADR_ATTN|IARD_RAE);
|
||||||
|
rhc->status |= *data & (07LL|IADR_ATTN|IARD_RAE);
|
||||||
|
/* Clear flags */
|
||||||
|
if (*data & CONT_RESET && rhc->dev_reset != NULL)
|
||||||
|
rhc->dev_reset(dptr);
|
||||||
|
if (*data & (DBPE_CLR|DR_EXC_CLR|CHN_CLR))
|
||||||
|
rhc->status &= ~(*data & (DBPE_CLR|DR_EXC_CLR|CHN_CLR));
|
||||||
|
if (*data & OVER_CLR)
|
||||||
|
rhc->status &= ~(DTC_OVER);
|
||||||
|
if (*data & CBOV_CLR)
|
||||||
|
rhc->status &= ~(DIB_CBOV);
|
||||||
|
if (*data & CXR_ILC)
|
||||||
|
rhc->status &= ~(CXR_ILFC|CXR_SD_RAE);
|
||||||
|
if (*data & WRT_CW)
|
||||||
|
rh_writecw(rhc, 0);
|
||||||
|
if (*data & PI_ENABLE)
|
||||||
|
rhc->status &= ~PI_ENABLE;
|
||||||
|
if (rhc->status & PI_ENABLE)
|
||||||
|
set_interrupt(dev, rhc->status);
|
||||||
|
if ((rhc->status & IADR_ATTN) != 0 && rhc->attn != 0)
|
||||||
|
set_interrupt(dev, rhc->status);
|
||||||
|
sim_debug(DEBUG_CONO, dptr, "%s %03o CONO %06o PC=%06o %06o\n",
|
||||||
|
dptr->name, dev, (uint32)*data, PC, rhc->status);
|
||||||
|
return SCPE_OK;
|
||||||
|
|
||||||
|
case DATAI:
|
||||||
|
*data = 0;
|
||||||
|
if (rhc->status & BUSY && rhc->reg != 04) {
|
||||||
|
rhc->status |= CC_CHAN_ACT;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
if (rhc->reg == 040) {
|
||||||
|
*data = (uint64)(rhc->dev_read(dptr, rhc, 0) & 077);
|
||||||
|
*data |= ((uint64)(rhc->cia)) << 6;
|
||||||
|
*data |= ((uint64)(rhc->xfer_drive)) << 18;
|
||||||
|
} else if (rhc->reg == 044) {
|
||||||
|
*data = (uint64)rhc->ivect;
|
||||||
|
if (rhc->imode)
|
||||||
|
*data |= IRQ_KI10;
|
||||||
|
else
|
||||||
|
*data |= IRQ_KA10;
|
||||||
|
} else if (rhc->reg == 054) {
|
||||||
|
*data = (uint64)(rhc->rae);
|
||||||
|
} else if ((rhc->reg & 040) == 0) {
|
||||||
|
int parity;
|
||||||
|
*data = (uint64)(rhc->dev_read(dptr, rhc, rhc->reg) & 0177777);
|
||||||
|
parity = (int)((*data >> 8) ^ *data);
|
||||||
|
parity = (parity >> 4) ^ parity;
|
||||||
|
parity = (parity >> 2) ^ parity;
|
||||||
|
parity = ((parity >> 1) ^ parity) & 1;
|
||||||
|
*data |= ((uint64)(parity ^ 1)) << 17;
|
||||||
|
*data |= ((uint64)(rhc->drive)) << 18;
|
||||||
|
}
|
||||||
|
*data |= ((uint64)(rhc->reg)) << 30;
|
||||||
|
sim_debug(DEBUG_DATAIO, dptr, "%s %03o DATI %012llo %d PC=%06o\n",
|
||||||
|
dptr->name, dev, *data, rhc->drive, PC);
|
||||||
|
return SCPE_OK;
|
||||||
|
|
||||||
|
case DATAO:
|
||||||
|
sim_debug(DEBUG_DATAIO, dptr, "%s %03o DATO %012llo PC=%06o %06o\n",
|
||||||
|
dptr->name, dev, *data, PC, rhc->status);
|
||||||
|
rhc->reg = ((int)(*data >> 30)) & 077;
|
||||||
|
rhc->imode &= ~2;
|
||||||
|
if (rhc->reg < 040 && rhc->reg != 04) {
|
||||||
|
rhc->drive = (int)(*data >> 18) & 07;
|
||||||
|
}
|
||||||
|
if (*data & LOAD_REG) {
|
||||||
|
if (rhc->reg == 040) {
|
||||||
|
if ((*data & 1) == 0) {
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rhc->status & BUSY) {
|
||||||
|
rhc->status |= CC_CHAN_ACT;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
rhc->status &= ~(CCW_COMP_1|PI_ENABLE);
|
||||||
|
if (((*data >> 1) & 037) < FNC_XFER) {
|
||||||
|
rhc->status |= CXR_ILC;
|
||||||
|
rh_setirq(rhc);
|
||||||
|
sim_debug(DEBUG_DATAIO, dptr,
|
||||||
|
"%s %03o command abort %012llo, %d PC=%06o %06o\n",
|
||||||
|
dptr->name, dev, *data, rhc->drive, PC, rhc->status);
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
/* Check if access error */
|
||||||
|
if (rhc->rae & (1 << rhc->drive))
|
||||||
|
return SCPE_OK;
|
||||||
|
/* Start command */
|
||||||
|
rh_setup(rhc, (uint32)(*data >> 6));
|
||||||
|
rhc->xfer_drive = (int)(*data >> 18) & 07;
|
||||||
|
rhc->dev_write(dptr, rhc, 0, (uint32)(*data & 077));
|
||||||
|
sim_debug(DEBUG_DATAIO, dptr,
|
||||||
|
"%s %03o command %012llo, %d PC=%06o %06o\n",
|
||||||
|
dptr->name, dev, *data, rhc->drive, PC, rhc->status);
|
||||||
|
} else if (rhc->reg == 044) {
|
||||||
|
/* Set KI10 Irq vector */
|
||||||
|
rhc->ivect = (int)(*data & IRQ_VECT);
|
||||||
|
rhc->imode = (*data & IRQ_KI10) != 0;
|
||||||
|
} else if (rhc->reg == 050) {
|
||||||
|
; /* Diagnostic access to mass bus. */
|
||||||
|
} else if (rhc->reg == 054) {
|
||||||
|
/* clear flags */
|
||||||
|
rhc->rae &= ~(*data & 0377);
|
||||||
|
if (rhc->rae == 0)
|
||||||
|
clr_interrupt(dev);
|
||||||
|
} else if ((rhc->reg & 040) == 0) {
|
||||||
|
rhc->drive = (int)(*data >> 18) & 07;
|
||||||
|
/* Check if access error */
|
||||||
|
if (rhc->rae & (1 << rhc->drive)) {
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
rhc->dev_write(dptr, rhc, rhc->reg & 037, (int)(*data & 0777777));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clr_interrupt(dev);
|
||||||
|
if (((rhc->status & (IADR_ATTN|BUSY)) == IADR_ATTN && rhc->attn != 0)
|
||||||
|
|| (rhc->status & PI_ENABLE))
|
||||||
|
set_interrupt(rhc->devnum, rhc->status);
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
return SCPE_OK; /* Unreached */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle KI and KL style interrupt vectors */
|
||||||
|
t_addr
|
||||||
|
rh_devirq(uint32 dev, t_addr addr) {
|
||||||
|
DEVICE *dptr = NULL;
|
||||||
|
struct rh_if *rhc = NULL;
|
||||||
|
int drive;
|
||||||
|
|
||||||
|
for (drive = 0; rh[drive].dev_num != 0; drive++) {
|
||||||
|
if (rh[drive].dev_num == (dev & 0774)) {
|
||||||
|
rhc = rh[drive].rh;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rhc != NULL) {
|
||||||
|
if (rhc->imode == 1) /* KI10 Style */
|
||||||
|
addr = RSIGN | rhc->ivect;
|
||||||
|
else if (rhc->imode == 2) /* RH20 style */
|
||||||
|
addr = rhc->ivect;
|
||||||
|
}
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the attention flag for a unit */
|
||||||
|
void rh_setattn(struct rh_if *rhc, int unit)
|
||||||
|
{
|
||||||
|
rhc->attn |= 1<<unit;
|
||||||
|
if ((rhc->status & BUSY) == 0 && (rhc->status & IADR_ATTN) != 0)
|
||||||
|
set_interrupt(rhc->devnum, rhc->status);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rh_error(struct rh_if *rhc)
|
||||||
|
{
|
||||||
|
if (rhc->imode == 2)
|
||||||
|
rhc->status |= RH20_DR_EXC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decrement block count for RH20, nop for RH10 */
|
||||||
|
int rh_blkend(struct rh_if *rhc)
|
||||||
|
{
|
||||||
|
#if KL
|
||||||
|
if (rhc->imode == 2) {
|
||||||
|
//fprintf(stderr, "RH blkend %o\n\r", rhc->cia);
|
||||||
|
rhc->cia = (rhc->cia + 1) & 01777;
|
||||||
|
if (rhc->cia == 0) {
|
||||||
|
rhc->status |= RH20_XEND;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set an IRQ for a DF10 device */
|
||||||
|
void rh_setirq(struct rh_if *rhc) {
|
||||||
|
rhc->status |= PI_ENABLE;
|
||||||
|
set_interrupt(rhc->devnum, rhc->status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generate the DF10 complete word */
|
||||||
|
void rh_writecw(struct rh_if *rhc, int nxm) {
|
||||||
|
uint64 wrd1;
|
||||||
|
#if KL
|
||||||
|
if (rhc->imode == 2) {
|
||||||
|
uint32 chan = (rhc->devnum - 0540);
|
||||||
|
int wc = ((rhc->wcr ^ RH20_WMASK) + 1) & RH20_WMASK;
|
||||||
|
rhc->status |= RH20_CHAN_RDY;
|
||||||
|
rhc->status &= ~(RH20_PCR_FULL);
|
||||||
|
if (wc != 0 || (rhc->status & RH20_XEND) == 0 ||
|
||||||
|
(rhc->ptcr & BIT10) != 0 || nxm) {
|
||||||
|
uint64 wrd2;
|
||||||
|
wrd1 = SMASK|(uint64)(rhc->ccw);
|
||||||
|
if ((rhc->ptcr & BIT10) == 0 || (rhc->status & RH20_DR_EXC) != 0)
|
||||||
|
return;
|
||||||
|
if (nxm) {
|
||||||
|
wrd1 |= RH20_NXM_ERR;
|
||||||
|
rhc->status |= RH20_CHAN_ERR;
|
||||||
|
}
|
||||||
|
if (wc != 0) {
|
||||||
|
wrd1 |= RH20_NOT_WC0;
|
||||||
|
if (rhc->status & RH20_XEND) {
|
||||||
|
wrd1 |= RH20_LONG_STS;
|
||||||
|
if ((rhc->ptcr & 070) == 060) { /* Write command */
|
||||||
|
rhc->status |= RH20_LONG_WC|RH20_CHAN_ERR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ((rhc->status & RH20_XEND) == 0) {
|
||||||
|
wrd1 |= RH20_SHRT_STS;
|
||||||
|
if ((rhc->ptcr & 070) == 060) { /* Write command */
|
||||||
|
rhc->status |= RH20_SHRT_WC|RH20_CHAN_ERR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* No error and not storing */
|
||||||
|
if ((rhc->status & RH20_CHAN_ERR) == 0 && (rhc->ptcr & BIT10) == 0)
|
||||||
|
return;
|
||||||
|
wrd1 |= RH20_NADR_PAR;
|
||||||
|
wrd2 = ((uint64)rhc->cop << 33) | (((uint64)wc) << CSHIFT) |
|
||||||
|
((uint64)(rhc->cda) & AMASK);
|
||||||
|
(void)Mem_write_word(chan+1, &wrd1, 1);
|
||||||
|
(void)Mem_write_word(chan+2, &wrd2, 1);
|
||||||
|
//fprintf(stderr, "RH20 final %012llo %012llo %06o\n\r", wrd1, wrd2, wc);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (nxm)
|
||||||
|
rhc->status |= CXR_NXM;
|
||||||
|
rhc->status |= CCW_COMP_1;
|
||||||
|
if (rhc->wcr != 0)
|
||||||
|
rhc->cda++;
|
||||||
|
wrd1 = ((uint64)(rhc->ccw & WMASK) << CSHIFT) | ((uint64)(rhc->cda) & AMASK);
|
||||||
|
(void)Mem_write_word(rhc->cia|1, &wrd1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finish off a DF10 transfer */
|
||||||
|
void rh_finish_op(struct rh_if *rhc, int nxm) {
|
||||||
|
#if KL
|
||||||
|
if (rhc->imode != 2)
|
||||||
|
#endif
|
||||||
|
rhc->status &= ~BUSY;
|
||||||
|
rh_writecw(rhc, nxm);
|
||||||
|
rh_setirq(rhc);
|
||||||
|
#if KL
|
||||||
|
if (rhc->imode == 2 &&
|
||||||
|
(rhc->status & (RH20_SCR_FULL|RH20_PCR_FULL)) == (RH20_SCR_FULL) &&
|
||||||
|
(rhc->status & (RH20_DR_EXC|RH20_CHAN_ERR)) == 0)
|
||||||
|
rh20_setup(rhc);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if KL
|
||||||
|
/* Set up for a RH20 transfer */
|
||||||
|
void rh20_setup(struct rh_if *rhc)
|
||||||
|
{
|
||||||
|
DEVICE *dptr = NULL;
|
||||||
|
int reg;
|
||||||
|
|
||||||
|
for (reg = 0; rh[reg].dev_num != 0; reg++) {
|
||||||
|
if (rh[reg].rh == rhc) {
|
||||||
|
dptr = rh[reg].dev;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dptr == 0)
|
||||||
|
return;
|
||||||
|
rhc->pbar = rhc->sbar;
|
||||||
|
rhc->ptcr = rhc->stcr;
|
||||||
|
/* Read drive status */
|
||||||
|
rhc->drive = (rhc->ptcr >> 18) & 07;
|
||||||
|
rhc->status &= ~(RH20_DATA_OVR|RH20_CHAN_RDY|RH20_DR_RESP|RH20_CHAN_ERR|RH20_SHRT_WC|\
|
||||||
|
RH20_LONG_WC|RH20_DR_EXC|RH20_SCR_FULL|PI_ENABLE|RH20_XEND);
|
||||||
|
rhc->status |= RH20_PCR_FULL;
|
||||||
|
if (rhc->status & RH20_SBAR) {
|
||||||
|
rhc->drive = (rhc->pbar >> 18) & 07;
|
||||||
|
if (rhc->dev_write != NULL)
|
||||||
|
rhc->dev_write(dptr, rhc, 5, (rhc->pbar & 0177777));
|
||||||
|
rhc->status &= ~RH20_SBAR;
|
||||||
|
}
|
||||||
|
if (rhc->ptcr & BIT7) { /* If RCPL reset I/O pointers */
|
||||||
|
rhc->ccw = eb_ptr + (rhc->devnum - 0540);
|
||||||
|
rhc->wcr = 0;
|
||||||
|
}
|
||||||
|
/* Hold block count in cia */
|
||||||
|
rhc->drive = (rhc->ptcr >> 18) & 07;
|
||||||
|
rhc->cia = (rhc->ptcr >> 6) & 01777;
|
||||||
|
if (rhc->dev_write != NULL)
|
||||||
|
rhc->dev_write(dptr, rhc, 0, (rhc->ptcr & 077));
|
||||||
|
rhc->cop = 0;
|
||||||
|
rhc->wcr = 0;
|
||||||
|
rhc->status &= ~RH20_CHAN_RDY;
|
||||||
|
//fprintf(stderr, "RH setup %06o %06o %o\n\r", rhc->ptcr, rhc->ccw, rhc->cia);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Setup for a DF10 transfer */
|
||||||
|
void rh_setup(struct rh_if *rhc, uint32 addr)
|
||||||
|
{
|
||||||
|
rhc->cia = addr & ICWA;
|
||||||
|
rhc->ccw = rhc->cia;
|
||||||
|
rhc->wcr = 0;
|
||||||
|
rhc->status |= BUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Fetch the next IO control word */
|
||||||
|
int rh_fetch(struct rh_if *rhc) {
|
||||||
|
uint64 data;
|
||||||
|
int reg;
|
||||||
|
DEVICE *dptr = NULL;
|
||||||
|
|
||||||
|
for (reg = 0; rh[reg].dev_num != 0; reg++) {
|
||||||
|
if (rh[reg].rh == rhc) {
|
||||||
|
dptr = rh[reg].dev;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if KL
|
||||||
|
if (rhc->imode == 2 && (rhc->cop & 2) != 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (Mem_read_word(rhc->ccw, &data, 0)) {
|
||||||
|
rh_finish_op(rhc, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
sim_debug(DEBUG_EXP, dptr, "%s fetch %06o %012llo\n\r", dptr->name, rhc->ccw, data);
|
||||||
|
#if KL
|
||||||
|
if (rhc->imode == 2) {
|
||||||
|
while((data & RH20_XFER) == 0) {
|
||||||
|
rhc->ccw = (uint32)(data & AMASK);
|
||||||
|
if ((data & (BIT1|BIT2)) == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (Mem_read_word(rhc->ccw, &data, 0)) {
|
||||||
|
rh_finish_op(rhc, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
sim_debug(DEBUG_EXP, dptr, "%s fetch2 %06o %012llo\n\r", dptr->name, rhc->ccw, data);
|
||||||
|
//fprintf(stderr, "RH20 fetch2 %06o %012llo\n\r", rhc->ccw, data);
|
||||||
|
}
|
||||||
|
rhc->wcr = (((data >> CSHIFT) & RH20_WMASK) ^ WMASK) + 1;
|
||||||
|
rhc->cda = (data & AMASK);
|
||||||
|
rhc->cop = (data >> 33) & 07;
|
||||||
|
rhc->ccw = (uint32)((rhc->ccw + 1) & AMASK);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
while((data & (WMASK << CSHIFT)) == 0) {
|
||||||
|
if ((data & AMASK) == 0 || (uint32)(data & AMASK) == rhc->ccw) {
|
||||||
|
rh_finish_op(rhc, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
rhc->ccw = (uint32)(data & AMASK);
|
||||||
|
if (Mem_read_word(rhc->ccw, &data, 0)) {
|
||||||
|
rh_finish_op(rhc, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
sim_debug(DEBUG_EXP, dptr, "%s fetch2 %06o %012llo\n\r", dptr->name, rhc->ccw, data);
|
||||||
|
}
|
||||||
|
rhc->wcr = (uint32)((data >> CSHIFT) & WMASK);
|
||||||
|
rhc->cda = (uint32)(data & AMASK);
|
||||||
|
rhc->ccw = (uint32)((rhc->ccw + 1) & AMASK);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read next word */
|
||||||
|
int rh_read(struct rh_if *rhc) {
|
||||||
|
uint64 data;
|
||||||
|
if (rhc->wcr == 0) {
|
||||||
|
if (!rh_fetch(rhc))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
rhc->wcr = (uint32)((rhc->wcr + 1) & WMASK);
|
||||||
|
if (rhc->cda != 0) {
|
||||||
|
if (rhc->cda > MEMSIZE) {
|
||||||
|
rh_finish_op(rhc, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#if KL
|
||||||
|
if (rhc->imode == 2) {
|
||||||
|
if (Mem_read_word(rhc->cda, &data, 0)) {
|
||||||
|
rh_finish_op(rhc, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (rhc->cop & 01)
|
||||||
|
rhc->cda = (uint32)((rhc->cda - 1) & AMASK);
|
||||||
|
else
|
||||||
|
rhc->cda = (uint32)((rhc->cda + 1) & AMASK);
|
||||||
|
} else {
|
||||||
|
rhc->cda = (uint32)((rhc->cda + 1) & AMASK);
|
||||||
|
if (Mem_read_word(rhc->cda, &data, 0)) {
|
||||||
|
rh_finish_op(rhc, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
rhc->cda = (uint32)((rhc->cda + 1) & AMASK);
|
||||||
|
if (Mem_read_word(rhc->cda, &data, 0)) {
|
||||||
|
rh_finish_op(rhc, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
data = 0;
|
||||||
|
}
|
||||||
|
rhc->buf = data;
|
||||||
|
if (rhc->wcr == 0) {
|
||||||
|
return rh_fetch(rhc);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write next word */
|
||||||
|
int rh_write(struct rh_if *rhc) {
|
||||||
|
if (rhc->wcr == 0) {
|
||||||
|
if (!rh_fetch(rhc))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
rhc->wcr = (uint32)((rhc->wcr + 1) & WMASK);
|
||||||
|
if (rhc->cda != 0) {
|
||||||
|
if (rhc->cda > MEMSIZE) {
|
||||||
|
rh_finish_op(rhc, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#if KL
|
||||||
|
if (rhc->imode == 2) {
|
||||||
|
if (Mem_write_word(rhc->cda, &rhc->buf, 0)) {
|
||||||
|
rh_finish_op(rhc, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (rhc->cop & 01)
|
||||||
|
rhc->cda = (uint32)((rhc->cda - 1) & AMASK);
|
||||||
|
else
|
||||||
|
rhc->cda = (uint32)((rhc->cda + 1) & AMASK);
|
||||||
|
} else {
|
||||||
|
rhc->cda = (uint32)((rhc->cda + 1) & AMASK);
|
||||||
|
if (Mem_write_word(rhc->cda, &rhc->buf, 0)) {
|
||||||
|
rh_finish_op(rhc, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
rhc->cda = (uint32)((rhc->cda + 1) & AMASK);
|
||||||
|
if (Mem_write_word(rhc->cda, &rhc->buf, 0)) {
|
||||||
|
rh_finish_op(rhc, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (rhc->wcr == 0) {
|
||||||
|
return rh_fetch(rhc);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
752
PDP10/kx10_rp.c
752
PDP10/kx10_rp.c
File diff suppressed because it is too large
Load diff
520
PDP10/kx10_rs.c
520
PDP10/kx10_rs.c
|
@ -1,6 +1,6 @@
|
||||||
/* ka10_rs.c: Dec RH10 RS04
|
/* kx10_rs.c: DEC Massbus RS04
|
||||||
|
|
||||||
Copyright (c) 2017, Richard Cornwell
|
Copyright (c) 2017-2020, Richard Cornwell
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -28,6 +28,8 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (NUM_DEVS_RS > 0)
|
#if (NUM_DEVS_RS > 0)
|
||||||
|
#define BUF_EMPTY(u) (u->hwmark == 0xFFFFFFFF)
|
||||||
|
#define CLR_BUF(u) u->hwmark = 0xFFFFFFFF
|
||||||
|
|
||||||
#define RS_NUMWD 128 /* 36bit words/sec */
|
#define RS_NUMWD 128 /* 36bit words/sec */
|
||||||
#define NUM_UNITS_RS 8
|
#define NUM_UNITS_RS 8
|
||||||
|
@ -42,72 +44,14 @@
|
||||||
#define DTYPE(x) (((x) & UNIT_M_DTYPE) << UNIT_V_DTYPE)
|
#define DTYPE(x) (((x) & UNIT_M_DTYPE) << UNIT_V_DTYPE)
|
||||||
#define GET_DTYPE(x) (((x) >> UNIT_V_DTYPE) & UNIT_M_DTYPE)
|
#define GET_DTYPE(x) (((x) >> UNIT_V_DTYPE) & UNIT_M_DTYPE)
|
||||||
#define UNIT_WPRT (UNIT_WLK | UNIT_RO) /* write protect */
|
#define UNIT_WPRT (UNIT_WLK | UNIT_RO) /* write protect */
|
||||||
#define CNTRL_V_CTYPE (UNIT_V_UF + 4)
|
|
||||||
#define CNTRL_M_CTYPE 7
|
|
||||||
#define GET_CNTRL(x) (((x) >> CNTRL_V_CTYPE) & CNTRL_M_CTYPE)
|
|
||||||
#define CNTRL(x) (((x) & CNTRL_M_CTYPE) << CNTRL_V_CTYPE)
|
|
||||||
|
|
||||||
/* Parameters in the unit descriptor */
|
/* Parameters in the unit descriptor */
|
||||||
|
|
||||||
|
|
||||||
/* CONI Flags */
|
|
||||||
#define IADR_ATTN 0000000000040LL /* Interrupt on attention */
|
|
||||||
#define IARD_RAE 0000000000100LL /* Interrupt on register access error */
|
|
||||||
#define DIB_CBOV 0000000000200LL /* Control bus overrun */
|
|
||||||
#define CXR_PS_FAIL 0000000002000LL /* Power supply fail (not implemented) */
|
|
||||||
#define CXR_ILC 0000000004000LL /* Illegal function code */
|
|
||||||
#define CR_DRE 0000000010000LL /* Or Data and Control Timeout */
|
|
||||||
#define DTC_OVER 0000000020000LL /* DF10 did not supply word on time (not implemented) */
|
|
||||||
#define CCW_COMP_1 0000000040000LL /* Control word written. */
|
|
||||||
#define CXR_CHAN_ER 0000000100000LL /* Channel Error */
|
|
||||||
#define CXR_EXC 0000000200000LL /* Error in drive transfer */
|
|
||||||
#define CXR_DBPE 0000000400000LL /* Device Parity error (not implemented) */
|
|
||||||
#define CXR_NXM 0000001000000LL /* Channel non-existent memory (not implemented) */
|
|
||||||
#define CXR_CWPE 0000002000000LL /* Channel Control word parity error (not implemented) */
|
|
||||||
#define CXR_CDPE 0000004000000LL /* Channel Data Parity Error (not implemented) */
|
|
||||||
#define CXR_SD_RAE 0000200000000LL /* Register access error */
|
|
||||||
#define CXR_ILFC 0000400000000LL /* Illegal CXR function code */
|
|
||||||
#define B22_FLAG 0004000000000LL /* 22 bit channel */
|
|
||||||
#define CC_CHAN_PLS 0010000000000LL /* Channel transfer pulse (not implemented) */
|
|
||||||
#define CC_CHAN_ACT 0020000000000LL /* Channel in use */
|
|
||||||
#define CC_INH 0040000000000LL /* Disconnect channel */
|
|
||||||
#define CB_FULL 0200000000000LL /* Set when channel buffer is full (not implemented) */
|
|
||||||
#define AR_FULL 0400000000000LL /* Set when AR is full (not implemented) */
|
|
||||||
|
|
||||||
/* CONO Flags */
|
|
||||||
#define ATTN_EN 0000000000040LL /* enable attention interrupt. */
|
|
||||||
#define REA_EN 0000000000100LL /* enable register error interrupt */
|
|
||||||
#define CBOV_CLR 0000000000200LL /* Clear CBOV */
|
|
||||||
#define CONT_RESET 0000000002000LL /* Clear All error bits */
|
|
||||||
#define ILC_CLR 0000000004000LL /* Clear ILC and SD RAE */
|
|
||||||
#define DRE_CLR 0000000010000LL /* Clear CR_CBTO and CR_DBTO */
|
|
||||||
#define OVER_CLR 0000000020000LL /* Clear DTC overrun */
|
|
||||||
#define WRT_CW 0000000040000LL /* Write control word */
|
|
||||||
#define CHN_CLR 0000000100000LL /* Clear Channel Error */
|
|
||||||
#define DR_EXC_CLR 0000000200000LL /* Clear DR_EXC */
|
|
||||||
#define DBPE_CLR 0000000400000LL /* Clear CXR_DBPE */
|
|
||||||
|
|
||||||
/* DATAO/DATAI */
|
|
||||||
#define CR_REG 0770000000000LL /* Register number */
|
|
||||||
#define LOAD_REG 0004000000000LL /* Load register */
|
|
||||||
#define CR_MAINT_MODE 0000100000000LL /* Maint mode... not implemented */
|
|
||||||
#define CR_DRIVE 0000007000000LL
|
|
||||||
#define CR_GEN_EVD 0000000400000LL /* Enable Parity */
|
|
||||||
#define CR_DXES 0000000200000LL /* Disable DXES errors */
|
|
||||||
#define CR_INAD 0000000077600LL
|
|
||||||
#define CR_WTEVM 0000000000100LL /* Verify Parity */
|
|
||||||
#define CR_FUNC 0000000000076LL
|
|
||||||
#define CR_GO 0000000000001LL
|
|
||||||
|
|
||||||
#define IRQ_VECT 0000000000177LL /* Interupt vector */
|
|
||||||
#define IRQ_KI10 0000002000000LL
|
|
||||||
#define IRQ_KA10 0000001000000LL
|
|
||||||
|
|
||||||
#define CMD u3
|
#define CMD u3
|
||||||
/* u3 low */
|
/* u3 low */
|
||||||
/* RSC - 00 - control */
|
/* RSC - 00 - control */
|
||||||
|
|
||||||
#define CS1_GO CR_GO /* go */
|
#define CS1_GO 1 /* go */
|
||||||
#define CS1_V_FNC 1 /* function pos */
|
#define CS1_V_FNC 1 /* function pos */
|
||||||
#define CS1_M_FNC 037 /* function mask */
|
#define CS1_M_FNC 037 /* function mask */
|
||||||
#define CS1_FNC (CS1_M_FNC << CS1_V_FNC)
|
#define CS1_FNC (CS1_M_FNC << CS1_V_FNC)
|
||||||
|
@ -228,21 +172,10 @@ struct drvtyp rs_drv_tab[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct df10 rs_df10[NUM_DEVS_RS];
|
|
||||||
uint32 rs_xfer_drive[NUM_DEVS_RS];
|
|
||||||
uint64 rs_buf[NUM_DEVS_RS][RS_NUMWD];
|
uint64 rs_buf[NUM_DEVS_RS][RS_NUMWD];
|
||||||
int rs_reg[NUM_DEVS_RS];
|
void rs_write(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 data);
|
||||||
int rs_ivect[NUM_DEVS_RS];
|
uint32 rs_read(DEVICE *dptr, struct rh_if *rhc, int reg);
|
||||||
int rs_imode[NUM_DEVS_RS];
|
void rs_rst(DEVICE *dptr);
|
||||||
int rs_drive[NUM_DEVS_RS];
|
|
||||||
int rs_rae[NUM_DEVS_RS];
|
|
||||||
int rs_attn[NUM_DEVS_RS];
|
|
||||||
extern int readin_flag;
|
|
||||||
|
|
||||||
t_stat rs_devio(uint32 dev, uint64 *data);
|
|
||||||
int rs_devirq(uint32 dev, int addr);
|
|
||||||
void rs_write(int ctlr, int unit, int reg, uint32 data);
|
|
||||||
uint32 rs_read(int ctlr, int unit, int reg);
|
|
||||||
t_stat rs_svc(UNIT *);
|
t_stat rs_svc(UNIT *);
|
||||||
t_stat rs_boot(int32, DEVICE *);
|
t_stat rs_boot(int32, DEVICE *);
|
||||||
void rs_ini(UNIT *, t_bool);
|
void rs_ini(UNIT *, t_bool);
|
||||||
|
@ -258,28 +191,38 @@ const char *rs_description (DEVICE *dptr);
|
||||||
UNIT rs_unit[] = {
|
UNIT rs_unit[] = {
|
||||||
/* Controller 1 */
|
/* Controller 1 */
|
||||||
{ UDATA (&rs_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
{ UDATA (&rs_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||||
UNIT_ROABLE+DTYPE(RS04_DTYPE)+CNTRL(0), RS04_SIZE) },
|
UNIT_ROABLE+DTYPE(RS04_DTYPE)+CNTRL_RH(0), RS04_SIZE) },
|
||||||
{ UDATA (&rs_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
{ UDATA (&rs_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||||
UNIT_ROABLE+DTYPE(RS04_DTYPE)+CNTRL(0), RS04_SIZE) },
|
UNIT_ROABLE+DTYPE(RS04_DTYPE)+CNTRL_RH(0), RS04_SIZE) },
|
||||||
{ UDATA (&rs_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
{ UDATA (&rs_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||||
UNIT_ROABLE+DTYPE(RS04_DTYPE)+CNTRL(0), RS04_SIZE) },
|
UNIT_ROABLE+DTYPE(RS04_DTYPE)+CNTRL_RH(0), RS04_SIZE) },
|
||||||
{ UDATA (&rs_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
{ UDATA (&rs_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||||
UNIT_ROABLE+DTYPE(RS04_DTYPE)+CNTRL(0), RS04_SIZE) },
|
UNIT_ROABLE+DTYPE(RS04_DTYPE)+CNTRL_RH(0), RS04_SIZE) },
|
||||||
{ UDATA (&rs_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
{ UDATA (&rs_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||||
UNIT_ROABLE+DTYPE(RS04_DTYPE)+CNTRL(0), RS04_SIZE) },
|
UNIT_ROABLE+DTYPE(RS04_DTYPE)+CNTRL_RH(0), RS04_SIZE) },
|
||||||
{ UDATA (&rs_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
{ UDATA (&rs_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||||
UNIT_ROABLE+DTYPE(RS04_DTYPE)+CNTRL(0), RS04_SIZE) },
|
UNIT_ROABLE+DTYPE(RS04_DTYPE)+CNTRL_RH(0), RS04_SIZE) },
|
||||||
{ UDATA (&rs_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
{ UDATA (&rs_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||||
UNIT_ROABLE+DTYPE(RS04_DTYPE)+CNTRL(0), RS04_SIZE) },
|
UNIT_ROABLE+DTYPE(RS04_DTYPE)+CNTRL_RH(0), RS04_SIZE) },
|
||||||
{ UDATA (&rs_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
{ UDATA (&rs_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||||
UNIT_ROABLE+DTYPE(RS04_DTYPE)+CNTRL(0), RS04_SIZE) },
|
UNIT_ROABLE+DTYPE(RS04_DTYPE)+CNTRL_RH(0), RS04_SIZE) },
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rh_if rs_rh[] = {
|
||||||
|
{ &rs_write, &rs_read, &rs_rst},
|
||||||
};
|
};
|
||||||
|
|
||||||
DIB rs_dib[] = {
|
DIB rs_dib[] = {
|
||||||
{RH10_DEV, 1, &rs_devio, &rs_devirq}
|
{RH10_DEV, 1, &rh_devio, &rh_devirq, &rs_rh[0]}
|
||||||
};
|
};
|
||||||
|
|
||||||
MTAB rs_mod[] = {
|
MTAB rs_mod[] = {
|
||||||
|
#if KL
|
||||||
|
{MTAB_XTD|MTAB_VDV, TYPE_RH10, NULL, "RH10", &rh_set_type, NULL,
|
||||||
|
NULL, "Sets controller to RH10" },
|
||||||
|
{MTAB_XTD|MTAB_VDV, TYPE_RH20, "RH20", "RH20", &rh_set_type, &rh_show_type,
|
||||||
|
NULL, "Sets controller to RH20"},
|
||||||
|
#endif
|
||||||
{UNIT_WLK, 0, "write enabled", "WRITEENABLED", NULL},
|
{UNIT_WLK, 0, "write enabled", "WRITEENABLED", NULL},
|
||||||
{UNIT_WLK, UNIT_WLK, "write locked", "LOCKED", NULL},
|
{UNIT_WLK, UNIT_WLK, "write locked", "LOCKED", NULL},
|
||||||
{UNIT_DTYPE, (RS03_DTYPE << UNIT_V_DTYPE), "RS03", "RS03", &rs_set_type },
|
{UNIT_DTYPE, (RS03_DTYPE << UNIT_V_DTYPE), "RS03", "RS03", &rs_set_type },
|
||||||
|
@ -288,23 +231,20 @@ MTAB rs_mod[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
REG rsa_reg[] = {
|
REG rsa_reg[] = {
|
||||||
{ORDATA(IVECT, rs_ivect[0], 18)},
|
{ORDATA(IVECT, rs_rh[0].ivect, 18)},
|
||||||
{FLDATA(IMODE, rs_imode[0], 0)},
|
{FLDATA(IMODE, rs_rh[0].imode, 0)},
|
||||||
{ORDATA(XFER, rs_xfer_drive[0], 3), REG_HRO},
|
{ORDATA(XFER, rs_rh[0].xfer_drive, 3), REG_HRO},
|
||||||
{ORDATA(DRIVE, rs_drive[0], 3), REG_HRO},
|
{ORDATA(DRIVE, rs_rh[0].drive, 3), REG_HRO},
|
||||||
{ORDATA(REG, rs_reg[0], 6), REG_RO},
|
{ORDATA(REG, rs_rh[0].reg, 6), REG_RO},
|
||||||
{ORDATA(RAE, rs_rae[0], 8), REG_RO},
|
{ORDATA(RAE, rs_rh[0].rae, 8), REG_RO},
|
||||||
{ORDATA(ATTN, rs_attn[0], 8), REG_RO},
|
{ORDATA(ATTN, rs_rh[0].attn, 8), REG_RO},
|
||||||
{FLDATA(READIN, readin_flag, 0), REG_HRO},
|
{ORDATA(STATUS, rs_rh[0].status, 18), REG_RO},
|
||||||
{ORDATA(STATUS, rs_df10[0].status, 18), REG_RO},
|
{ORDATA(CIA, rs_rh[0].cia, 18)},
|
||||||
{ORDATA(CIA, rs_df10[0].cia, 18)},
|
{ORDATA(CCW, rs_rh[0].ccw, 18)},
|
||||||
{ORDATA(CCW, rs_df10[0].ccw, 18)},
|
{ORDATA(WCR, rs_rh[0].wcr, 18)},
|
||||||
{ORDATA(WCR, rs_df10[0].wcr, 18)},
|
{ORDATA(CDA, rs_rh[0].cda, 18)},
|
||||||
{ORDATA(CDA, rs_df10[0].cda, 18)},
|
{ORDATA(DEVNUM, rs_rh[0].devnum, 9), REG_HRO},
|
||||||
{ORDATA(DEVNUM, rs_df10[0].devnum, 9), REG_HRO},
|
{ORDATA(BUF, rs_rh[0].buf, 36), REG_HRO},
|
||||||
{ORDATA(BUF, rs_df10[0].buf, 36), REG_HRO},
|
|
||||||
{ORDATA(NXM, rs_df10[0].nxmerr, 8), REG_HRO},
|
|
||||||
{ORDATA(COMP, rs_df10[0].ccw_comp, 8), REG_HRO},
|
|
||||||
{BRDATA(BUFF, rs_buf[0], 16, 64, RS_NUMWD), REG_HRO},
|
{BRDATA(BUFF, rs_buf[0], 16, 64, RS_NUMWD), REG_HRO},
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
|
@ -322,213 +262,44 @@ DEVICE *rs_devs[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
t_stat rs_devio(uint32 dev, uint64 *data) {
|
void
|
||||||
int ctlr = -1;
|
rs_rst(DEVICE *dptr)
|
||||||
DEVICE *dptr = NULL;
|
{
|
||||||
struct df10 *df10;
|
|
||||||
int drive;
|
|
||||||
|
|
||||||
for (drive = 0; rh[drive].dev_num != 0; drive++) {
|
|
||||||
if (rh[drive].dev_num == (dev & 0774)) {
|
|
||||||
dptr = rh[drive].dev;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (dptr == NULL)
|
|
||||||
return SCPE_OK;
|
|
||||||
ctlr = GET_CNTRL(dptr->units[0].flags);
|
|
||||||
df10 = &rs_df10[ctlr];
|
|
||||||
df10->devnum = dev;
|
|
||||||
switch(dev & 3) {
|
|
||||||
case CONI:
|
|
||||||
*data = df10->status & ~(IADR_ATTN|IARD_RAE);
|
|
||||||
if (rs_attn[ctlr] != 0 && (df10->status & IADR_ATTN))
|
|
||||||
*data |= IADR_ATTN;
|
|
||||||
if (rs_rae[ctlr] != 0 && (df10->status & IARD_RAE))
|
|
||||||
*data |= IARD_RAE;
|
|
||||||
#if KI_22BIT
|
|
||||||
*data |= B22_FLAG;
|
|
||||||
#endif
|
|
||||||
sim_debug(DEBUG_CONI, dptr, "RS %03o CONI %06o PC=%o %o\n",
|
|
||||||
dev, (uint32)*data, PC, rs_attn[ctlr]);
|
|
||||||
return SCPE_OK;
|
|
||||||
|
|
||||||
case CONO:
|
|
||||||
clr_interrupt(dev);
|
|
||||||
df10->status &= ~(07LL|IADR_ATTN|IARD_RAE);
|
|
||||||
df10->status |= *data & (07LL|IADR_ATTN|IARD_RAE);
|
|
||||||
/* Clear flags */
|
|
||||||
if (*data & CONT_RESET) {
|
|
||||||
UNIT *uptr=dptr->units;
|
UNIT *uptr=dptr->units;
|
||||||
|
int drive;
|
||||||
for(drive = 0; drive < NUM_UNITS_RS; drive++, uptr++) {
|
for(drive = 0; drive < NUM_UNITS_RS; drive++, uptr++) {
|
||||||
uptr->CMD &= DS_MOL|DS_WRL|DS_DPR|DS_DRY|DS_VV|076;
|
uptr->CMD &= DS_MOL|DS_WRL|DS_DPR|DS_DRY|DS_VV|076;
|
||||||
uptr->DA &= 003400177777;
|
uptr->DA &= 003400177777;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (*data & (DBPE_CLR|DR_EXC_CLR|CHN_CLR))
|
|
||||||
df10->status &= ~(*data & (DBPE_CLR|DR_EXC_CLR|CHN_CLR));
|
|
||||||
if (*data & OVER_CLR)
|
|
||||||
df10->status &= ~(DTC_OVER);
|
|
||||||
if (*data & CBOV_CLR)
|
|
||||||
df10->status &= ~(DIB_CBOV);
|
|
||||||
if (*data & CXR_ILC)
|
|
||||||
df10->status &= ~(CXR_ILFC|CXR_SD_RAE);
|
|
||||||
if (*data & WRT_CW)
|
|
||||||
df10_writecw(df10);
|
|
||||||
if (*data & PI_ENABLE)
|
|
||||||
df10->status &= ~PI_ENABLE;
|
|
||||||
if (df10->status & PI_ENABLE)
|
|
||||||
set_interrupt(dev, df10->status);
|
|
||||||
if ((df10->status & IADR_ATTN) != 0 && rs_attn[ctlr] != 0)
|
|
||||||
set_interrupt(dev, df10->status);
|
|
||||||
sim_debug(DEBUG_CONO, dptr, "RS %03o CONO %06o %d PC=%06o %06o\n",
|
|
||||||
dev, (uint32)*data, ctlr, PC, df10->status);
|
|
||||||
return SCPE_OK;
|
|
||||||
|
|
||||||
case DATAI:
|
|
||||||
*data = 0;
|
|
||||||
if (df10->status & BUSY && rs_reg[ctlr] != 04) {
|
|
||||||
df10->status |= CC_CHAN_ACT;
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
if (rs_reg[ctlr] == 040) {
|
|
||||||
*data = (uint64)(rs_read(ctlr, rs_drive[ctlr], 0) & 077);
|
|
||||||
*data |= ((uint64)(df10->cia)) << 6;
|
|
||||||
*data |= ((uint64)(rs_xfer_drive[ctlr])) << 18;
|
|
||||||
} else if (rs_reg[ctlr] == 044) {
|
|
||||||
*data = (uint64)rs_ivect[ctlr];
|
|
||||||
if (rs_imode[ctlr])
|
|
||||||
*data |= IRQ_KI10;
|
|
||||||
else
|
|
||||||
*data |= IRQ_KA10;
|
|
||||||
} else if (rs_reg[ctlr] == 054) {
|
|
||||||
*data = (uint64)(rs_rae[ctlr]);
|
|
||||||
} else if ((rs_reg[ctlr] & 040) == 0) {
|
|
||||||
int parity;
|
|
||||||
|
|
||||||
*data = (uint64)(rs_read(ctlr, rs_drive[ctlr], rs_reg[ctlr]) & 0177777);
|
|
||||||
parity = (int)((*data >> 8) ^ *data);
|
|
||||||
parity = (parity >> 4) ^ parity;
|
|
||||||
parity = (parity >> 2) ^ parity;
|
|
||||||
parity = ((parity >> 1) ^ parity) & 1;
|
|
||||||
*data |= ((uint64)(parity ^ 1)) << 17;
|
|
||||||
*data |= ((uint64)(rs_drive[ctlr])) << 18;
|
|
||||||
}
|
|
||||||
*data |= ((uint64)(rs_reg[ctlr])) << 30;
|
|
||||||
sim_debug(DEBUG_DATAIO, dptr, "RS %03o DATI %012llo, %d %d PC=%06o\n",
|
|
||||||
dev, *data, ctlr, rs_drive[ctlr], PC);
|
|
||||||
return SCPE_OK;
|
|
||||||
|
|
||||||
case DATAO:
|
|
||||||
sim_debug(DEBUG_DATAIO, dptr, "RS %03o DATO %012llo, %d PC=%06o %06o\n",
|
|
||||||
dev, *data, ctlr, PC, df10->status);
|
|
||||||
rs_reg[ctlr] = ((int)(*data >> 30)) & 077;
|
|
||||||
if (rs_reg[ctlr] < 040 && rs_reg[ctlr] != 04) {
|
|
||||||
rs_drive[ctlr] = (int)(*data >> 18) & 07;
|
|
||||||
}
|
|
||||||
if (*data & LOAD_REG) {
|
|
||||||
if (rs_reg[ctlr] == 040) {
|
|
||||||
if ((*data & 1) == 0) {
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (df10->status & BUSY) {
|
|
||||||
df10->status |= CC_CHAN_ACT;
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
df10->status &= ~(1 << df10->ccw_comp);
|
|
||||||
df10->status &= ~PI_ENABLE;
|
|
||||||
if (((*data >> 1) & 077) < FNC_XFER) {
|
|
||||||
df10->status |= CXR_ILC;
|
|
||||||
df10_setirq(df10);
|
|
||||||
sim_debug(DEBUG_DATAIO, dptr,
|
|
||||||
"RS %03o command abort %012llo, %d[%d] PC=%06o %06o\n",
|
|
||||||
dev, *data, ctlr, rs_drive[ctlr], PC, df10->status);
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Start command */
|
|
||||||
df10_setup(df10, (uint32)(*data >> 6));
|
|
||||||
rs_xfer_drive[ctlr] = (int)(*data >> 18) & 07;
|
|
||||||
rs_write(ctlr, rs_drive[ctlr], 0, (uint32)(*data & 077));
|
|
||||||
sim_debug(DEBUG_DATAIO, dptr,
|
|
||||||
"RS %03o command %012llo, %d[%d] PC=%06o %06o\n",
|
|
||||||
dev, *data, ctlr, rs_drive[ctlr], PC, df10->status);
|
|
||||||
} else if (rs_reg[ctlr] == 044) {
|
|
||||||
/* Set KI10 Irq vector */
|
|
||||||
rs_ivect[ctlr] = (int)(*data & IRQ_VECT);
|
|
||||||
rs_imode[ctlr] = (*data & IRQ_KI10) != 0;
|
|
||||||
} else if (rs_reg[ctlr] == 050) {
|
|
||||||
; /* Diagnostic access to mass bus. */
|
|
||||||
} else if (rs_reg[ctlr] == 054) {
|
|
||||||
/* clear flags */
|
|
||||||
rs_rae[ctlr] &= ~(*data & 0377);
|
|
||||||
if (rs_rae[ctlr] == 0)
|
|
||||||
clr_interrupt(dev);
|
|
||||||
} else if ((rs_reg[ctlr] & 040) == 0) {
|
|
||||||
rs_drive[ctlr] = (int)(*data >> 18) & 07;
|
|
||||||
/* Check if access error */
|
|
||||||
if (rs_rae[ctlr] & (1 << rs_drive[ctlr])) {
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
rs_drive[ctlr] = (int)(*data >> 18) & 07;
|
|
||||||
rs_write(ctlr, rs_drive[ctlr], rs_reg[ctlr] & 037,
|
|
||||||
(int)(*data & 0777777));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
return SCPE_OK; /* Unreached */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Handle KI and KL style interrupt vectors */
|
|
||||||
int
|
|
||||||
rs_devirq(uint32 dev, int addr) {
|
|
||||||
DEVICE *dptr = NULL;
|
|
||||||
int drive;
|
|
||||||
|
|
||||||
for (drive = 0; rh[drive].dev_num != 0; drive++) {
|
|
||||||
if (rh[drive].dev_num == (dev & 0774)) {
|
|
||||||
dptr = rh[drive].dev;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (dptr != NULL) {
|
|
||||||
drive = GET_CNTRL(dptr->units[0].flags);
|
|
||||||
return (rs_imode[drive] ? rs_ivect[drive] : addr);
|
|
||||||
}
|
|
||||||
return addr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rs_write(int ctlr, int unit, int reg, uint32 data) {
|
rs_write(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 data) {
|
||||||
int i;
|
int i;
|
||||||
DEVICE *dptr = rs_devs[ctlr];
|
int unit = rhc->drive;
|
||||||
struct df10 *df10 = &rs_df10[ctlr];
|
|
||||||
UNIT *uptr = &dptr->units[unit];
|
UNIT *uptr = &dptr->units[unit];
|
||||||
|
|
||||||
if ((uptr->CMD & CR_GO) && reg != 04) {
|
if ((uptr->CMD & CS1_GO) && reg != 04) {
|
||||||
uptr->CMD |= (ER1_RMR << 16)|DS_ERR;
|
uptr->CMD |= (ER1_RMR << 16)|DS_ERR;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch(reg) {
|
switch(reg) {
|
||||||
case 000: /* control */
|
case 000: /* control */
|
||||||
sim_debug(DEBUG_DETAIL, dptr, "RSA%o %d Status=%06o\n", unit, ctlr, uptr->CMD);
|
sim_debug(DEBUG_DETAIL, dptr, "%s%o Status=%06o\n", dptr->name, unit, uptr->CMD);
|
||||||
/* Set if drive not writable */
|
/* Set if drive not writable */
|
||||||
if (uptr->flags & UNIT_WLK)
|
if (uptr->flags & UNIT_WLK)
|
||||||
uptr->CMD |= DS_WRL;
|
uptr->CMD |= DS_WRL;
|
||||||
/* If drive not ready don't do anything */
|
/* If drive not ready don't do anything */
|
||||||
if ((uptr->CMD & DS_DRY) == 0) {
|
if ((uptr->CMD & DS_DRY) == 0) {
|
||||||
uptr->CMD |= (ER1_RMR << 16)|DS_ERR;
|
uptr->CMD |= (ER1_RMR << 16)|DS_ERR;
|
||||||
sim_debug(DEBUG_DETAIL, dptr, "RSA%o %d busy\n", unit, ctlr);
|
sim_debug(DEBUG_DETAIL, dptr, "%s%o busy\n", dptr->name, unit);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Check if GO bit set */
|
/* Check if GO bit set */
|
||||||
if ((data & 1) == 0) {
|
if ((data & 1) == 0) {
|
||||||
uptr->CMD &= ~076;
|
uptr->CMD &= ~076;
|
||||||
uptr->CMD |= data & 076;
|
uptr->CMD |= data & 076;
|
||||||
sim_debug(DEBUG_DETAIL, dptr, "RSA%o %d no go\n", unit, ctlr);
|
sim_debug(DEBUG_DETAIL, dptr, "%s%o no go\n", dptr->name, unit);
|
||||||
return; /* No, nop */
|
return; /* No, nop */
|
||||||
}
|
}
|
||||||
uptr->CMD &= DS_ATA|DS_VV|DS_DPR|DS_MOL|DS_WRL;
|
uptr->CMD &= DS_ATA|DS_VV|DS_DPR|DS_MOL|DS_WRL;
|
||||||
|
@ -542,7 +313,8 @@ rs_write(int ctlr, int unit, int reg, uint32 data) {
|
||||||
case FNC_WCHK: /* write check */
|
case FNC_WCHK: /* write check */
|
||||||
case FNC_WRITE: /* write */
|
case FNC_WRITE: /* write */
|
||||||
case FNC_READ: /* read */
|
case FNC_READ: /* read */
|
||||||
uptr->CMD |= DS_PIP|CR_GO;
|
uptr->CMD |= DS_PIP|CS1_GO;
|
||||||
|
CLR_BUF(uptr);
|
||||||
uptr->DATAPTR = 0;
|
uptr->DATAPTR = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -551,30 +323,26 @@ rs_write(int ctlr, int unit, int reg, uint32 data) {
|
||||||
if ((uptr->flags & UNIT_ATT) != 0)
|
if ((uptr->flags & UNIT_ATT) != 0)
|
||||||
uptr->CMD |= DS_VV;
|
uptr->CMD |= DS_VV;
|
||||||
uptr->CMD |= DS_DRY;
|
uptr->CMD |= DS_DRY;
|
||||||
df10_setirq(df10);
|
rh_setirq(rhc);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FNC_DCLR: /* drive clear */
|
case FNC_DCLR: /* drive clear */
|
||||||
uptr->CMD |= DS_DRY;
|
uptr->CMD |= DS_DRY;
|
||||||
uptr->CMD &= ~(DS_ATA|CR_GO);
|
uptr->CMD &= ~(DS_ATA|CS1_GO);
|
||||||
rs_attn[ctlr] = 0;
|
rhc->attn = 0;
|
||||||
clr_interrupt(df10->devnum);
|
clr_interrupt(rhc->devnum);
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
if (rs_unit[(ctlr * 8) + i].CMD & DS_ATA)
|
if (dptr->units[i].CMD & DS_ATA)
|
||||||
rs_attn[ctlr] = 1;
|
rhc->attn |= 1 << i;
|
||||||
}
|
}
|
||||||
if ((df10->status & IADR_ATTN) != 0 && rs_attn[ctlr] != 0)
|
|
||||||
df10_setirq(df10);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
uptr->CMD |= DS_DRY|DS_ERR|DS_ATA;
|
uptr->CMD |= DS_DRY|DS_ERR|DS_ATA;
|
||||||
uptr->CMD |= (ER1_ILF << 16);
|
uptr->CMD |= (ER1_ILF << 16);
|
||||||
if ((df10->status & IADR_ATTN) != 0 && rs_attn[ctlr] != 0)
|
|
||||||
df10_setirq(df10);
|
|
||||||
}
|
}
|
||||||
if (uptr->CMD & CR_GO)
|
if (uptr->CMD & CS1_GO)
|
||||||
sim_activate(uptr, 100);
|
sim_activate(uptr, 100);
|
||||||
sim_debug(DEBUG_DETAIL, dptr, "RSA%o AStatus=%06o\n", unit, uptr->CMD);
|
sim_debug(DEBUG_DETAIL, dptr, "%s%o AStatus=%06o\n", dptr->name, unit, uptr->CMD);
|
||||||
return;
|
return;
|
||||||
case 001: /* status */
|
case 001: /* status */
|
||||||
break;
|
break;
|
||||||
|
@ -587,17 +355,13 @@ rs_write(int ctlr, int unit, int reg, uint32 data) {
|
||||||
case 003: /* maintenance */
|
case 003: /* maintenance */
|
||||||
break;
|
break;
|
||||||
case 004: /* atten summary */
|
case 004: /* atten summary */
|
||||||
rs_attn[ctlr] = 0;
|
rhc->attn = 0;
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
if (data & (1<<i))
|
if (data & (1<<i))
|
||||||
rs_unit[(ctlr * 8) + i].CMD &= ~DS_ATA;
|
dptr->units[i].CMD &= ~DS_ATA;
|
||||||
if (rs_unit[(ctlr * 8) + i].CMD & DS_ATA)
|
if (dptr->units[i].CMD & DS_ATA)
|
||||||
rs_attn[ctlr] = 1;
|
rhc->attn |= 1 << i;
|
||||||
}
|
}
|
||||||
clr_interrupt(df10->devnum);
|
|
||||||
if (((df10->status & IADR_ATTN) != 0 && rs_attn[ctlr] != 0) ||
|
|
||||||
(df10->status & PI_ENABLE))
|
|
||||||
df10_setirq(df10);
|
|
||||||
break;
|
break;
|
||||||
case 005: /* sector/track */
|
case 005: /* sector/track */
|
||||||
uptr->DA = data & 0177777;
|
uptr->DA = data & 0177777;
|
||||||
|
@ -607,14 +371,13 @@ rs_write(int ctlr, int unit, int reg, uint32 data) {
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
uptr->CMD |= (ER1_ILR<<16)|DS_ERR;
|
uptr->CMD |= (ER1_ILR<<16)|DS_ERR;
|
||||||
rs_rae[ctlr] &= ~(1<<unit);
|
rhc->rae |= 1 << unit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32
|
uint32
|
||||||
rs_read(int ctlr, int unit, int reg) {
|
rs_read(DEVICE *dptr, struct rh_if *rhc, int reg) {
|
||||||
DEVICE *dptr = rs_devs[ctlr];
|
int unit = rhc->drive;
|
||||||
struct df10 *df10 = &rs_df10[ctlr];
|
|
||||||
UNIT *uptr = &dptr->units[unit];
|
UNIT *uptr = &dptr->units[unit];
|
||||||
uint32 temp = 0;
|
uint32 temp = 0;
|
||||||
int i;
|
int i;
|
||||||
|
@ -628,7 +391,7 @@ rs_read(int ctlr, int unit, int reg) {
|
||||||
temp = uptr->CMD & 077;
|
temp = uptr->CMD & 077;
|
||||||
if (uptr->flags & UNIT_ATT)
|
if (uptr->flags & UNIT_ATT)
|
||||||
temp |= CS1_DVA;
|
temp |= CS1_DVA;
|
||||||
if ((df10->status & BUSY) == 0 && (uptr->CMD & CR_GO) == 0)
|
if ((uptr->CMD & CS1_GO) == 0)
|
||||||
temp |= CS1_GO;
|
temp |= CS1_GO;
|
||||||
break;
|
break;
|
||||||
case 001: /* status */
|
case 001: /* status */
|
||||||
|
@ -639,7 +402,7 @@ rs_read(int ctlr, int unit, int reg) {
|
||||||
break;
|
break;
|
||||||
case 004: /* atten summary */
|
case 004: /* atten summary */
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
if (rs_unit[(ctlr * 8) + i].CMD & DS_ATA) {
|
if (dptr->units[i].CMD & DS_ATA) {
|
||||||
temp |= 1 << i;
|
temp |= 1 << i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -655,7 +418,7 @@ rs_read(int ctlr, int unit, int reg) {
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
uptr->CMD |= (ER1_ILR<<16);
|
uptr->CMD |= (ER1_ILR<<16);
|
||||||
rs_rae[ctlr] &= ~(1<<unit);
|
rhc->rae |= 1 << unit;
|
||||||
}
|
}
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
@ -664,21 +427,20 @@ rs_read(int ctlr, int unit, int reg) {
|
||||||
t_stat rs_svc (UNIT *uptr)
|
t_stat rs_svc (UNIT *uptr)
|
||||||
{
|
{
|
||||||
int dtype = GET_DTYPE(uptr->flags);
|
int dtype = GET_DTYPE(uptr->flags);
|
||||||
int ctlr = GET_CNTRL(uptr->flags);
|
int ctlr = GET_CNTRL_RH(uptr->flags);
|
||||||
int unit;
|
int unit;
|
||||||
DEVICE *dptr;
|
DEVICE *dptr;
|
||||||
struct df10 *df;
|
struct rh_if *rhc;
|
||||||
int da;
|
int da;
|
||||||
t_stat r;
|
int sts;
|
||||||
|
|
||||||
/* Find dptr, and df10 */
|
/* Find dptr, and df10 */
|
||||||
dptr = rs_devs[ctlr];
|
dptr = rs_devs[ctlr];
|
||||||
|
rhc = &rs_rh[ctlr];
|
||||||
unit = uptr - dptr->units;
|
unit = uptr - dptr->units;
|
||||||
df = &rs_df10[ctlr];
|
|
||||||
if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
|
if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
|
||||||
uptr->CMD |= (ER1_UNS << 16) | DS_ATA|DS_ERR; /* set drive error */
|
uptr->CMD |= (ER1_UNS << 16) | DS_ATA|DS_ERR; /* set drive error */
|
||||||
df->status &= ~BUSY;
|
rh_setirq(rhc);
|
||||||
df10_setirq(df);
|
|
||||||
return (SCPE_OK);
|
return (SCPE_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -693,42 +455,35 @@ t_stat rs_svc (UNIT *uptr)
|
||||||
case FNC_DCLR: /* drive clear */
|
case FNC_DCLR: /* drive clear */
|
||||||
break;
|
break;
|
||||||
case FNC_PRESET: /* read-in preset */
|
case FNC_PRESET: /* read-in preset */
|
||||||
rs_attn[ctlr] = 1;
|
|
||||||
uptr->CMD |= DS_DRY|DS_ATA;
|
uptr->CMD |= DS_DRY|DS_ATA;
|
||||||
uptr->CMD &= ~CR_GO;
|
uptr->CMD &= ~CS1_GO;
|
||||||
df->status &= ~BUSY;
|
rh_setattn(rhc, unit);
|
||||||
if (df->status & IADR_ATTN)
|
sim_debug(DEBUG_DETAIL, dptr, "%s%o seekdone\n", dptr->name, unit);
|
||||||
df10_setirq(df);
|
|
||||||
sim_debug(DEBUG_DETAIL, dptr, "RSA%o seekdone\n", unit);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FNC_SEARCH: /* search */
|
case FNC_SEARCH: /* search */
|
||||||
if (GET_SC(uptr->DA) >= rs_drv_tab[dtype].sect ||
|
if (GET_SC(uptr->DA) >= rs_drv_tab[dtype].sect ||
|
||||||
GET_SF(uptr->DA) >= rs_drv_tab[dtype].surf)
|
GET_SF(uptr->DA) >= rs_drv_tab[dtype].surf)
|
||||||
uptr->CMD |= (ER1_IAE << 16)|DS_ERR;
|
uptr->CMD |= (ER1_IAE << 16)|DS_ERR;
|
||||||
rs_attn[ctlr] = 1;
|
|
||||||
uptr->CMD |= DS_DRY|DS_ATA;
|
uptr->CMD |= DS_DRY|DS_ATA;
|
||||||
uptr->CMD &= ~CR_GO;
|
uptr->CMD &= ~CS1_GO;
|
||||||
df->status &= ~BUSY;
|
rh_setattn(rhc, unit);
|
||||||
if ((df->status & (IADR_ATTN|BUSY)) == IADR_ATTN)
|
sim_debug(DEBUG_DETAIL, dptr, "%s%o searchdone\n", dptr->name, unit);
|
||||||
df10_setirq(df);
|
|
||||||
sim_debug(DEBUG_DETAIL, dptr, "RSA%o searchdone\n", unit);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FNC_READ: /* read */
|
case FNC_READ: /* read */
|
||||||
case FNC_WCHK: /* write check */
|
case FNC_WCHK: /* write check */
|
||||||
if (uptr->DATAPTR == 0) {
|
if (BUF_EMPTY(uptr)) {
|
||||||
int wc;
|
int wc;
|
||||||
if (GET_SC(uptr->DA) >= rs_drv_tab[dtype].sect ||
|
if (GET_SC(uptr->DA) >= rs_drv_tab[dtype].sect ||
|
||||||
GET_SF(uptr->DA) >= rs_drv_tab[dtype].surf) {
|
GET_SF(uptr->DA) >= rs_drv_tab[dtype].surf) {
|
||||||
uptr->CMD |= (ER1_IAE << 16)|DS_ERR|DS_DRY|DS_ATA;
|
uptr->CMD |= (ER1_IAE << 16)|DS_ERR|DS_DRY|DS_ATA;
|
||||||
df->status &= ~BUSY;
|
uptr->CMD &= ~CS1_GO;
|
||||||
uptr->CMD &= ~CR_GO;
|
sim_debug(DEBUG_DETAIL, dptr, "%s%o readx done\n", dptr->name, unit);
|
||||||
sim_debug(DEBUG_DETAIL, dptr, "RSA%o readx done\n", unit);
|
rh_finish_op(rhc, 0);
|
||||||
df10_finish_op(df, 0);
|
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
sim_debug(DEBUG_DETAIL, dptr, "RSA%o read (%d,%d)\n", unit,
|
sim_debug(DEBUG_DETAIL, dptr, "%s%o read (%d,%d)\n", dptr->name, unit,
|
||||||
GET_SC(uptr->DA), GET_SF(uptr->DA));
|
GET_SC(uptr->DA), GET_SF(uptr->DA));
|
||||||
da = GET_DA(uptr->DA, dtype) * RS_NUMWD;
|
da = GET_DA(uptr->DA, dtype) * RS_NUMWD;
|
||||||
(void)sim_fseek(uptr->fileref, da * sizeof(uint64), SEEK_SET);
|
(void)sim_fseek(uptr->fileref, da * sizeof(uint64), SEEK_SET);
|
||||||
|
@ -737,15 +492,17 @@ t_stat rs_svc (UNIT *uptr)
|
||||||
while (wc < RS_NUMWD)
|
while (wc < RS_NUMWD)
|
||||||
rs_buf[ctlr][wc++] = 0;
|
rs_buf[ctlr][wc++] = 0;
|
||||||
uptr->hwmark = RS_NUMWD;
|
uptr->hwmark = RS_NUMWD;
|
||||||
|
uptr->DATAPTR = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
df->buf = rs_buf[ctlr][uptr->DATAPTR++];
|
rhc->buf = rs_buf[ctlr][uptr->DATAPTR++];
|
||||||
sim_debug(DEBUG_DATA, dptr, "RSA%o read word %d %012llo %09o %06o\n",
|
sim_debug(DEBUG_DATA, dptr, "%s%o read word %d %012llo %09o %06o\n",
|
||||||
unit, uptr->DATAPTR, df->buf, df->cda, df->wcr);
|
dptr->name, unit, uptr->DATAPTR, rhc->buf, rhc->cda, rhc->wcr);
|
||||||
if (df10_write(df)) {
|
if (rh_write(rhc)) {
|
||||||
if (uptr->DATAPTR == uptr->hwmark) {
|
if (uptr->DATAPTR == RS_NUMWD) {
|
||||||
/* Increment to next sector. Set Last Sector */
|
/* Increment to next sector. Set Last Sector */
|
||||||
uptr->DATAPTR = 0;
|
uptr->DATAPTR = 0;
|
||||||
|
CLR_BUF(uptr);
|
||||||
uptr->DA += 1 << DA_V_SC;
|
uptr->DA += 1 << DA_V_SC;
|
||||||
if (GET_SC(uptr->DA) >= rs_drv_tab[dtype].sect) {
|
if (GET_SC(uptr->DA) >= rs_drv_tab[dtype].sect) {
|
||||||
uptr->DA &= (DA_M_SF << DA_V_SF);
|
uptr->DA &= (DA_M_SF << DA_V_SF);
|
||||||
|
@ -753,43 +510,53 @@ t_stat rs_svc (UNIT *uptr)
|
||||||
if (GET_SF(uptr->DA) >= rs_drv_tab[dtype].surf)
|
if (GET_SF(uptr->DA) >= rs_drv_tab[dtype].surf)
|
||||||
uptr->CMD |= DS_LST;
|
uptr->CMD |= DS_LST;
|
||||||
}
|
}
|
||||||
|
if (rh_blkend(rhc))
|
||||||
|
goto rd_end;
|
||||||
}
|
}
|
||||||
sim_activate(uptr, 20);
|
sim_activate(uptr, 10);
|
||||||
} else {
|
} else {
|
||||||
sim_debug(DEBUG_DETAIL, dptr, "RSA%o read done\n", unit);
|
rd_end:
|
||||||
|
sim_debug(DEBUG_DETAIL, dptr, "%s%o read done\n", dptr->name, unit);
|
||||||
uptr->CMD |= DS_DRY;
|
uptr->CMD |= DS_DRY;
|
||||||
uptr->CMD &= ~CR_GO;
|
uptr->CMD &= ~CS1_GO;
|
||||||
df10_finish_op(df, 0);
|
if (uptr->DATAPTR == RS_NUMWD)
|
||||||
|
(void)rh_blkend(rhc);
|
||||||
|
rh_finish_op(rhc, 0);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FNC_WRITE: /* write */
|
case FNC_WRITE: /* write */
|
||||||
if (uptr->DATAPTR == 0) {
|
if (BUF_EMPTY(uptr)) {
|
||||||
if (GET_SC(uptr->DA) >= rs_drv_tab[dtype].sect ||
|
if (GET_SC(uptr->DA) >= rs_drv_tab[dtype].sect ||
|
||||||
GET_SF(uptr->DA) >= rs_drv_tab[dtype].surf) {
|
GET_SF(uptr->DA) >= rs_drv_tab[dtype].surf) {
|
||||||
uptr->CMD |= (ER1_IAE << 16)|DS_ERR|DS_DRY|DS_ATA;
|
uptr->CMD |= (ER1_IAE << 16)|DS_ERR|DS_DRY|DS_ATA;
|
||||||
uptr->CMD &= ~CR_GO;
|
uptr->CMD &= ~CS1_GO;
|
||||||
sim_debug(DEBUG_DETAIL, dptr, "RSA%o writex done\n", unit);
|
sim_debug(DEBUG_DETAIL, dptr, "%s%o writex done\n", dptr->name, unit);
|
||||||
df10_finish_op(df, 0);
|
rh_finish_op(rhc, 0);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
uptr->DATAPTR = 0;
|
||||||
|
uptr->hwmark = 0;
|
||||||
}
|
}
|
||||||
r = df10_read(df);
|
sts = rh_read(rhc);
|
||||||
rs_buf[ctlr][uptr->DATAPTR++] = df->buf;
|
rs_buf[ctlr][uptr->DATAPTR++] = rhc->buf;
|
||||||
sim_debug(DEBUG_DATA, dptr, "RSA%o write word %d %012llo %09o %06o\n",
|
sim_debug(DEBUG_DATA, dptr, "%s%o write word %d %012llo %09o %06o\n",
|
||||||
unit, uptr->DATAPTR, df->buf, df->cda, df->wcr);
|
dptr->name, unit, uptr->DATAPTR, rhc->buf, rhc->cda, rhc->wcr);
|
||||||
if (r == 0 || uptr->DATAPTR == RS_NUMWD) {
|
if (sts == 0) {
|
||||||
while (uptr->DATAPTR < RS_NUMWD)
|
while (uptr->DATAPTR < RS_NUMWD)
|
||||||
rs_buf[ctlr][uptr->DATAPTR++] = 0;
|
rs_buf[ctlr][uptr->DATAPTR++] = 0;
|
||||||
sim_debug(DEBUG_DETAIL, dptr, "RSA%o write (%d,%d)\n", unit,
|
}
|
||||||
|
if (uptr->DATAPTR == RS_NUMWD) {
|
||||||
|
sim_debug(DEBUG_DETAIL, dptr, "%s%o write (%d,%d)\n", dptr->name, unit,
|
||||||
GET_SC(uptr->DA), GET_SF(uptr->DA));
|
GET_SC(uptr->DA), GET_SF(uptr->DA));
|
||||||
da = GET_DA(uptr->DA, dtype) * RS_NUMWD;
|
da = GET_DA(uptr->DA, dtype) * RS_NUMWD;
|
||||||
(void)sim_fseek(uptr->fileref, da * sizeof(uint64), SEEK_SET);
|
(void)sim_fseek(uptr->fileref, da * sizeof(uint64), SEEK_SET);
|
||||||
(void)sim_fwrite (&rs_buf[ctlr][0], sizeof(uint64), RS_NUMWD,
|
(void)sim_fwrite (&rs_buf[ctlr][0], sizeof(uint64), RS_NUMWD,
|
||||||
uptr->fileref);
|
uptr->fileref);
|
||||||
uptr->DATAPTR = 0;
|
uptr->DATAPTR = 0;
|
||||||
if (r) {
|
CLR_BUF(uptr);
|
||||||
|
if (sts) {
|
||||||
uptr->DA += 1 << DA_V_SC;
|
uptr->DA += 1 << DA_V_SC;
|
||||||
if (GET_SC(uptr->DA) >= rs_drv_tab[dtype].sect) {
|
if (GET_SC(uptr->DA) >= rs_drv_tab[dtype].sect) {
|
||||||
uptr->DA &= (DA_M_SF << DA_V_SF);
|
uptr->DA &= (DA_M_SF << DA_V_SF);
|
||||||
|
@ -798,14 +565,17 @@ t_stat rs_svc (UNIT *uptr)
|
||||||
uptr->CMD |= DS_LST;
|
uptr->CMD |= DS_LST;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (rh_blkend(rhc))
|
||||||
|
goto wr_end;
|
||||||
}
|
}
|
||||||
if (r) {
|
if (sts) {
|
||||||
sim_activate(uptr, 20);
|
sim_activate(uptr, 10);
|
||||||
} else {
|
} else {
|
||||||
sim_debug(DEBUG_DETAIL, dptr, "RSA%o write done\n", unit);
|
wr_end:
|
||||||
|
sim_debug(DEBUG_DETAIL, dptr, "%s%o write done\n", dptr->name, unit);
|
||||||
uptr->CMD |= DS_DRY;
|
uptr->CMD |= DS_DRY;
|
||||||
uptr->CMD &= ~CR_GO;
|
uptr->CMD &= ~CS1_GO;
|
||||||
df10_finish_op(df, 0);
|
rh_finish_op(rhc, 0);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -833,12 +603,9 @@ rs_reset(DEVICE * rstr)
|
||||||
{
|
{
|
||||||
int ctlr;
|
int ctlr;
|
||||||
for (ctlr = 0; ctlr < NUM_DEVS_RS; ctlr++) {
|
for (ctlr = 0; ctlr < NUM_DEVS_RS; ctlr++) {
|
||||||
rs_df10[ctlr].devnum = rs_dib[ctlr].dev_num;
|
rs_rh[ctlr].status = 0;
|
||||||
rs_df10[ctlr].nxmerr = 19;
|
rs_rh[ctlr].attn = 0;
|
||||||
rs_df10[ctlr].ccw_comp = 14;
|
rs_rh[ctlr].rae = 0;
|
||||||
rs_df10[ctlr].status = 0;
|
|
||||||
rs_attn[ctlr] = 0;
|
|
||||||
rs_rae[ctlr] = 0;
|
|
||||||
}
|
}
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
@ -848,16 +615,16 @@ t_stat
|
||||||
rs_boot(int32 unit_num, DEVICE * rptr)
|
rs_boot(int32 unit_num, DEVICE * rptr)
|
||||||
{
|
{
|
||||||
UNIT *uptr = &rptr->units[unit_num];
|
UNIT *uptr = &rptr->units[unit_num];
|
||||||
int ctlr = GET_CNTRL(uptr->flags);
|
int ctlr = GET_CNTRL_RH(uptr->flags);
|
||||||
|
struct rh_if *rhc;
|
||||||
DEVICE *dptr;
|
DEVICE *dptr;
|
||||||
struct df10 *df;
|
|
||||||
uint32 addr;
|
uint32 addr;
|
||||||
uint32 ptr = 0;
|
uint32 ptr = 0;
|
||||||
uint64 word;
|
uint64 word;
|
||||||
int wc;
|
int wc;
|
||||||
|
|
||||||
df = &rs_df10[ctlr];
|
|
||||||
dptr = rs_devs[ctlr];
|
dptr = rs_devs[ctlr];
|
||||||
|
rhc = &rs_rh[ctlr];
|
||||||
(void)sim_fseek(uptr->fileref, 0, SEEK_SET);
|
(void)sim_fseek(uptr->fileref, 0, SEEK_SET);
|
||||||
(void)sim_fread (&rs_buf[0][0], sizeof(uint64), RS_NUMWD, uptr->fileref);
|
(void)sim_fread (&rs_buf[0][0], sizeof(uint64), RS_NUMWD, uptr->fileref);
|
||||||
uptr->CMD |= DS_VV;
|
uptr->CMD |= DS_VV;
|
||||||
|
@ -875,9 +642,9 @@ rs_boot(int32 unit_num, DEVICE * rptr)
|
||||||
addr = rs_buf[0][ptr] & RMASK;
|
addr = rs_buf[0][ptr] & RMASK;
|
||||||
wc = (rs_buf[0][ptr++] >> 18) & RMASK;
|
wc = (rs_buf[0][ptr++] >> 18) & RMASK;
|
||||||
word = rs_buf[0][ptr++];
|
word = rs_buf[0][ptr++];
|
||||||
rs_reg[ctlr] = 040;
|
rhc->reg = 040;
|
||||||
rs_drive[ctlr] = uptr - dptr->units;
|
rhc->drive = uptr - dptr->units;
|
||||||
df->status |= CCW_COMP_1|PI_ENABLE;
|
rhc->status |= CCW_COMP_1|PI_ENABLE;
|
||||||
PC = word & RMASK;
|
PC = word & RMASK;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
|
||||||
|
@ -901,14 +668,19 @@ t_stat rs_attach (UNIT *uptr, CONST char *cptr)
|
||||||
if (rstr == 0)
|
if (rstr == 0)
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
dib = (DIB *) rstr->ctxt;
|
dib = (DIB *) rstr->ctxt;
|
||||||
ctlr = dib->dev_num & 014;
|
for (ctlr = 0; rh[ctlr].dev_num != 0; ctlr++) {
|
||||||
|
if (rh[ctlr].dev == rstr)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (uptr->flags & UNIT_WLK)
|
||||||
|
uptr->CMD |= DS_WRL;
|
||||||
|
if (sim_switches & SIM_SW_REST)
|
||||||
|
return SCPE_OK;
|
||||||
uptr->DA = 0;
|
uptr->DA = 0;
|
||||||
uptr->CMD &= ~DS_VV;
|
uptr->CMD &= ~DS_VV;
|
||||||
uptr->CMD |= DS_DPR|DS_MOL|DS_DRY;
|
uptr->CMD |= DS_DPR|DS_MOL|DS_DRY;
|
||||||
if (uptr->flags & UNIT_WLK)
|
rs_rh[ctlr].status |= PI_ENABLE;
|
||||||
uptr->CMD |= DS_WRL;
|
set_interrupt(dib->dev_num, rs_rh[ctlr].status);
|
||||||
rs_df10[ctlr].status |= PI_ENABLE;
|
|
||||||
set_interrupt(dib->dev_num, rs_df10[ctlr].status);
|
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
211
PDP10/kx10_sys.c
211
PDP10/kx10_sys.c
|
@ -1,9 +1,9 @@
|
||||||
/* ka10_sys.c: PDP-10 simulator interface
|
/* kx10_sys.c: PDP-10 simulator interface
|
||||||
Derived from Bob Supnik's pdp10_sys.c
|
Derived from Bob Supnik's pdp10_sys.c
|
||||||
|
|
||||||
|
|
||||||
Copyright (c) 2005-2009, Robert M Supnik
|
Copyright (c) 2005-2009, Robert M Supnik
|
||||||
Copyright (c) 2011-2018, Richard Cornwell
|
Copyright (c) 2011-2020, Richard Cornwell
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -42,11 +42,8 @@
|
||||||
sim_load binary loader
|
sim_load binary loader
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if KLB
|
#if KL
|
||||||
char sim_name[] = "KL-10B";
|
char sim_name[] = "KL-10";
|
||||||
#endif
|
|
||||||
#if KLA
|
|
||||||
char sim_name[] = "KL-10A";
|
|
||||||
#endif
|
#endif
|
||||||
#if KI
|
#if KI
|
||||||
char sim_name[] = "KI-10";
|
char sim_name[] = "KI-10";
|
||||||
|
@ -68,6 +65,9 @@ DEVICE *sim_devices[] = {
|
||||||
#if PDP6 | KA | KI
|
#if PDP6 | KA | KI
|
||||||
&cty_dev,
|
&cty_dev,
|
||||||
#endif
|
#endif
|
||||||
|
#if KL
|
||||||
|
&dte_dev,
|
||||||
|
#endif
|
||||||
#if (NUM_DEVS_PT > 0)
|
#if (NUM_DEVS_PT > 0)
|
||||||
&ptp_dev,
|
&ptp_dev,
|
||||||
&ptr_dev,
|
&ptr_dev,
|
||||||
|
@ -75,6 +75,9 @@ DEVICE *sim_devices[] = {
|
||||||
#if (NUM_DEVS_LP > 0)
|
#if (NUM_DEVS_LP > 0)
|
||||||
&lpt_dev,
|
&lpt_dev,
|
||||||
#endif
|
#endif
|
||||||
|
#if (NUM_DEVS_LP20 > 0)
|
||||||
|
&lp20_dev,
|
||||||
|
#endif
|
||||||
#if (NUM_DEVS_CR > 0)
|
#if (NUM_DEVS_CR > 0)
|
||||||
&cr_dev,
|
&cr_dev,
|
||||||
#endif
|
#endif
|
||||||
|
@ -141,6 +144,9 @@ DEVICE *sim_devices[] = {
|
||||||
#if (NUM_DEVS_DC > 0)
|
#if (NUM_DEVS_DC > 0)
|
||||||
&dc_dev,
|
&dc_dev,
|
||||||
#endif
|
#endif
|
||||||
|
#if (NUM_DEVS_TTY > 0)
|
||||||
|
&tty_dev,
|
||||||
|
#endif
|
||||||
#if (NUM_DEVS_DCS > 0)
|
#if (NUM_DEVS_DCS > 0)
|
||||||
&dcs_dev,
|
&dcs_dev,
|
||||||
#endif
|
#endif
|
||||||
|
@ -155,10 +161,19 @@ DEVICE *sim_devices[] = {
|
||||||
#if (NUM_DEVS_WCNSLS > 0)
|
#if (NUM_DEVS_WCNSLS > 0)
|
||||||
&wcnsls_dev,
|
&wcnsls_dev,
|
||||||
#endif
|
#endif
|
||||||
|
#if (NUM_DEVS_OCNSLS > 0)
|
||||||
|
&ocnsls_dev,
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if (NUM_DEVS_III > 0)
|
||||||
|
&iii_dev,
|
||||||
#endif
|
#endif
|
||||||
#if NUM_DEVS_IMP > 0
|
#if NUM_DEVS_IMP > 0
|
||||||
&imp_dev,
|
&imp_dev,
|
||||||
#endif
|
#endif
|
||||||
|
#if NUM_DEVS_NIA > 0
|
||||||
|
&nia_dev,
|
||||||
|
#endif
|
||||||
#if NUM_DEVS_CH10 > 0
|
#if NUM_DEVS_CH10 > 0
|
||||||
&ch10_dev,
|
&ch10_dev,
|
||||||
#endif
|
#endif
|
||||||
|
@ -182,6 +197,9 @@ DEVICE *sim_devices[] = {
|
||||||
#if NUM_DEVS_AUXCPU > 0
|
#if NUM_DEVS_AUXCPU > 0
|
||||||
&auxcpu_dev,
|
&auxcpu_dev,
|
||||||
#endif
|
#endif
|
||||||
|
#if NUM_DEVS_SLAVE > 0
|
||||||
|
&slave_dev,
|
||||||
|
#endif
|
||||||
#if NUM_DEVS_DKB > 0
|
#if NUM_DEVS_DKB > 0
|
||||||
&dkb_dev,
|
&dkb_dev,
|
||||||
#endif
|
#endif
|
||||||
|
@ -197,7 +215,11 @@ DEVICE *sim_devices[] = {
|
||||||
const char *sim_stop_messages[] = {
|
const char *sim_stop_messages[] = {
|
||||||
"Unknown error",
|
"Unknown error",
|
||||||
"HALT instruction",
|
"HALT instruction",
|
||||||
"Breakpoint"
|
"Breakpoint",
|
||||||
|
"Invalid access",
|
||||||
|
#if MAGIC_SWITCH
|
||||||
|
"No magic"
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Simulator debug controls */
|
/* Simulator debug controls */
|
||||||
|
@ -232,6 +254,7 @@ DEBTAB crd_debug[] = {
|
||||||
#define FMT_E 3 /* EXE */
|
#define FMT_E 3 /* EXE */
|
||||||
#define FMT_D 4 /* WAITS DMP */
|
#define FMT_D 4 /* WAITS DMP */
|
||||||
#define FMT_I 5 /* ITS SBLK */
|
#define FMT_I 5 /* ITS SBLK */
|
||||||
|
#define FMT_B 6 /* EXB format */
|
||||||
|
|
||||||
#define EXE_DIR 01776 /* EXE directory */
|
#define EXE_DIR 01776 /* EXE directory */
|
||||||
#define EXE_VEC 01775 /* EXE entry vec */
|
#define EXE_VEC 01775 /* EXE entry vec */
|
||||||
|
@ -510,18 +533,27 @@ return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int get_word(FILE *fileref, uint64 *word)
|
int get_word(FILE *fileref, uint64 *word, int ftype)
|
||||||
{
|
{
|
||||||
char cbuf[5];
|
char cbuf[5];
|
||||||
|
|
||||||
if (sim_fread(cbuf, 1, 5, fileref) != 5)
|
if (sim_fread(cbuf, 1, 5, fileref) != 5)
|
||||||
return 1;
|
return 1;
|
||||||
*word = ((uint64)(cbuf[0]) << 29) |
|
if (ftype) {
|
||||||
((uint64)(cbuf[1]) << 22) |
|
*word = ((uint64)(cbuf[0] & 0177) << 29) |
|
||||||
((uint64)(cbuf[2]) << 15) |
|
((uint64)(cbuf[1] & 0177) << 22) |
|
||||||
((uint64)(cbuf[3]) << 8) |
|
((uint64)(cbuf[2] & 0177) << 15) |
|
||||||
((uint64)(cbuf[4] & 0177) << 1) |
|
((uint64)(cbuf[3] & 0177) << 8) |
|
||||||
((uint64)(cbuf[4] & 0200) >> 7);
|
((uint64)(cbuf[4] & 0177) << 1);
|
||||||
|
if (cbuf[4] & 0200)
|
||||||
|
*word |= 1;
|
||||||
|
} else {
|
||||||
|
*word = ((uint64)(cbuf[0] & 0377) << 28) |
|
||||||
|
((uint64)(cbuf[1] & 0377) << 20) |
|
||||||
|
((uint64)(cbuf[2] & 0377) << 12) |
|
||||||
|
((uint64)(cbuf[3] & 0377) << 4) |
|
||||||
|
(uint64)(cbuf[4] & 017);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -538,14 +570,14 @@ int get_word(FILE *fileref, uint64 *word)
|
||||||
JRST start
|
JRST start
|
||||||
*/
|
*/
|
||||||
|
|
||||||
t_stat load_sav (FILE *fileref)
|
t_stat load_sav (FILE *fileref, int ftype)
|
||||||
{
|
{
|
||||||
uint64 data;
|
uint64 data;
|
||||||
uint32 pa;
|
uint32 pa;
|
||||||
int32 wc;
|
int32 wc;
|
||||||
|
|
||||||
for ( ;; ) { /* loop */
|
for ( ;; ) { /* loop */
|
||||||
if (get_word(fileref, &data))
|
if (get_word(fileref, &data, ftype))
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
wc = (int32)(data >> 18);
|
wc = (int32)(data >> 18);
|
||||||
pa = (uint32) (data & RMASK);
|
pa = (uint32) (data & RMASK);
|
||||||
|
@ -559,7 +591,7 @@ t_stat load_sav (FILE *fileref)
|
||||||
pa &= RMASK;
|
pa &= RMASK;
|
||||||
wc++;
|
wc++;
|
||||||
wc &= RMASK;
|
wc &= RMASK;
|
||||||
if (get_word(fileref, &data))
|
if (get_word(fileref, &data, ftype))
|
||||||
return SCPE_FMT;
|
return SCPE_FMT;
|
||||||
M[pa] = data;
|
M[pa] = data;
|
||||||
} /* end if count*/
|
} /* end if count*/
|
||||||
|
@ -594,7 +626,7 @@ t_stat load_sav (FILE *fileref)
|
||||||
#define PAG_V_PN 9
|
#define PAG_V_PN 9
|
||||||
#define DIRSIZ (2 * PAG_SIZE)
|
#define DIRSIZ (2 * PAG_SIZE)
|
||||||
|
|
||||||
t_stat load_exe (FILE *fileref)
|
t_stat load_exe (FILE *fileref, int ftype)
|
||||||
{
|
{
|
||||||
uint64 data, dirbuf[DIRSIZ], pagbuf[PAG_SIZE], entbuf[2];
|
uint64 data, dirbuf[DIRSIZ], pagbuf[PAG_SIZE], entbuf[2];
|
||||||
int32 ndir, entvec, i, j, k, cont, bsz, bty, rpt, wc;
|
int32 ndir, entvec, i, j, k, cont, bsz, bty, rpt, wc;
|
||||||
|
@ -604,8 +636,9 @@ uint32 ma;
|
||||||
ndir = entvec = 0; /* no dir, entvec */
|
ndir = entvec = 0; /* no dir, entvec */
|
||||||
cont = 1;
|
cont = 1;
|
||||||
do {
|
do {
|
||||||
wc = sim_fread (&data, sizeof (uint64), 1, fileref);/* read blk hdr */
|
|
||||||
if (wc == 0) /* error? */
|
wc = get_word(fileref, &data, ftype);
|
||||||
|
if (wc != 0) /* error? */
|
||||||
return SCPE_FMT;
|
return SCPE_FMT;
|
||||||
bsz = (int32) ((data & RMASK) - 1); /* get count */
|
bsz = (int32) ((data & RMASK) - 1); /* get count */
|
||||||
if (bsz < 0) /* zero? */
|
if (bsz < 0) /* zero? */
|
||||||
|
@ -616,9 +649,11 @@ do {
|
||||||
case EXE_DIR: /* directory */
|
case EXE_DIR: /* directory */
|
||||||
if (ndir != 0) /* got one */
|
if (ndir != 0) /* got one */
|
||||||
return SCPE_FMT;
|
return SCPE_FMT;
|
||||||
ndir = sim_fread (dirbuf, sizeof (uint64), bsz, fileref);
|
for (i = 0; i < bsz; i++) {
|
||||||
if (ndir < bsz) /* error */
|
if (get_word(fileref, &dirbuf[i], ftype))
|
||||||
return SCPE_FMT;
|
return SCPE_FMT;
|
||||||
|
}
|
||||||
|
ndir = bsz;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EXE_PDV: /* optional */
|
case EXE_PDV: /* optional */
|
||||||
|
@ -628,9 +663,11 @@ do {
|
||||||
case EXE_VEC: /* entry vec */
|
case EXE_VEC: /* entry vec */
|
||||||
if (bsz != 2) /* must be 2 wds */
|
if (bsz != 2) /* must be 2 wds */
|
||||||
return SCPE_FMT;
|
return SCPE_FMT;
|
||||||
entvec = sim_fread (entbuf, sizeof (uint64), bsz, fileref);
|
for (i = 0; i < bsz; i++) {
|
||||||
if (entvec < 2) /* error? */
|
if (get_word(fileref, &entbuf[i], ftype))
|
||||||
return SCPE_FMT;
|
return SCPE_FMT;
|
||||||
|
}
|
||||||
|
entvec = bsz;
|
||||||
cont = 0; /* stop */
|
cont = 0; /* stop */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -651,10 +688,11 @@ for (i = 0; i < ndir; i = i + 2) { /* loop thru dir */
|
||||||
rpt = ((int32) ((dirbuf[i + 1] >> 27) + 1)) & 0777; /* repeat count */
|
rpt = ((int32) ((dirbuf[i + 1] >> 27) + 1)) & 0777; /* repeat count */
|
||||||
for (j = 0; j < rpt; j++, mpage++) { /* loop thru rpts */
|
for (j = 0; j < rpt; j++, mpage++) { /* loop thru rpts */
|
||||||
if (fpage) { /* file pages? */
|
if (fpage) { /* file pages? */
|
||||||
(void)sim_fseek (fileref, (fpage << PAG_V_PN) * sizeof (uint64), SEEK_SET);
|
(void)sim_fseek (fileref, (fpage << PAG_V_PN) * 5, SEEK_SET);
|
||||||
wc = sim_fread (pagbuf, sizeof (uint64), PAG_SIZE, fileref);
|
for (k = 0; k < PAG_SIZE; k++) {
|
||||||
if (wc < PAG_SIZE)
|
if (get_word(fileref, &pagbuf[k], ftype))
|
||||||
return SCPE_FMT;
|
break;
|
||||||
|
}
|
||||||
fpage++;
|
fpage++;
|
||||||
}
|
}
|
||||||
ma = mpage << PAG_V_PN; /* mem addr */
|
ma = mpage << PAG_V_PN; /* mem addr */
|
||||||
|
@ -667,18 +705,103 @@ for (i = 0; i < ndir; i = i + 2) { /* loop thru dir */
|
||||||
} /* end directory */
|
} /* end directory */
|
||||||
if (entvec && entbuf[1])
|
if (entvec && entbuf[1])
|
||||||
PC = (int32) (entbuf[1] & RMASK); /* start addr */
|
PC = (int32) (entbuf[1] & RMASK); /* start addr */
|
||||||
|
else if (entvec == 0)
|
||||||
|
PC = (int32) (M[0120] & RMASK);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int exb_pos = -1;
|
||||||
|
int get_exb_byte (FILE *fileref, int *byt, int ftype)
|
||||||
|
{
|
||||||
|
static uint64 word;
|
||||||
|
|
||||||
|
exb_pos++;
|
||||||
|
switch(exb_pos & 3) {
|
||||||
|
case 0: if (get_word(fileref, &word, ftype))
|
||||||
|
return 1;
|
||||||
|
*byt = ((word >> 18) & 0377);
|
||||||
|
break;
|
||||||
|
case 1: *byt = ((word >> 26) & 0377);
|
||||||
|
break;
|
||||||
|
case 2: *byt = ((word >> 0) & 0377);
|
||||||
|
break;
|
||||||
|
case 3: *byt = ((word >> 8) & 0377);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat load_exb (FILE *fileref, int ftype)
|
||||||
|
{
|
||||||
|
int odd = 0;
|
||||||
|
int pos = 0;
|
||||||
|
int wc;
|
||||||
|
int byt;
|
||||||
|
uint64 word;
|
||||||
|
t_addr addr;
|
||||||
|
|
||||||
|
exb_pos = -1;
|
||||||
|
for ( ;; ) {
|
||||||
|
/* All records start on even byte */
|
||||||
|
if (odd && get_exb_byte (fileref, &byt, ftype))
|
||||||
|
return SCPE_FMT;
|
||||||
|
if (get_exb_byte(fileref, &byt, ftype))
|
||||||
|
return SCPE_FMT;
|
||||||
|
wc = byt;
|
||||||
|
if (get_exb_byte(fileref, &byt, ftype))
|
||||||
|
return SCPE_FMT;
|
||||||
|
wc |= byt << 8;
|
||||||
|
wc -= 4;
|
||||||
|
odd = wc & 1;
|
||||||
|
if (get_exb_byte(fileref, &byt, ftype))
|
||||||
|
return SCPE_FMT;
|
||||||
|
addr = byt;
|
||||||
|
if (get_exb_byte(fileref, &byt, ftype))
|
||||||
|
return SCPE_FMT;
|
||||||
|
addr |= byt << 8;
|
||||||
|
if (get_exb_byte(fileref, &byt, ftype))
|
||||||
|
return SCPE_FMT;
|
||||||
|
addr |= byt << 16;
|
||||||
|
if (get_exb_byte(fileref, &byt, ftype))
|
||||||
|
return SCPE_FMT;
|
||||||
|
addr |= byt << 24;
|
||||||
|
/* Empty record gives start address */
|
||||||
|
if (wc == 0) {
|
||||||
|
PC = addr;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
pos = 0;
|
||||||
|
for (; wc > 0; wc--, pos++) {
|
||||||
|
if (get_exb_byte(fileref, &byt, ftype))
|
||||||
|
return SCPE_FMT;
|
||||||
|
switch(pos) {
|
||||||
|
case 0: word = ((uint64)byt); break;
|
||||||
|
case 1: word |= ((uint64)byt) << 8; break;
|
||||||
|
case 2: word |= ((uint64)byt) << 16; break;
|
||||||
|
case 3: word |= ((uint64)byt) << 24; break;
|
||||||
|
case 4: word |= ((uint64)(byt & 017)) << 32;
|
||||||
|
M[addr++] = word;
|
||||||
|
pos = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SCPE_FMT;
|
||||||
|
}
|
||||||
|
|
||||||
/* Master loader */
|
/* Master loader */
|
||||||
|
|
||||||
t_stat sim_load (FILE *fileref, CONST char *cptr, CONST char *fnam, int flag)
|
t_stat sim_load (FILE *fileref, CONST char *cptr, CONST char *fnam, int flag)
|
||||||
{
|
{
|
||||||
uint64 data;
|
uint64 data;
|
||||||
int32 wc, fmt;
|
int32 wc, fmt;
|
||||||
|
int ftype;
|
||||||
extern int32 sim_switches;
|
extern int32 sim_switches;
|
||||||
|
|
||||||
fmt = 0; /* no fmt */
|
fmt = 0; /* no fmt */
|
||||||
|
ftype = 0;
|
||||||
|
if (sim_switches & SWMASK ('C')) /* -c? core dump */
|
||||||
|
ftype = 1;
|
||||||
if (sim_switches & SWMASK ('R')) /* -r? */
|
if (sim_switches & SWMASK ('R')) /* -r? */
|
||||||
fmt = FMT_R;
|
fmt = FMT_R;
|
||||||
else if (sim_switches & SWMASK ('S')) /* -s? */
|
else if (sim_switches & SWMASK ('S')) /* -s? */
|
||||||
|
@ -689,12 +812,16 @@ else if (sim_switches & SWMASK ('D')) /* -d? */
|
||||||
fmt = FMT_D;
|
fmt = FMT_D;
|
||||||
else if (sim_switches & SWMASK ('I')) /* -i? */
|
else if (sim_switches & SWMASK ('I')) /* -i? */
|
||||||
fmt = FMT_I;
|
fmt = FMT_I;
|
||||||
|
else if (sim_switches & SWMASK ('B')) /* -b? */
|
||||||
|
fmt = FMT_B;
|
||||||
else if (match_ext (fnam, "RIM")) /* .RIM? */
|
else if (match_ext (fnam, "RIM")) /* .RIM? */
|
||||||
fmt = FMT_R;
|
fmt = FMT_R;
|
||||||
else if (match_ext (fnam, "SAV")) /* .SAV? */
|
else if (match_ext (fnam, "SAV")) /* .SAV? */
|
||||||
fmt = FMT_S;
|
fmt = FMT_S;
|
||||||
else if (match_ext (fnam, "EXE")) /* .EXE? */
|
else if (match_ext (fnam, "EXE")) /* .EXE? */
|
||||||
fmt = FMT_E;
|
fmt = FMT_E;
|
||||||
|
else if (match_ext (fnam, "EXB")) /* .EXB? */
|
||||||
|
fmt = FMT_B;
|
||||||
else if (match_ext (fnam, "DMP")) /* .DMP? */
|
else if (match_ext (fnam, "DMP")) /* .DMP? */
|
||||||
fmt = FMT_D;
|
fmt = FMT_D;
|
||||||
else if (match_ext (fnam, "BIN")) /* .BIN? */
|
else if (match_ext (fnam, "BIN")) /* .BIN? */
|
||||||
|
@ -716,16 +843,19 @@ switch (fmt) { /* case fmt */
|
||||||
return load_rim (fileref);
|
return load_rim (fileref);
|
||||||
|
|
||||||
case FMT_S: /* SAV */
|
case FMT_S: /* SAV */
|
||||||
return load_sav (fileref);
|
return load_sav (fileref, ftype);
|
||||||
|
|
||||||
case FMT_E: /* EXE */
|
case FMT_E: /* EXE */
|
||||||
return load_exe (fileref);
|
return load_exe (fileref, ftype);
|
||||||
|
|
||||||
case FMT_D: /* DMP */
|
case FMT_D: /* DMP */
|
||||||
return load_dmp (fileref);
|
return load_dmp (fileref);
|
||||||
|
|
||||||
case FMT_I: /* SBLK */
|
case FMT_I: /* SBLK */
|
||||||
return load_sblk (fileref);
|
return load_sblk (fileref);
|
||||||
|
|
||||||
|
case FMT_B: /* EXB */
|
||||||
|
return load_exb (fileref, ftype);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("Can't determine load file format\n");
|
printf ("Can't determine load file format\n");
|
||||||
|
@ -759,13 +889,22 @@ static const char *opcode[] = {
|
||||||
"LUUO10", "LUUO11", "LUUO12", "LUUO13", "LUUO14", "LUUO15", "LUUO16", "LUUO17",
|
"LUUO10", "LUUO11", "LUUO12", "LUUO13", "LUUO14", "LUUO15", "LUUO16", "LUUO17",
|
||||||
"LUUO20", "LUUO21", "LUUO22", "LUUO23", "LUUO24", "LUUO25", "LUUO26", "LUUO27",
|
"LUUO20", "LUUO21", "LUUO22", "LUUO23", "LUUO24", "LUUO25", "LUUO26", "LUUO27",
|
||||||
"LUUO30", "LUUO31", "LUUO32", "LUUO33", "LUUO34", "LUUO35", "LUUO36", "LUUO37",
|
"LUUO30", "LUUO31", "LUUO32", "LUUO33", "LUUO34", "LUUO35", "LUUO36", "LUUO37",
|
||||||
"MUUO40", "MUUO41", "MUUO42", "MUUO43", "MUUO44", "MUUO45", "MUUO46", "MUUO47",
|
"CALL", "INITI", "MUUO42", "MUUO43", "MUUO44", "MUUO45", "MUUO46", "CALLI",
|
||||||
"MUUO50", "MUUO51", "MUUO52", "MUUO53", "MUUO54", "MUUO55", "MUUO56", "MUUO57",
|
#if KL
|
||||||
"MUUO60", "MUUO61", "MUUO62", "MUUO63", "MUUO64", "MUUO65", "MUUO66", "MUUO67",
|
"OPEN", "TTCALL", "PMOVE", "PMOVEM", "MUUO54", "RENAME", "IN", "OUT",
|
||||||
"MUUO70", "MUUO71", "MUUO72", "MUUO73", "MUUO74", "MUUO75", "MUUO76", "MUUO77",
|
#else
|
||||||
|
"OPEN", "TTCALL", "MUUO52", "MUUO53", "MUUO54", "RENAME", "IN", "OUT",
|
||||||
|
#endif
|
||||||
|
"SETSTS", "STATO", "STATUS", "GETSTS", "INBUF", "OUTBUF", "INPUT", "OUTPUT",
|
||||||
|
"CLOSE", "RELEAS", "MTAPE", "UGETF", "USETI", "USETO", "LOOKUP", "ENTER",
|
||||||
|
|
||||||
"UJEN", "MUUO101", "MUUO102", "JSYS", "MUUO104", "MUUO105", "MUUO106",
|
#if KL
|
||||||
|
"UJEN", "GFAD", "GFSB", "JSYS", "ADJSP", "GFMP", "GFDV ",
|
||||||
"DFAD", "DFSB", "DFMP", "DFDV", "DADD", "DSUB", "DMUL", "DDIV",
|
"DFAD", "DFSB", "DFMP", "DFDV", "DADD", "DSUB", "DMUL", "DDIV",
|
||||||
|
#else
|
||||||
|
"UJEN", "MUUO101", "MUUO102", "JSYS", "MUUO104", "MUUO105", "MUUO106",
|
||||||
|
"DFAD", "DFSB", "DFMP", "DFDV", "MUUO114", "MUUO115", "MUUO116", "MUUO117",
|
||||||
|
#endif
|
||||||
"DMOVE", "DMOVN", "FIX", "EXTEND", "DMOVEM", "DMOVNM", "FIXR", "FLTR",
|
"DMOVE", "DMOVN", "FIX", "EXTEND", "DMOVEM", "DMOVNM", "FIXR", "FLTR",
|
||||||
"UFA", "DFN", "FSC", "ADJBP", "ILDB", "LDB", "IDPB", "DPB",
|
"UFA", "DFN", "FSC", "ADJBP", "ILDB", "LDB", "IDPB", "DPB",
|
||||||
"FAD", "FADL", "FADM", "FADB", "FADR", "FADRL", "FADRM", "FADRB",
|
"FAD", "FADL", "FADM", "FADB", "FADR", "FADRL", "FADRM", "FADRB",
|
||||||
|
|
627
PDP10/kx10_tu.c
627
PDP10/kx10_tu.c
File diff suppressed because it is too large
Load diff
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
Copyright (c) 2017 Richard Cornwell
|
Copyright (c) 2017 Richard Cornwell
|
||||||
|
|
||||||
|
Based on PDP18B/pdp18b_dt.c by:
|
||||||
|
Copyright (c) 1993-2017, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
to deal in the Software without restriction, including without limitation
|
to deal in the Software without restriction, including without limitation
|
||||||
|
@ -19,6 +22,10 @@
|
||||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
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.
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
Except as contained in this notice, the name of Robert M Supnik shall not be
|
||||||
|
used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
Except as contained in this notice, the name of Richard Cornwell shall not be
|
Except as contained in this notice, the name of Richard Cornwell shall not be
|
||||||
used in advertising or otherwise to promote the sale, use or other dealings
|
used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
in this Software without prior written authorization from Richard Cornwell.
|
in this Software without prior written authorization from Richard Cornwell.
|
||||||
|
@ -228,6 +235,8 @@
|
||||||
|
|
||||||
#define DT_WRDTIM 15000
|
#define DT_WRDTIM 15000
|
||||||
|
|
||||||
|
#define WRITTEN u6
|
||||||
|
|
||||||
int32 dtc_dtsa = 0; /* status A */
|
int32 dtc_dtsa = 0; /* status A */
|
||||||
int32 dtc_dtsb = 0; /* status B */
|
int32 dtc_dtsb = 0; /* status B */
|
||||||
int dtc_dct = 0;
|
int dtc_dct = 0;
|
||||||
|
@ -239,6 +248,7 @@ t_stat dtc_set_dct (UNIT *, int32, CONST char *, void *);
|
||||||
t_stat dtc_show_dct (FILE *, UNIT *, int32, CONST void *);
|
t_stat dtc_show_dct (FILE *, UNIT *, int32, CONST void *);
|
||||||
t_stat dtc_reset (DEVICE *dptr);
|
t_stat dtc_reset (DEVICE *dptr);
|
||||||
t_stat dtc_attach (UNIT *uptr, CONST char *cptr);
|
t_stat dtc_attach (UNIT *uptr, CONST char *cptr);
|
||||||
|
void dtc_flush (UNIT *uptr);
|
||||||
t_stat dtc_detach (UNIT *uptr);
|
t_stat dtc_detach (UNIT *uptr);
|
||||||
|
|
||||||
/* DT data structures
|
/* DT data structures
|
||||||
|
@ -495,7 +505,6 @@ dtc_svc (UNIT *uptr)
|
||||||
case DTC_FEND: /* Tape in endzone */
|
case DTC_FEND: /* Tape in endzone */
|
||||||
/* Set stop */
|
/* Set stop */
|
||||||
sim_debug(DEBUG_DETAIL, &dtc_dev, "DTC %o rev forward end\n", u);
|
sim_debug(DEBUG_DETAIL, &dtc_dev, "DTC %o rev forward end\n", u);
|
||||||
uptr->u6 = 0;
|
|
||||||
dtc_dtsb |= DTB_EOT|DTB_NULL;
|
dtc_dtsb |= DTB_EOT|DTB_NULL;
|
||||||
dtc_dtsb &= ~(DTB_REQ|DTB_ACT);
|
dtc_dtsb &= ~(DTB_REQ|DTB_ACT);
|
||||||
if (uptr->CMD & DTC_ETF)
|
if (uptr->CMD & DTC_ETF)
|
||||||
|
@ -607,7 +616,6 @@ dtc_svc (UNIT *uptr)
|
||||||
uptr->DSTATE &= ~(DTC_M_WORD << DTC_V_WORD);
|
uptr->DSTATE &= ~(DTC_M_WORD << DTC_V_WORD);
|
||||||
uptr->DSTATE |= (word - 1) << DTC_V_WORD;
|
uptr->DSTATE |= (word - 1) << DTC_V_WORD;
|
||||||
}
|
}
|
||||||
uptr->u6-=2;
|
|
||||||
if ((dtc_dtsb & DTB_DLY) || (dtc_dtsb & DTB_ACT) == 0)
|
if ((dtc_dtsb & DTB_DLY) || (dtc_dtsb & DTB_ACT) == 0)
|
||||||
break;
|
break;
|
||||||
switch (DTC_GETFNC(uptr->CMD)) {
|
switch (DTC_GETFNC(uptr->CMD)) {
|
||||||
|
@ -636,6 +644,7 @@ dtc_svc (UNIT *uptr)
|
||||||
}
|
}
|
||||||
fbuf[off] = (data >> 18) & RMASK;
|
fbuf[off] = (data >> 18) & RMASK;
|
||||||
fbuf[off+1] = data & RMASK;
|
fbuf[off+1] = data & RMASK;
|
||||||
|
uptr->WRITTEN = 1;
|
||||||
uptr->hwmark = uptr->capac;
|
uptr->hwmark = uptr->capac;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -749,7 +758,6 @@ dtc_svc (UNIT *uptr)
|
||||||
sim_debug(DEBUG_DETAIL, &dtc_dev, "DTC %o forward end\n", u);
|
sim_debug(DEBUG_DETAIL, &dtc_dev, "DTC %o forward end\n", u);
|
||||||
/* Move to first block */
|
/* Move to first block */
|
||||||
uptr->DSTATE = DTC_FBLK | (uptr->DSTATE & DTC_MOTMASK);
|
uptr->DSTATE = DTC_FBLK | (uptr->DSTATE & DTC_MOTMASK);
|
||||||
uptr->u6 = 0;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DTC_FBLK: /* In forward block number */
|
case DTC_FBLK: /* In forward block number */
|
||||||
|
@ -887,6 +895,7 @@ dtc_svc (UNIT *uptr)
|
||||||
dtc_dtsb |= DTB_DONE;
|
dtc_dtsb |= DTB_DONE;
|
||||||
fbuf[off] = (data >> 18) & RMASK;
|
fbuf[off] = (data >> 18) & RMASK;
|
||||||
fbuf[off+1] = data & RMASK;
|
fbuf[off+1] = data & RMASK;
|
||||||
|
uptr->WRITTEN = 1;
|
||||||
uptr->hwmark = uptr->capac;
|
uptr->hwmark = uptr->capac;
|
||||||
break;
|
break;
|
||||||
case FNC_WMRK:
|
case FNC_WMRK:
|
||||||
|
@ -1178,13 +1187,15 @@ dtc_attach (UNIT *uptr, CONST char *cptr)
|
||||||
return SCPE_MEM;
|
return SCPE_MEM;
|
||||||
}
|
}
|
||||||
fbuf = (uint32 *) uptr->filebuf; /* file buffer */
|
fbuf = (uint32 *) uptr->filebuf; /* file buffer */
|
||||||
printf ("%s%d: ", sim_dname (&dtc_dev), u);
|
sim_printf ("%s%d: ", sim_dname (&dtc_dev), u);
|
||||||
if (uptr->flags & UNIT_8FMT)
|
if (uptr->flags & UNIT_8FMT)
|
||||||
printf ("12b format");
|
sim_printf ("12b format");
|
||||||
else if (uptr->flags & UNIT_11FMT)
|
else if (uptr->flags & UNIT_11FMT)
|
||||||
printf ("16b format");
|
sim_printf ("16b format");
|
||||||
else printf ("18b/36b format");
|
else sim_printf ("18b/36b format");
|
||||||
printf (", buffering file in memory\n");
|
sim_printf (", buffering file in memory\n");
|
||||||
|
uptr->WRITTEN = 0;
|
||||||
|
uptr->io_flush = dtc_flush;
|
||||||
if (uptr->flags & UNIT_8FMT) { /* 12b? */
|
if (uptr->flags & UNIT_8FMT) { /* 12b? */
|
||||||
for (ba = 0; ba < uptr->capac; ) { /* loop thru file */
|
for (ba = 0; ba < uptr->capac; ) { /* loop thru file */
|
||||||
k = fxread (pdp8b, sizeof (uint16), D8_NBSIZE, uptr->fileref);
|
k = fxread (pdp8b, sizeof (uint16), D8_NBSIZE, uptr->fileref);
|
||||||
|
@ -1201,8 +1212,7 @@ dtc_attach (UNIT *uptr, CONST char *cptr)
|
||||||
}
|
}
|
||||||
} /* end file loop */
|
} /* end file loop */
|
||||||
uptr->hwmark = ba;
|
uptr->hwmark = ba;
|
||||||
} /* end if */
|
} else if (uptr->flags & UNIT_11FMT) { /* 16b? */
|
||||||
else if (uptr->flags & UNIT_11FMT) { /* 16b? */
|
|
||||||
for (ba = 0; ba < uptr->capac; ) { /* loop thru file */
|
for (ba = 0; ba < uptr->capac; ) { /* loop thru file */
|
||||||
k = fxread (pdp11b, sizeof (uint16), D18_BSIZE, uptr->fileref);
|
k = fxread (pdp11b, sizeof (uint16), D18_BSIZE, uptr->fileref);
|
||||||
if (k == 0)
|
if (k == 0)
|
||||||
|
@ -1213,8 +1223,7 @@ dtc_attach (UNIT *uptr, CONST char *cptr)
|
||||||
fbuf[ba++] = pdp11b[k];
|
fbuf[ba++] = pdp11b[k];
|
||||||
}
|
}
|
||||||
uptr->hwmark = ba;
|
uptr->hwmark = ba;
|
||||||
} /* end elif */
|
} else uptr->hwmark = fxread (uptr->filebuf, sizeof (uint32),
|
||||||
else uptr->hwmark = fxread (uptr->filebuf, sizeof (uint32),
|
|
||||||
uptr->capac, uptr->fileref);
|
uptr->capac, uptr->fileref);
|
||||||
uptr->flags = uptr->flags | UNIT_BUF; /* set buf flag */
|
uptr->flags = uptr->flags | UNIT_BUF; /* set buf flag */
|
||||||
uptr->pos = DT_EZLIN; /* beyond leader */
|
uptr->pos = DT_EZLIN; /* beyond leader */
|
||||||
|
@ -1230,23 +1239,15 @@ dtc_attach (UNIT *uptr, CONST char *cptr)
|
||||||
Deallocate buffer
|
Deallocate buffer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
t_stat
|
void
|
||||||
dtc_detach (UNIT* uptr)
|
dtc_flush (UNIT* uptr)
|
||||||
{
|
{
|
||||||
uint16 pdp8b[D8_NBSIZE];
|
uint16 pdp8b[D8_NBSIZE];
|
||||||
uint16 pdp11b[D18_BSIZE];
|
uint16 pdp11b[D18_BSIZE];
|
||||||
uint32 ba, k, *fbuf;
|
uint32 ba, k, *fbuf;
|
||||||
int32 u = uptr - dtc_dev.units;
|
|
||||||
|
|
||||||
if (!(uptr->flags & UNIT_ATT))
|
if (uptr->WRITTEN && uptr->hwmark && ((uptr->flags & UNIT_RO) == 0)) { /* any data? */
|
||||||
return SCPE_OK;
|
|
||||||
if (sim_is_active (uptr)) {
|
|
||||||
sim_cancel (uptr);
|
|
||||||
uptr->CMD = uptr->pos = 0;
|
|
||||||
}
|
|
||||||
fbuf = (uint32 *) uptr->filebuf; /* file buffer */
|
fbuf = (uint32 *) uptr->filebuf; /* file buffer */
|
||||||
if (uptr->hwmark && ((uptr->flags & UNIT_RO) == 0)) { /* any data? */
|
|
||||||
printf ("%s%d: writing buffer to file\n", sim_dname (&dtc_dev), u);
|
|
||||||
rewind (uptr->fileref); /* start of file */
|
rewind (uptr->fileref); /* start of file */
|
||||||
if (uptr->flags & UNIT_8FMT) { /* 12b? */
|
if (uptr->flags & UNIT_8FMT) { /* 12b? */
|
||||||
for (ba = 0; ba < uptr->hwmark; ) { /* loop thru file */
|
for (ba = 0; ba < uptr->hwmark; ) { /* loop thru file */
|
||||||
|
@ -1261,8 +1262,7 @@ dtc_detach (UNIT* uptr)
|
||||||
if (ferror (uptr->fileref))
|
if (ferror (uptr->fileref))
|
||||||
break;
|
break;
|
||||||
} /* end loop file */
|
} /* end loop file */
|
||||||
} /* end if 12b */
|
} else if (uptr->flags & UNIT_11FMT) { /* 16b? */
|
||||||
else if (uptr->flags & UNIT_11FMT) { /* 16b? */
|
|
||||||
for (ba = 0; ba < uptr->hwmark; ) { /* loop thru file */
|
for (ba = 0; ba < uptr->hwmark; ) { /* loop thru file */
|
||||||
for (k = 0; k < D18_BSIZE; k++) /* loop blk */
|
for (k = 0; k < D18_BSIZE; k++) /* loop blk */
|
||||||
pdp11b[k] = fbuf[ba++] & 0177777;
|
pdp11b[k] = fbuf[ba++] & 0177777;
|
||||||
|
@ -1270,11 +1270,28 @@ dtc_detach (UNIT* uptr)
|
||||||
if (ferror (uptr->fileref))
|
if (ferror (uptr->fileref))
|
||||||
break;
|
break;
|
||||||
} /* end loop file */
|
} /* end loop file */
|
||||||
} /* end if 16b */
|
} else fxwrite (uptr->filebuf, sizeof (uint32), /* write file */
|
||||||
else fxwrite (uptr->filebuf, sizeof (uint32), /* write file */
|
|
||||||
uptr->hwmark, uptr->fileref);
|
uptr->hwmark, uptr->fileref);
|
||||||
if (ferror (uptr->fileref))
|
if (ferror (uptr->fileref))
|
||||||
perror ("I/O error");
|
sim_perror ("I/O error");
|
||||||
|
uptr->WRITTEN = 0;
|
||||||
|
} /* end if hwmark */
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat
|
||||||
|
dtc_detach (UNIT* uptr)
|
||||||
|
{
|
||||||
|
int32 u = uptr - dtc_dev.units;
|
||||||
|
|
||||||
|
if (!(uptr->flags & UNIT_ATT))
|
||||||
|
return SCPE_OK;
|
||||||
|
if (sim_is_active (uptr)) {
|
||||||
|
sim_cancel (uptr);
|
||||||
|
uptr->CMD = uptr->pos = 0;
|
||||||
|
}
|
||||||
|
if (uptr->hwmark && ((uptr->flags & UNIT_RO) == 0)) { /* any data? */
|
||||||
|
sim_printf ("%s%d: writing buffer to file\n", sim_dname (&dtc_dev), u);
|
||||||
|
dtc_flush (uptr);
|
||||||
} /* end if hwmark */
|
} /* end if hwmark */
|
||||||
free (uptr->filebuf); /* release buf */
|
free (uptr->filebuf); /* release buf */
|
||||||
uptr->flags = uptr->flags & ~UNIT_BUF; /* clear buf flag */
|
uptr->flags = uptr->flags & ~UNIT_BUF; /* clear buf flag */
|
||||||
|
|
329
PDP10/pdp6_slave.c
Normal file
329
PDP10/pdp6_slave.c
Normal file
|
@ -0,0 +1,329 @@
|
||||||
|
/* 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, 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)
|
||||||
|
{
|
||||||
|
t_stat r;
|
||||||
|
|
||||||
|
if (!cptr || !*cptr)
|
||||||
|
return SCPE_ARG;
|
||||||
|
if (!(uptr->flags & UNIT_ATTABLE))
|
||||||
|
return SCPE_NOATT;
|
||||||
|
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];
|
||||||
|
t_addr 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, (uint8)(data & 0xff));
|
||||||
|
build (response, (uint8)((data >> 8)) & 0xff);
|
||||||
|
build (response, (uint8)((data >> 16) & 0xff));
|
||||||
|
build (response, (uint8)((data >> 24) & 0xff));
|
||||||
|
build (response, (uint8)((data >> 32) & 0xff));
|
||||||
|
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";
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
|
@ -82,7 +82,7 @@
|
||||||
|
|
||||||
#### Richard Cornwell has implemented the IBM 701, IBM 704, IBM 7010/1410, IBM 7070/7074, IBM 7080/702/705/7053 and IBM 7090/7094/709/704 simulators.
|
#### Richard Cornwell has implemented the IBM 701, IBM 704, IBM 7010/1410, IBM 7070/7074, IBM 7080/702/705/7053 and IBM 7090/7094/709/704 simulators.
|
||||||
|
|
||||||
#### Richard Cornwell has implemented the PDP6, PDP10-KA, and PDP10-KI simulators.
|
#### Richard Cornwell has implemented the PDP6, PDP10-KA, PDP10-KI and PDP10-KL simulators.
|
||||||
|
|
||||||
#### Dave Bryan has implemented an HP-3000 Series III simulator.
|
#### Dave Bryan has implemented an HP-3000 Series III simulator.
|
||||||
|
|
||||||
|
@ -229,7 +229,7 @@ Host platforms which have libSDL2 available can leverage this functionality.
|
||||||
RAW Disk Access (including CDROM)
|
RAW Disk Access (including CDROM)
|
||||||
Virtual Disk Container files, including differencing disks
|
Virtual Disk Container files, including differencing disks
|
||||||
File System type detection to accurately autosize disks.
|
File System type detection to accurately autosize disks.
|
||||||
Recognized file systems are: DEC ODS1, DEC ODS2, DEC RT11, Ultrix Partitions
|
Recognized file systems are: DEC ODS1, DEC ODS2, DEC RT11, DEC RSX11, Ultrix Partitions
|
||||||
|
|
||||||
#### Tape Extensions
|
#### Tape Extensions
|
||||||
AWS format tape support
|
AWS format tape support
|
||||||
|
@ -304,6 +304,9 @@ The following extensions to the SCP command language without affecting prior beh
|
||||||
Restores the default CTRL+C behavior for the
|
Restores the default CTRL+C behavior for the
|
||||||
currently running command procedure.
|
currently running command procedure.
|
||||||
|
|
||||||
|
DO <stdin>
|
||||||
|
Invokes a nested DO command with input from the
|
||||||
|
running console.
|
||||||
|
|
||||||
Error traps can be taken for any command which returns a status other than SCPE_STEP, SCPE_OK, and SCPE_EXIT.
|
Error traps can be taken for any command which returns a status other than SCPE_STEP, SCPE_OK, and SCPE_EXIT.
|
||||||
|
|
||||||
|
@ -541,6 +544,7 @@ Different Linux distributions have different package management systems:
|
||||||
Ubuntu:
|
Ubuntu:
|
||||||
|
|
||||||
# apt-get install libpcap-dev
|
# apt-get install libpcap-dev
|
||||||
|
# apt-get install libpcre3-dev
|
||||||
# apt-get install vde2
|
# apt-get install vde2
|
||||||
# apt-get install libsdl2
|
# apt-get install libsdl2
|
||||||
# apt-get install libsdl2_ttf
|
# apt-get install libsdl2_ttf
|
||||||
|
|
|
@ -213,6 +213,10 @@
|
||||||
RelativePath="..\PDP10\ka10_dpk.c"
|
RelativePath="..\PDP10\ka10_dpk.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\PDP10\ka10_iii.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\PDP10\ka10_imx.c"
|
RelativePath="..\PDP10\ka10_imx.c"
|
||||||
>
|
>
|
||||||
|
@ -265,6 +269,10 @@
|
||||||
RelativePath="..\PDP10\kx10_df.c"
|
RelativePath="..\PDP10\kx10_df.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\PDP10\kx10_disk.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\PDP10\kx10_dk.c"
|
RelativePath="..\PDP10\kx10_dk.c"
|
||||||
>
|
>
|
||||||
|
@ -301,6 +309,10 @@
|
||||||
RelativePath="..\PDP10\kx10_rc.c"
|
RelativePath="..\PDP10\kx10_rc.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\PDP10\kx10_rh.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\PDP10\kx10_rp.c"
|
RelativePath="..\PDP10\kx10_rp.c"
|
||||||
>
|
>
|
||||||
|
@ -419,6 +431,10 @@
|
||||||
RelativePath="..\display\display.h"
|
RelativePath="..\display\display.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\display\iii.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\display\sim_ws.c"
|
RelativePath="..\display\sim_ws.c"
|
||||||
>
|
>
|
||||||
|
@ -601,10 +617,18 @@
|
||||||
Name="Header Files"
|
Name="Header Files"
|
||||||
Filter="h;hpp;hxx;hm;inl;inc"
|
Filter="h;hpp;hxx;hm;inl;inc"
|
||||||
>
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\display\iii.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\PDP10\kx10_defs.h"
|
RelativePath="..\PDP10\kx10_defs.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\PDP10\kx10_disk.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\scp.h"
|
RelativePath="..\scp.h"
|
||||||
>
|
>
|
||||||
|
|
|
@ -217,6 +217,10 @@
|
||||||
RelativePath="..\PDP10\kx10_df.c"
|
RelativePath="..\PDP10\kx10_df.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\PDP10\kx10_disk.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\PDP10\kx10_dk.c"
|
RelativePath="..\PDP10\kx10_dk.c"
|
||||||
>
|
>
|
||||||
|
@ -253,6 +257,10 @@
|
||||||
RelativePath="..\PDP10\kx10_rc.c"
|
RelativePath="..\PDP10\kx10_rc.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\PDP10\kx10_rh.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\PDP10\kx10_rp.c"
|
RelativePath="..\PDP10\kx10_rp.c"
|
||||||
>
|
>
|
||||||
|
@ -537,6 +545,10 @@
|
||||||
RelativePath="..\PDP10\kx10_defs.h"
|
RelativePath="..\PDP10\kx10_defs.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\PDP10\kx10_disk.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\scp.h"
|
RelativePath="..\scp.h"
|
||||||
>
|
>
|
||||||
|
|
573
Visual Studio Projects/PDP10-KL.vcproj
Normal file
573
Visual Studio Projects/PDP10-KL.vcproj
Normal file
|
@ -0,0 +1,573 @@
|
||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="9.00"
|
||||||
|
Name="PDP10-KL"
|
||||||
|
ProjectGUID="{DA2AA7A0-B679-456B-B152-DEF40FAE5A7A}"
|
||||||
|
RootNamespace="PDP10-KL"
|
||||||
|
Keyword="Win32Proj"
|
||||||
|
TargetFrameworkVersion="131072"
|
||||||
|
>
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"
|
||||||
|
/>
|
||||||
|
</Platforms>
|
||||||
|
<ToolFiles>
|
||||||
|
</ToolFiles>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="0"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
Description="Check for required build dependencies & git commit id"
|
||||||
|
CommandLine="Pre-Build-Event.cmd "$(TargetDir)$(TargetName).exe" LIBPCRE BUILD LIBSDL"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="../PDP10;.;..;../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include;../../windows-build/include;;../../windows-build/include/SDL2"
|
||||||
|
PreprocessorDefinitions="USE_INT64;USE_SIM_CARD;KL=1;USE_SHARED;HAVE_SLIRP_NETWORK;USE_SIMH_SLIRP_DEBUG;SIM_BUILD_TOOL=simh-Visual-Studio-Project;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID;HAVE_PCRE_H;PCRE_STATIC"
|
||||||
|
KeepComments="false"
|
||||||
|
BasicRuntimeChecks="0"
|
||||||
|
RuntimeLibrary="1"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
CompileAs="1"
|
||||||
|
ShowIncludes="false"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalOptions="/fixed:no"
|
||||||
|
AdditionalDependencies="libcmtd.lib wsock32.lib winmm.lib Iphlpapi.lib pcrestaticd.lib zlib.lib dxguid.lib Imm32.lib Version.lib"
|
||||||
|
LinkIncremental="1"
|
||||||
|
AdditionalLibraryDirectories="../../windows-build/lib/Debug/"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="1"
|
||||||
|
StackReserveSize="10485760"
|
||||||
|
StackCommitSize="10485760"
|
||||||
|
RandomizedBaseAddress="1"
|
||||||
|
DataExecutionPrevention="0"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
Description="Running Available Tests"
|
||||||
|
CommandLine="Post-Build-Event.cmd PDP10 "$(TargetDir)$(TargetName).exe""
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="0"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
Description="Check for required build dependencies & git commit id"
|
||||||
|
CommandLine="Pre-Build-Event.cmd "$(TargetDir)$(TargetName).exe" LIBPCRE BUILD LIBSDL"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
InlineFunctionExpansion="1"
|
||||||
|
OmitFramePointers="true"
|
||||||
|
WholeProgramOptimization="true"
|
||||||
|
AdditionalIncludeDirectories="../PDP10;.;..;../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include;../../windows-build/include;;../../windows-build/include/SDL2"
|
||||||
|
PreprocessorDefinitions="USE_INT64;USE_SIM_CARD;KL=1;USE_SHARED;HAVE_SLIRP_NETWORK;USE_SIMH_SLIRP_DEBUG;SIM_BUILD_TOOL=simh-Visual-Studio-Project;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID;HAVE_PCRE_H;PCRE_STATIC"
|
||||||
|
StringPooling="true"
|
||||||
|
RuntimeLibrary="0"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
CompileAs="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalOptions="/fixed:no"
|
||||||
|
AdditionalDependencies="libcmtd.lib wsock32.lib winmm.lib Iphlpapi.lib pcrestaticd.lib zlib.lib dxguid.lib Imm32.lib Version.lib"
|
||||||
|
LinkIncremental="1"
|
||||||
|
AdditionalLibraryDirectories="../../windows-build/lib/Release/"
|
||||||
|
GenerateDebugInformation="false"
|
||||||
|
SubSystem="1"
|
||||||
|
StackReserveSize="10485760"
|
||||||
|
StackCommitSize="10485760"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
LinkTimeCodeGeneration="1"
|
||||||
|
RandomizedBaseAddress="1"
|
||||||
|
DataExecutionPrevention="0"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
Description="Running Available Tests"
|
||||||
|
CommandLine="Post-Build-Event.cmd PDP10 "$(TargetDir)$(TargetName).exe""
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="Source Files"
|
||||||
|
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\PDP10\ka10_ch10.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\PDP10\ka10_pd.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\PDP10\kl10_fe.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\PDP10\kl10_nia.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\PDP10\kx10_cpu.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\PDP10\kx10_dc.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\PDP10\kx10_df.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\PDP10\kx10_disk.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\PDP10\kx10_imp.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\PDP10\kx10_lp.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\PDP10\kx10_mt.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\PDP10\kx10_rh.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\PDP10\kx10_rp.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\PDP10\kx10_rs.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\PDP10\kx10_sys.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\PDP10\kx10_tu.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\windows-build\pthreads\pthread.c"
|
||||||
|
>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
PreprocessorDefinitions="HAVE_CONFIG_H;PTW32_BUILD_INLINED;PTW32_STATIC_LIB;__CLEANUP_C;$(NOINHERIT)"
|
||||||
|
CompileAs="1"
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Release|Win32"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
WholeProgramOptimization="false"
|
||||||
|
PreprocessorDefinitions="HAVE_CONFIG_H;PTW32_BUILD_INLINED;PTW32_STATIC_LIB;__CLEANUP_C;$(NOINHERIT)"
|
||||||
|
CompileAs="1"
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\scp.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sim_card.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sim_console.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sim_disk.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sim_ether.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sim_fio.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sim_serial.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sim_sock.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sim_tape.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sim_timer.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sim_tmxr.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sim_video.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<Filter
|
||||||
|
Name="slirp"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\arp_table.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\bootp.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\bootp.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\cksum.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\debug.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\dnssearch.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp_glue\glib_qemu_stubs.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\if.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\if.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\ip.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\ip_icmp.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\ip_icmp.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\ip_input.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\ip_output.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\libslirp.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\main.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\mbuf.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\mbuf.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\misc.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\misc.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\sbuf.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\sbuf.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp_glue\sim_slirp.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\slirp.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\slirp.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\slirp_config.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\socket.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\socket.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\tcp.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\tcp_input.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\tcp_output.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\tcp_subr.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\tcp_timer.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\tcp_timer.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\tcp_var.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\tcpip.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\tftp.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\tftp.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\udp.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\slirp\udp.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Header Files"
|
||||||
|
Filter="h;hpp;hxx;hm;inl;inc"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\PDP10\kx10_defs.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\PDP10\kx10_disk.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\scp.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sim_card.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sim_console.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sim_defs.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sim_disk.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sim_ether.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sim_fio.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sim_rev.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sim_serial.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sim_sock.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sim_tape.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sim_timer.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sim_tmxr.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sim_video.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Resource Files"
|
||||||
|
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||||
|
>
|
||||||
|
</Filter>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
|
@ -245,6 +245,10 @@
|
||||||
RelativePath="..\PDP10\pdp6_mtc.c"
|
RelativePath="..\PDP10\pdp6_mtc.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\PDP10\pdp6_slave.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\windows-build\pthreads\pthread.c"
|
RelativePath="..\..\windows-build\pthreads\pthread.c"
|
||||||
>
|
>
|
||||||
|
|
|
@ -398,6 +398,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "imds-810", "imds-810.vcproj
|
||||||
{D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8}
|
{D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8}
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PDP10-KL", "PDP10-KL.vcproj", "{DA2AA7A0-B679-456B-B152-DEF40FAE5A7A}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Win32 = Debug|Win32
|
Debug|Win32 = Debug|Win32
|
||||||
|
@ -724,6 +726,10 @@ Global
|
||||||
{0720F164-692E-4C07-BE69-41C4302062E5}.Debug|Win32.Build.0 = Debug|Win32
|
{0720F164-692E-4C07-BE69-41C4302062E5}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
{0720F164-692E-4C07-BE69-41C4302062E5}.Release|Win32.ActiveCfg = Release|Win32
|
{0720F164-692E-4C07-BE69-41C4302062E5}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
{0720F164-692E-4C07-BE69-41C4302062E5}.Release|Win32.Build.0 = Release|Win32
|
{0720F164-692E-4C07-BE69-41C4302062E5}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{DA2AA7A0-B679-456B-B152-DEF40FAE5A7A}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{DA2AA7A0-B679-456B-B152-DEF40FAE5A7A}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{DA2AA7A0-B679-456B-B152-DEF40FAE5A7A}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{DA2AA7A0-B679-456B-B152-DEF40FAE5A7A}.Release|Win32.Build.0 = Release|Win32
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
BIN
doc/ka10_doc.doc
BIN
doc/ka10_doc.doc
Binary file not shown.
BIN
doc/ki10_doc.doc
BIN
doc/ki10_doc.doc
Binary file not shown.
BIN
doc/kl10_doc.doc
Normal file
BIN
doc/kl10_doc.doc
Normal file
Binary file not shown.
35
makefile
35
makefile
|
@ -587,6 +587,7 @@ ifeq (${WIN32},) #*nix Environments (&& cygwin)
|
||||||
DISPLAYVT = ${DISPLAYD}/vt11.c
|
DISPLAYVT = ${DISPLAYD}/vt11.c
|
||||||
DISPLAY340 = ${DISPLAYD}/type340.c
|
DISPLAY340 = ${DISPLAYD}/type340.c
|
||||||
DISPLAYNG = ${DISPLAYD}/ng.c
|
DISPLAYNG = ${DISPLAYD}/ng.c
|
||||||
|
DISPLAYIII = ${DISPLAYD}/iii.c
|
||||||
DISPLAY_OPT += -DUSE_DISPLAY $(VIDEO_CCDEFS) $(VIDEO_LDFLAGS)
|
DISPLAY_OPT += -DUSE_DISPLAY $(VIDEO_CCDEFS) $(VIDEO_LDFLAGS)
|
||||||
$(info using libSDL2: $(call find_include,SDL2/SDL))
|
$(info using libSDL2: $(call find_include,SDL2/SDL))
|
||||||
ifeq (Darwin,$(OSTYPE))
|
ifeq (Darwin,$(OSTYPE))
|
||||||
|
@ -1994,7 +1995,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_lp.c ${PDP6D}/kx10_pt.c ${PDP6D}/kx10_cr.c \
|
||||||
${PDP6D}/kx10_cp.c ${PDP6D}/pdp6_dct.c ${PDP6D}/pdp6_dtc.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}/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}
|
PDP6_OPT = -DPDP6=1 -DUSE_INT64 -I ${PDP6D} -DUSE_SIM_CARD ${DISPLAY_OPT} ${PDP6_DISPLAY_OPT}
|
||||||
|
|
||||||
KA10D = ${SIMHD}/PDP10
|
KA10D = ${SIMHD}/PDP10
|
||||||
|
@ -2007,13 +2008,14 @@ KA10 = ${KA10D}/kx10_cpu.c ${KA10D}/kx10_sys.c ${KA10D}/kx10_df.c \
|
||||||
${KA10D}/kx10_rp.c ${KA10D}/kx10_rc.c ${KA10D}/kx10_dt.c \
|
${KA10D}/kx10_rp.c ${KA10D}/kx10_rc.c ${KA10D}/kx10_dt.c \
|
||||||
${KA10D}/kx10_dk.c ${KA10D}/kx10_cr.c ${KA10D}/kx10_cp.c \
|
${KA10D}/kx10_dk.c ${KA10D}/kx10_cr.c ${KA10D}/kx10_cp.c \
|
||||||
${KA10D}/kx10_tu.c ${KA10D}/kx10_rs.c ${KA10D}/ka10_pd.c \
|
${KA10D}/kx10_tu.c ${KA10D}/kx10_rs.c ${KA10D}/ka10_pd.c \
|
||||||
${KA10D}/kx10_imp.c ${KA10D}/ka10_tk10.c ${KA10D}/ka10_mty.c \
|
${KA10D}/kx10_rh.c ${KA10D}/kx10_imp.c ${KA10D}/ka10_tk10.c \
|
||||||
${KA10D}/ka10_imx.c ${KA10D}/ka10_ch10.c ${KA10D}/ka10_stk.c \
|
${KA10D}/ka10_mty.c ${KA10D}/ka10_imx.c ${KA10D}/ka10_ch10.c \
|
||||||
${KA10D}/ka10_ten11.c ${KA10D}/ka10_auxcpu.c ${KA10D}/ka10_pmp.c \
|
${KA10D}/ka10_stk.c ${KA10D}/ka10_ten11.c ${KA10D}/ka10_auxcpu.c \
|
||||||
${KA10D}/ka10_dkb.c ${KA10D}/pdp6_dct.c ${KA10D}/pdp6_dtc.c \
|
$(KA10D)/ka10_pmp.c ${KA10D}/ka10_dkb.c ${KA10D}/pdp6_dct.c \
|
||||||
${KA10D}/pdp6_mtc.c ${KA10D}/pdp6_dsk.c ${KA10D}/pdp6_dcs.c \
|
${KA10D}/pdp6_dtc.c ${KA10D}/pdp6_mtc.c ${KA10D}/pdp6_dsk.c \
|
||||||
${KA10D}/ka10_dpk.c ${KA10D}/kx10_dpy.c ${PDP10D}/ka10_ai.c \
|
${KA10D}/pdp6_dcs.c ${KA10D}/ka10_dpk.c ${KA10D}/kx10_dpy.c \
|
||||||
${DISPLAYL} ${DISPLAY340}
|
${PDP10D}/ka10_ai.c ${KA10D}/ka10_iii.c ${KA10D}/kx10_disk.c \
|
||||||
|
${DISPLAYL} ${DISPLAY340} ${DISPLAYIII}
|
||||||
KA10_OPT = -DKA=1 -DUSE_INT64 -I ${KA10D} -DUSE_SIM_CARD ${NETWORK_OPT} ${DISPLAY_OPT} ${KA10_DISPLAY_OPT}
|
KA10_OPT = -DKA=1 -DUSE_INT64 -I ${KA10D} -DUSE_SIM_CARD ${NETWORK_OPT} ${DISPLAY_OPT} ${KA10_DISPLAY_OPT}
|
||||||
ifneq (${PANDA_LIGHTS},)
|
ifneq (${PANDA_LIGHTS},)
|
||||||
# ONLY for Panda display.
|
# ONLY for Panda display.
|
||||||
|
@ -2029,10 +2031,11 @@ endif
|
||||||
KI10 = ${KI10D}/kx10_cpu.c ${KI10D}/kx10_sys.c ${KI10D}/kx10_df.c \
|
KI10 = ${KI10D}/kx10_cpu.c ${KI10D}/kx10_sys.c ${KI10D}/kx10_df.c \
|
||||||
${KI10D}/kx10_dp.c ${KI10D}/kx10_mt.c ${KI10D}/kx10_cty.c \
|
${KI10D}/kx10_dp.c ${KI10D}/kx10_mt.c ${KI10D}/kx10_cty.c \
|
||||||
${KI10D}/kx10_lp.c ${KI10D}/kx10_pt.c ${KI10D}/kx10_dc.c \
|
${KI10D}/kx10_lp.c ${KI10D}/kx10_pt.c ${KI10D}/kx10_dc.c \
|
||||||
${KI10D}/kx10_rp.c ${KI10D}/kx10_rc.c ${KI10D}/kx10_dt.c \
|
${KI10D}/kx10_rh.c ${KI10D}/kx10_rp.c ${KI10D}/kx10_rc.c \
|
||||||
${KI10D}/kx10_dk.c ${KI10D}/kx10_cr.c ${KI10D}/kx10_cp.c \
|
${KI10D}/kx10_dt.c ${KI10D}/kx10_dk.c ${KI10D}/kx10_cr.c \
|
||||||
${KI10D}/kx10_tu.c ${KI10D}/kx10_rs.c ${KI10D}/kx10_imp.c \
|
${KI10D}/kx10_cp.c ${KI10D}/kx10_tu.c ${KI10D}/kx10_rs.c \
|
||||||
${KI10D}/kx10_dpy.c ${DISPLAYL} ${DISPLAY340}
|
${KI10D}/kx10_imp.c ${KI10D}/kx10_dpy.c ${KI10D}/kx10_disk.c \
|
||||||
|
${DISPLAYL} ${DISPLAY340}
|
||||||
KI10_OPT = -DKI=1 -DUSE_INT64 -I ${KI10D} -DUSE_SIM_CARD ${NETWORK_OPT} ${DISPLAY_OPT} ${KI10_DISPLAY_OPT}
|
KI10_OPT = -DKI=1 -DUSE_INT64 -I ${KI10D} -DUSE_SIM_CARD ${NETWORK_OPT} ${DISPLAY_OPT} ${KI10_DISPLAY_OPT}
|
||||||
ifneq (${PANDA_LIGHTS},)
|
ifneq (${PANDA_LIGHTS},)
|
||||||
# ONLY for Panda display.
|
# ONLY for Panda display.
|
||||||
|
@ -2041,12 +2044,13 @@ KI10 += ${KA10D}/ka10_lights.c
|
||||||
KI10_LDFLAGS = -lusb-1.0
|
KI10_LDFLAGS = -lusb-1.0
|
||||||
endif
|
endif
|
||||||
|
|
||||||
KL10D = PDP10
|
KL10D = ${SIMHD}/PDP10
|
||||||
KL10 = ${KL10D}/kx10_cpu.c ${KL10D}/kx10_sys.c ${KL10D}/kx10_df.c \
|
KL10 = ${KL10D}/kx10_cpu.c ${KL10D}/kx10_sys.c ${KL10D}/kx10_df.c \
|
||||||
${KL10D}/kx10_mt.c ${KL10D}/kx10_dc.c ${KL10D}/kx10_rh.c \
|
${KL10D}/kx10_mt.c ${KL10D}/kx10_dc.c ${KL10D}/kx10_rh.c \
|
||||||
${KL10D}/kx10_rp.c ${KL10D}/kx10_tu.c ${KL10D}/kx10_rs.c \
|
${KL10D}/kx10_rp.c ${KL10D}/kx10_tu.c ${KL10D}/kx10_rs.c \
|
||||||
${KL10D}/kx10_imp.c ${KL10D}/kl10_fe.c ${KL10D}/ka10_pd.c \
|
${KL10D}/kx10_imp.c ${KL10D}/kl10_fe.c ${KL10D}/ka10_pd.c \
|
||||||
${KL10D}/ka10_ch10.c ${KL10D}/kx10_lp.c
|
${KL10D}/ka10_ch10.c ${KL10D}/kx10_lp.c ${KL10D}/kl10_nia.c \
|
||||||
|
${KL10D}/kx10_disk.c
|
||||||
KL10_OPT = -DKL=1 -DUSE_INT64 -I $(KL10D) -DUSE_SIM_CARD ${NETWORK_OPT}
|
KL10_OPT = -DKL=1 -DUSE_INT64 -I $(KL10D) -DUSE_SIM_CARD ${NETWORK_OPT}
|
||||||
|
|
||||||
ATT3B2D = ${SIMHD}/3B2
|
ATT3B2D = ${SIMHD}/3B2
|
||||||
|
@ -2121,7 +2125,7 @@ ALL = pdp1 pdp4 pdp7 pdp8 pdp9 pdp15 pdp11 pdp10 \
|
||||||
swtp6800mp-a swtp6800mp-a2 tx-0 ssem b5500 isys8010 isys8020 \
|
swtp6800mp-a swtp6800mp-a2 tx-0 ssem b5500 isys8010 isys8020 \
|
||||||
isys8030 isys8024 imds-210 imds-220 imds-225 imds-230 imds-800 imds-810 \
|
isys8030 isys8024 imds-210 imds-220 imds-225 imds-230 imds-800 imds-810 \
|
||||||
scelbi 3b2 i701 i704 i7010 i7070 i7080 i7090 \
|
scelbi 3b2 i701 i704 i7010 i7070 i7080 i7090 \
|
||||||
sigma uc15 pdp10-ka pdp10-ki pdp6
|
sigma uc15 pdp10-ka pdp10-ki pdp10-kl pdp6
|
||||||
|
|
||||||
all : ${ALL}
|
all : ${ALL}
|
||||||
|
|
||||||
|
@ -2921,7 +2925,6 @@ endif
|
||||||
pdp10-kl : ${BIN}pdp10-kl${EXE}
|
pdp10-kl : ${BIN}pdp10-kl${EXE}
|
||||||
|
|
||||||
${BIN}pdp10-kl${EXE} : ${KL10} ${SIM}
|
${BIN}pdp10-kl${EXE} : ${KL10} ${SIM}
|
||||||
#cmake:ignore-target
|
|
||||||
${MKDIRBIN}
|
${MKDIRBIN}
|
||||||
${CC} ${KL10} ${SIM} ${KL10_OPT} ${CC_OUTSPEC} ${LDFLAGS}
|
${CC} ${KL10} ${SIM} ${KL10_OPT} ${CC_OUTSPEC} ${LDFLAGS}
|
||||||
ifneq (,$(call find_test,${PDP10D},kl10))
|
ifneq (,$(call find_test,${PDP10D},kl10))
|
||||||
|
|
Loading…
Add table
Reference in a new issue