VAX750: Fixed ROM based boot from console TU58

Problem was the console storage output buffer was masked with a WMASK instead of a BMASK (it is only a 8 bit register).
Also, the input interrupt processing cleared the output interrupt state instead of the input interrupt state.  This would only be a problem when interrupts are actually used instead of polled I/O.
This commit is contained in:
Mark Pizzolato 2015-09-17 17:48:02 -07:00
parent 42403efd1f
commit 0986c6ff9e
3 changed files with 178 additions and 19 deletions

View file

@ -85,6 +85,41 @@
#define CSTS_RD (CSR_DONE + CSR_IE + CSTS_BRK) /* terminal output */ #define CSTS_RD (CSR_DONE + CSR_IE + CSTS_BRK) /* terminal output */
#define CSTS_WR (CSR_IE + CSTS_BRK) #define CSTS_WR (CSR_IE + CSTS_BRK)
static BITFIELD rx_csr_bits[] = {
BITNCF(6), /* unused */
BIT(IE), /* Interrupt Enable */
BIT(DONE), /* Xmit Ready */
BITNCF(8), /* unused */
ENDBITS
};
static BITFIELD rx_buf_bits[] = {
BITF(DAT,8), /* data buffer */
BITNCF(5), /* unused */
BIT(RBRK),
BIT(OVR),
BIT(ERR),
ENDBITS
};
static BITFIELD tx_csr_bits[] = {
BIT(XBR), /* Break */
BITNC, /* unused */
BIT(MAINT), /* Maint */
BITNCF(3), /* unused */
BIT(IE), /* Interrupt Enable */
BIT(DONE), /* Xmit Ready */
BITNCF(8), /* unused */
ENDBITS
};
static BITFIELD tx_buf_bits[] = {
BITF(DAT,8), /* data buffer */
BITNCF(8), /* unused */
ENDBITS
};
/* Clock definitions */ /* Clock definitions */
#define TMR_CSR_ERR 0x80000000 /* error W1C */ #define TMR_CSR_ERR 0x80000000 /* error W1C */
@ -156,6 +191,18 @@
#define TD_END1 8 /* empty buffer */ #define TD_END1 8 /* empty buffer */
#define TD_INIT 9 /* empty buffer */ #define TD_INIT 9 /* empty buffer */
static char *td_states[] = {
"IDLE", "READ", "READ1", "READ2", "WRITE", "WRITE1", "WRITE2", "END", "END1", "INIT"
};
static char *td_ops[] = {
"NOP", "INI", "RD", "WR", "POS", "DIA", "GST", "SST", "MRSP"
};
static char *td_csostates[] = {
"GETOPC", "GETLEN", "GETDATA"
};
int32 tti_csr = 0; /* control/status */ int32 tti_csr = 0; /* control/status */
uint32 tti_buftime; /* time input character arrived */ uint32 tti_buftime; /* time input character arrived */
int32 tti_buf = 0; /* buffer */ int32 tti_buf = 0; /* buffer */
@ -382,12 +429,39 @@ MTAB td_mod[] = {
{ 0 } { 0 }
}; };
/* Debug detail levels */
#define TDDEB_OPS 00001 /* transactions */
#define TDDEB_IRD 00002 /* input reg reads */
#define TDDEB_ORD 00004 /* output reg reads */
#define TDDEB_RRD 00006 /* reg reads */
#define TDDEB_IWR 00010 /* input reg writes */
#define TDDEB_OWR 00020 /* output reg writes */
#define TDDEB_RWR 00030 /* reg writes */
#define TDDEB_TRC 00040 /* trace */
#define TDDEB_INT 00100 /* interrupts */
#define TDDEB_PKT 00200 /* packet */
DEBTAB td_deb[] = {
{ "OPS", TDDEB_OPS, "transactions" },
{ "PKT", TDDEB_PKT, "packet" },
{ "RRD", TDDEB_RRD, "reg reads"},
{ "IRD", TDDEB_IRD, "input reg reads" },
{ "ORD", TDDEB_ORD, "output reg reads" },
{ "RWR", TDDEB_RWR, "reg writes" },
{ "IWR", TDDEB_IWR, "input reg writes" },
{ "OWR", TDDEB_OWR, "output reg writes" },
{ "INT", TDDEB_INT, "interrupts" },
{ "TRC", TDDEB_TRC, "trace" },
{ NULL, 0 }
};
DEVICE td_dev = { DEVICE td_dev = {
"TD", &td_unit, td_reg, td_mod, "TD", &td_unit, td_reg, td_mod,
1, DEV_RDX, 20, 1, DEV_RDX, 8, 1, DEV_RDX, 20, 1, DEV_RDX, 8,
NULL, NULL, &td_reset, NULL, NULL, &td_reset,
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, DEV_DEBUG, 0, td_deb, NULL, NULL, NULL, NULL, NULL,
&td_description &td_description
}; };
@ -401,15 +475,23 @@ DEVICE td_dev = {
int32 csrs_rd (void) int32 csrs_rd (void)
{ {
sim_debug(TDDEB_IRD, &td_dev, "csrs_rd()\n");
sim_debug_bits_hdr(TDDEB_IRD, &td_dev, "RX_CSR", rx_csr_bits, csi_csr, csi_csr, 1);
return (csi_csr & RXCS_RD); return (csi_csr & RXCS_RD);
} }
void csrs_wr (int32 data) void csrs_wr (int32 data)
{ {
if ((data & CSR_IE) == 0) sim_debug(TDDEB_IWR, &td_dev, "csrs_wr()\n");
cso_int = 0; sim_debug_bits_hdr(TDDEB_IWR, &td_dev, "RX_CSR", rx_csr_bits, data, data, 1);
else if ((csi_csr & (CSR_DONE + CSR_IE)) == CSR_DONE) if ((data & CSR_IE) == 0) {
csi_int = 0;
sim_debug (TDDEB_INT, &td_dev, "CSI_INT(0)\n");
}
else if ((csi_csr & (CSR_DONE + CSR_IE)) == CSR_DONE) {
csi_int = 1; csi_int = 1;
sim_debug (TDDEB_INT, &td_dev, "CSI_INT(1)\n");
}
csi_csr = (csi_csr & ~RXCS_WR) | (data & RXCS_WR); csi_csr = (csi_csr & ~RXCS_WR) | (data & RXCS_WR);
return; return;
} }
@ -418,37 +500,57 @@ int32 csrd_rd (void)
{ {
int32 t = csi_buf; /* char + error */ int32 t = csi_buf; /* char + error */
sim_debug(TDDEB_IRD, &td_dev, "csrd_rd()\n");
sim_debug_bits_hdr(TDDEB_IRD, &td_dev, "RX_BUF", rx_buf_bits, t, t, 1);
csi_csr = csi_csr & ~CSR_DONE; /* clr done */ csi_csr = csi_csr & ~CSR_DONE; /* clr done */
csi_buf = csi_buf & BMASK; /* clr errors */ csi_buf = csi_buf & BMASK; /* clr errors */
csi_int = 0; if (csi_int) {
csi_int = 0;
sim_debug (TDDEB_INT, &td_dev, "CSI_INT(0)\n");
}
return t; return t;
} }
int32 csts_rd (void) int32 csts_rd (void)
{ {
sim_debug(TDDEB_ORD, &td_dev, "csts_rd()\n");
sim_debug_bits_hdr(TDDEB_ORD, &td_dev, "TX_CSR", tx_csr_bits, cso_csr, cso_csr, 1);
return (cso_csr & TXCS_RD); return (cso_csr & TXCS_RD);
} }
void csts_wr (int32 data) void csts_wr (int32 data)
{ {
sim_debug(TDDEB_OWR, &td_dev, "csts_wr()\n");
sim_debug_bits_hdr(TDDEB_OWR, &td_dev, "TX_CSR", tx_csr_bits, data, data, 1);
if ((cso_csr & CSTS_BRK) && !(data & CSTS_BRK)) { if ((cso_csr & CSTS_BRK) && !(data & CSTS_BRK)) {
td_ibptr = 0; td_ibptr = 0;
td_ibuf[td_ibptr++] = TD_OPINI; td_ibuf[td_ibptr++] = TD_OPINI;
td_process_packet(); /* check packet */ td_process_packet(); /* check packet */
} }
if ((data & CSR_IE) == 0) if ((data & CSR_IE) == 0) {
cso_int = 0; if (cso_int) {
else if ((cso_csr & (CSR_DONE + CSR_IE)) == CSR_DONE) cso_int = 0;
sim_debug (TDDEB_INT, &td_dev, "CSO_INT(0)\n");
}
}
else if ((cso_csr & (CSR_DONE + CSR_IE)) == CSR_DONE) {
cso_int = 1; cso_int = 1;
sim_debug (TDDEB_INT, &td_dev, "CSO_INT(1)\n");
}
cso_csr = (cso_csr & ~CSTS_WR) | (data & CSTS_WR); cso_csr = (cso_csr & ~CSTS_WR) | (data & CSTS_WR);
return; return;
} }
void cstd_wr (int32 data) void cstd_wr (int32 data)
{ {
cso_buf = data & WMASK; /* save data */ sim_debug(TDDEB_OWR, &td_dev, "cstd_wr() state=%s, ibptr=%d, ilen=%d\n", td_csostates[cso_state], td_ibptr, td_ilen);
sim_debug_bits_hdr(TDDEB_OWR, &td_dev, "TX_BUF", tx_buf_bits, data, data, 1);
cso_buf = data & BMASK; /* save data */
cso_csr = cso_csr & ~CSR_DONE; /* clear flag */ cso_csr = cso_csr & ~CSR_DONE; /* clear flag */
cso_int = 0; /* clear int */ if (cso_int) {
cso_int = 0; /* clear int */
sim_debug (TDDEB_INT, &td_dev, "CSO_INT(0)\n");
}
switch (cso_state) { switch (cso_state) {
@ -474,15 +576,41 @@ switch (cso_state) {
} }
cso_csr = cso_csr | CSR_DONE; /* set input flag */ cso_csr = cso_csr | CSR_DONE; /* set input flag */
if (cso_csr & CSR_IE) if (cso_csr & CSR_IE) {
cso_int = 1; cso_int = 1;
sim_debug (TDDEB_INT, &td_dev, "CSO_INT(1)\n");
}
return; return;
} }
void td_process_packet() void td_process_packet()
{ {
int32 opcode = td_ibuf[0]; int32 opcode = td_ibuf[0];
char *opcode_name, *command_name;
switch (opcode) {
case TD_OPDAT:
opcode_name = "OPDAT";
break;
case TD_OPCMD:
opcode_name = "OPCMD";
break;
case TD_OPINI:
opcode_name = "OPINI";
break;
case TD_OPBOO:
opcode_name = "OPBOO";
break;
case TD_OPCNT:
opcode_name = "OPCNT";
break;
case TD_OPXOF:
opcode_name = "OPXOF";
break;
default:
opcode_name = "unknown";
}
sim_debug (TDDEB_TRC, &td_dev, "td_process_packet() Opcode=%s(%d)\n", opcode_name, opcode);
switch (opcode) { switch (opcode) {
case TD_OPDAT: case TD_OPDAT:
@ -507,6 +635,11 @@ switch (opcode) {
cso_state = TD_GETLEN; /* get rest of packet */ cso_state = TD_GETLEN; /* get rest of packet */
return; return;
} }
if (td_ibuf[2] == TD_CMDEND)
command_name = "END";
else
command_name = td_ops[td_ibuf[2]];
sim_debug (TDDEB_OPS, &td_dev, "strt: fnc=%d(%s), block=%d, size=%d\n", td_ibuf[2], command_name, ((td_ibuf[11] << 8) | td_ibuf[10]), ((td_ibuf[9] << 8) | td_ibuf[8]));
switch (td_ibuf[2]) { switch (td_ibuf[2]) {
case TD_CMDNOP: /* NOP */ case TD_CMDNOP: /* NOP */
case TD_CMDGST: /* Get status */ case TD_CMDGST: /* Get status */
@ -526,6 +659,8 @@ switch (opcode) {
td_txsize = ((td_ibuf[9] << 8) | td_ibuf[8]); td_txsize = ((td_ibuf[9] << 8) | td_ibuf[8]);
td_state = TD_READ; td_state = TD_READ;
td_offset = 0; td_offset = 0;
if (td_block == 0)
td_block = td_block;
sim_activate (&td_unit, td_cwait); /* sched command */ sim_activate (&td_unit, td_cwait); /* sched command */
break; break;
@ -548,8 +683,10 @@ switch (opcode) {
case TD_CMDMRSP: case TD_CMDMRSP:
csi_buf = TD_OPDAT; csi_buf = TD_OPDAT;
csi_csr = csi_csr | CSR_DONE; /* set input flag */ csi_csr = csi_csr | CSR_DONE; /* set input flag */
if (csi_csr & CSR_IE) if (csi_csr & CSR_IE) {
csi_int = 1; csi_int = 1;
sim_debug (TDDEB_INT, &td_dev, "CSI_INT(1)\n");
}
break; break;
} }
break; break;
@ -690,6 +827,7 @@ sim_activate_abs (&tti_unit, KBD_WAIT (tti_unit.wait, tmr_poll));
csi_buf = 0; csi_buf = 0;
csi_csr = 0; csi_csr = 0;
csi_int = 0; csi_int = 0;
sim_debug (TDDEB_INT, &td_dev, "CSI_INT(0)\n");
return SCPE_OK; return SCPE_OK;
} }
@ -1093,6 +1231,7 @@ uint16 c, w;
uint32 da; uint32 da;
int8 *fbuf = uptr->filebuf; int8 *fbuf = uptr->filebuf;
sim_debug (TDDEB_TRC, &td_dev, "td_svc(state=%s)\n", td_states[td_state]);
switch (td_state) { /* case on state */ switch (td_state) { /* case on state */
case TD_IDLE: /* idle */ case TD_IDLE: /* idle */
@ -1141,8 +1280,10 @@ switch (td_state) { /* case on state */
if ((csi_csr & CSR_DONE) == 0) { /* prev data taken? */ if ((csi_csr & CSR_DONE) == 0) { /* prev data taken? */
csi_buf = td_obuf[td_obptr++]; /* get next byte */ csi_buf = td_obuf[td_obptr++]; /* get next byte */
csi_csr = csi_csr | CSR_DONE; /* set input flag */ csi_csr = csi_csr | CSR_DONE; /* set input flag */
if (csi_csr & CSR_IE) if (csi_csr & CSR_IE) {
csi_int = 1; csi_int = 1;
sim_debug (TDDEB_INT, &td_dev, "CSI_INT(1)\n");
}
if (td_obptr >= td_olen) { /* buffer empty? */ if (td_obptr >= td_olen) { /* buffer empty? */
if (td_txsize > 0) if (td_txsize > 0)
td_state = TD_READ1; td_state = TD_READ1;
@ -1157,8 +1298,10 @@ switch (td_state) { /* case on state */
if ((csi_csr & CSR_DONE) == 0) { /* prev data taken? */ if ((csi_csr & CSR_DONE) == 0) { /* prev data taken? */
csi_buf = TD_OPCNT; csi_buf = TD_OPCNT;
csi_csr = csi_csr | CSR_DONE; /* set input flag */ csi_csr = csi_csr | CSR_DONE; /* set input flag */
if (csi_csr & CSR_IE) if (csi_csr & CSR_IE) {
csi_int = 1; csi_int = 1;
sim_debug (TDDEB_INT, &td_dev, "CSI_INT(1)\n");
}
break; break;
} }
sim_activate (uptr, td_xwait); /* schedule next */ sim_activate (uptr, td_xwait); /* schedule next */
@ -1213,6 +1356,7 @@ switch (td_state) { /* case on state */
td_olen = td_obptr; td_olen = td_obptr;
td_obptr = 0; td_obptr = 0;
td_state = TD_END1; /* go empty */ td_state = TD_END1; /* go empty */
sim_debug(TDDEB_PKT, &td_dev, "END PKT: Generated - Success Code: %X\n", td_ecode);
sim_activate (uptr, td_xwait); /* schedule next */ sim_activate (uptr, td_xwait); /* schedule next */
break; break;
@ -1220,9 +1364,12 @@ switch (td_state) { /* case on state */
if ((csi_csr & CSR_DONE) == 0) { /* prev data taken? */ if ((csi_csr & CSR_DONE) == 0) { /* prev data taken? */
csi_buf = td_obuf[td_obptr++]; /* get next byte */ csi_buf = td_obuf[td_obptr++]; /* get next byte */
csi_csr = csi_csr | CSR_DONE; /* set input flag */ csi_csr = csi_csr | CSR_DONE; /* set input flag */
if (csi_csr & CSR_IE) if (csi_csr & CSR_IE) {
csi_int = 1; csi_int = 1;
sim_debug (TDDEB_INT, &td_dev, "CSI_INT(1)\n");
}
if (td_obptr >= td_olen) { /* buffer empty? */ if (td_obptr >= td_olen) { /* buffer empty? */
sim_debug(TDDEB_PKT, &td_dev, "END PKT: Sent\n");
td_state = TD_IDLE; td_state = TD_IDLE;
break; break;
} }
@ -1234,8 +1381,10 @@ switch (td_state) { /* case on state */
if ((csi_csr & CSR_DONE) == 0) { /* prev data taken? */ if ((csi_csr & CSR_DONE) == 0) { /* prev data taken? */
csi_buf = TD_OPCNT; csi_buf = TD_OPCNT;
csi_csr = csi_csr | CSR_DONE; /* set input flag */ csi_csr = csi_csr | CSR_DONE; /* set input flag */
if (csi_csr & CSR_IE) if (csi_csr & CSR_IE) {
csi_int = 1; csi_int = 1;
sim_debug (TDDEB_INT, &td_dev, "CSI_INT(1)\n");
}
td_state = TD_IDLE; td_state = TD_IDLE;
break; break;
} }
@ -1269,6 +1418,7 @@ t_stat td_reset (DEVICE *dptr)
cso_buf = 0; cso_buf = 0;
cso_csr = CSR_DONE; cso_csr = CSR_DONE;
cso_int = 0; cso_int = 0;
sim_debug (TDDEB_INT, &td_dev, "CSO_INT(0)\n");
cso_state = TD_GETOPC; cso_state = TD_GETOPC;
td_ibptr = 0; td_ibptr = 0;
td_obptr = 0; td_obptr = 0;

13
scp.c
View file

@ -9632,18 +9632,25 @@ for (i = fields-1; i >= 0; i--) { /* print xlation, transition
indicating the state and transition of the bit and bitfields. States: indicating the state and transition of the bit and bitfields. States:
0=steady(0->0), 1=steady(1->1), _=falling(1->0), ^=rising(0->1) */ 0=steady(0->0), 1=steady(1->1), _=falling(1->0), ^=rising(0->1) */
void sim_debug_bits(uint32 dbits, DEVICE* dptr, BITFIELD* bitdefs, void sim_debug_bits_hdr(uint32 dbits, DEVICE* dptr, const char *header,
uint32 before, uint32 after, int terminate) BITFIELD* bitdefs, uint32 before, uint32 after, int terminate)
{ {
if (sim_deb && dptr && (dptr->dctrl & dbits)) { if (sim_deb && dptr && (dptr->dctrl & dbits)) {
if (!debug_unterm) if (!debug_unterm)
fprintf(sim_deb, "%s", sim_debug_prefix(dbits, dptr)); /* print prefix if required */ fprintf(sim_deb, "%s", sim_debug_prefix(dbits, dptr)); /* print prefix if required */
if (header)
fprintf(sim_deb, "%s: ", header);
fprint_fields (sim_deb, (t_value)before, (t_value)after, bitdefs); /* print xlation, transition */ fprint_fields (sim_deb, (t_value)before, (t_value)after, bitdefs); /* print xlation, transition */
if (terminate) if (terminate)
fprintf(sim_deb, "\r\n"); fprintf(sim_deb, "\r\n");
debug_unterm = terminate ? 0 : 1; /* set unterm for next */ debug_unterm = terminate ? 0 : 1; /* set unterm for next */
} }
} }
void sim_debug_bits(uint32 dbits, DEVICE* dptr, BITFIELD* bitdefs,
uint32 before, uint32 after, int terminate)
{
sim_debug_bits_hdr(dbits, dptr, NULL, bitdefs, before, after, terminate);
}
/* Print message to stdout, sim_log (if enabled) and sim_deb (if enabled) */ /* Print message to stdout, sim_log (if enabled) and sim_deb (if enabled) */
void sim_printf (const char* fmt, ...) void sim_printf (const char* fmt, ...)

2
scp.h
View file

@ -190,6 +190,8 @@ void sim_printf (const char* fmt, ...);
void sim_perror (const char* msg); void sim_perror (const char* msg);
t_stat sim_messagef (t_stat stat, const char* fmt, ...); t_stat sim_messagef (t_stat stat, const char* fmt, ...);
void sim_data_trace(DEVICE *dptr, UNIT *uptr, const uint8 *data, const char *position, size_t len, const char *txt, uint32 reason); void sim_data_trace(DEVICE *dptr, UNIT *uptr, const uint8 *data, const char *position, size_t len, const char *txt, uint32 reason);
void sim_debug_bits_hdr (uint32 dbits, DEVICE* dptr, const char *header,
BITFIELD* bitdefs, uint32 before, uint32 after, int terminate);
void sim_debug_bits (uint32 dbits, DEVICE* dptr, BITFIELD* bitdefs, void sim_debug_bits (uint32 dbits, DEVICE* dptr, BITFIELD* bitdefs,
uint32 before, uint32 after, int terminate); uint32 before, uint32 after, int terminate);
#if defined (__DECC) && defined (__VMS) && (defined (__VAX) || (__DECC_VER < 60590001)) #if defined (__DECC) && defined (__VMS) && (defined (__VAX) || (__DECC_VER < 60590001))