SEL32: Add IPU device support using pthreads on Linux and Windows.

SEL32: Update makefile and SEL32.vsproj file to add IPU device.
SEL32: Update README.md file.
SEL32: Do a general code cleanup.
This commit is contained in:
Jim Bevier 2023-01-04 13:22:12 -07:00 committed by Paul Koning
parent 5e01c0516b
commit 4e159a04ed
21 changed files with 10185 additions and 1997 deletions

View file

@ -5,7 +5,10 @@ This is a working simulator for the SEL Concept/32 computer. The current
version is for the SEL 32/27, 32/67, 32/77, 32/87, 32/97, V6, and V9
computers. All of the processors except for the 32/77 can run the Gould
diags. Operational support for the 32/77 computers may be added in the
future.
future. Additional processors are now supported. The 32/6780, 32/8780,
32/9780, V6/IPU, and V9/IPU processors with an IPU able to run an
additional instruction stream. Threads are used so support is provided
by both Windows and Linux.
# SEL Concept/32
@ -19,9 +22,10 @@ can be used to access MPX or UTX via Telnet port 4747. The sumulator has
support for excess 64 floating point arithmetic and passes the 32/27 and
32/67 FP diags. UTX is the SEL version of System V Unix and BSD Unix
ported to the V6 and V9 processors. UTX utilizes the basemode instruction
set and a virtual memory system supported by the V6 & V9 CPUs. The system
needs further testing to solidify the SEL32 simulator code in all of the
supported environmenets and hardware configurations.
set and a virtual memory system supported by the V6 & V9 CPUs. The IPU is
also supported by UTX and MPX-32. The system needs further testing to
solidify the SEL32 simulator code in all of the supported environmenets
and hardware configurations.
# SEL32 installation configuration files in the installs directory:
@ -95,6 +99,13 @@ diag.tap - bootable level one diagnostic tape w/auto testing.
Testing is extremely difficult without any source for the
diagnostics. Updates to follow as tests are corrected.
# SEL32 tap tools available in the taptools directory:
Available tap tools in taptools directory:
./taptools - set of tools to work with .tap formatted tapes. Also tools
to convert between MPX and UNIX file formats. See README
file in the taptools directory and source for descriptions.
Other MPX versions support:
I have recently received some old MPX 3.X save tapes. Using
these I have been able to hand build a MPX3.6 SDT tape that
@ -109,4 +120,4 @@ Other MPX versions support:
thankfull. Please keep looking.
James C. Bevier
02/28/2022
01/03/2023

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
/* sel32_clk.c: SEL 32 Class F IOP processor RTOM functions.
Copyright (c) 2018-2021, James C. Bevier
Copyright (c) 2018-2023, James C. Bevier
Portions provided by Richard Cornwell, Geert Rolf and other SIMH contributers
Permission is hereby granted, free of charge, to any person obtaining a
@ -47,7 +47,6 @@ const char *rtc_desc(DEVICE *dptr);
extern int irq_pend; /* go scan for pending int or I/O */
extern uint32 INTS[]; /* interrupt control flags */
extern uint32 SPAD[]; /* computer SPAD */
extern uint32 M[]; /* system memory */
extern uint32 outbusy; /* output waiting on timeout */
extern uint32 inbusy; /* input waiting on timeout */
@ -112,7 +111,7 @@ t_stat rtc_srv (UNIT *uptr)
#endif
/* if clock disabled, do not do interrupts */
if (((rtc_dev.flags & DEV_DIS) == 0) && rtc_pie) {
int lev = 0x13;
int lev = rtc_lvl;
sim_debug(DEBUG_CMD, &rtc_dev,
"RT Clock mfp INTS[%02x] %08x SPAD[%02x] %08x\n",
lev, INTS[lev], lev+0x80, SPAD[lev+0x80]);
@ -127,15 +126,17 @@ t_stat rtc_srv (UNIT *uptr)
/* HACK for console I/O stopping */
/* This reduces the number of console I/O stopping errors */
/* need to find real cause of I/O stopping on clock interrupt */
if ((outbusy==0) && (inbusy==0)) /* skip interrupt if con I/O in busy wait */
if ((outbusy==0) && (inbusy==0)) { /* skip interrupt if con I/O in busy wait */
INTS[rtc_lvl] |= INTS_REQ; /* request the interrupt */
else
irq_pend = 1; /* make sure we scan for int */
} else {
sim_debug(DEBUG_CMD, &rtc_dev,
"RT Clock int console busy\n");
}
#else
INTS[rtc_lvl] |= INTS_REQ; /* request the interrupt */
#endif
irq_pend = 1; /* make sure we scan for int */
#endif
}
sim_debug(DEBUG_CMD, &rtc_dev,
"RT Clock int INTS[%02x] %08x SPAD[%02x] %08x\n",
@ -243,6 +244,7 @@ t_stat itm_set_freq (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat itm_reset (DEVICE *dptr);
t_stat itm_show_freq (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat itm_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, CONST char *cptr);
void itm_setup(uint32 ss, uint32 level);
const char *itm_desc(DEVICE *dptr);
/* Clock data structures
@ -370,6 +372,9 @@ int32 itm_rdwr(uint32 cmd, int32 cnt, uint32 level)
cmd &= 0x7f; /* just need the cmd */
itm_cmd = cmd; /* save last cmd */
if (itm_pie == 0) { /* timer enabled? */
itm_setup(1, level); /* no, initialize it */
}
switch (cmd) {
case 0x20: /* stop timer */
/* stop the timer and save the curr value for later */
@ -637,6 +642,13 @@ int32 itm_rdwr(uint32 cmd, int32 cnt, uint32 level)
/* level = interrupt level */
void itm_setup(uint32 ss, uint32 level)
{
if (ss && itm_pie && (level == itm_lvl)) { /* timer enabled? */
/* already setup, just return */
sim_debug(DEBUG_CMD, &itm_dev,
"Intv Timer setup call already enabled int %02x value %08x itm_pie %01x ss %01x\n",
itm_lvl, itm_cnt, itm_pie, ss);
return;
}
itm_lvl = level; /* save the interrupt level */
itm_load = 0; /* not loaded */
itm_src = 0; /* use itm for freq */
@ -645,14 +657,18 @@ void itm_setup(uint32 ss, uint32 level)
itm_cnt = 0; /* no count reset value */
sim_cancel (&itm_unit); /* not running yet */
if (ss == 1) { /* starting? */
#ifdef NOT_HERE_112422
INTS[level] |= INTS_ENAB; /* make sure enabled */
SPAD[level+0x80] |= SINT_ENAB; /* in spad too */
#endif
sim_debug(DEBUG_CMD, &itm_dev,
"Intv Timer setup enable int %02x value %08x itm_pie %01x ss %01x\n",
itm_lvl, itm_cnt, itm_pie, ss);
} else {
#ifdef NOT_HERE_112422
INTS[level] &= ~INTS_ENAB; /* make sure disabled */
SPAD[level+0x80] &= ~SINT_ENAB; /* in spad too */
#endif
sim_debug(DEBUG_CMD, &itm_dev,
"Intv Timer setup disable int %02x value %08x itm_pie %01x ss %01x\n",
itm_lvl, itm_cnt, itm_pie, ss);

View file

@ -1,6 +1,6 @@
/* sel32_com.c: SEL 32 8-Line IOP communications controller
Copyright (c) 2018-2021, James C. Bevier
Copyright (c) 2018-2023, James C. Bevier
Portions provided by Richard Cornwell and other SIMH contributers
Permission is hereby granted, free of charge, to any person obtaining a

View file

@ -1,6 +1,6 @@
/* sel32_con.c: SEL 32 Class F IOP processor console.
Copyright (c) 2018-2022, James C. Bevier
Copyright (c) 2018-2023, James C. Bevier
Portions provided by Richard Cornwell, Geert Rolf and other SIMH contributers
Permission is hereby granted, free of charge, to any person obtaining a
@ -34,8 +34,11 @@
#if NUM_DEVS_CON > 0
#define UNIT_CON UNIT_IDLE | UNIT_DISABLE
extern uint32 CPUSTATUS;
extern uint32 attention_trap;
#define UNIT_CON UNIT_IDLE | UNIT_DISABLE
#define CON_WAIT 1000
#define CMD u3
/* Held in u3 is the device command and status */
#define CON_INCH 0x00 /* Initialize channel command */
@ -113,8 +116,8 @@ MTAB con_mod[] = {
};
UNIT con_unit[] = {
{UDATA(&con_srvi, UNIT_CON, 0), 0, UNIT_ADDR(0x7EFC)}, /* 0 Input */
{UDATA(&con_srvo, UNIT_CON, 0), 0, UNIT_ADDR(0x7EFD)}, /* 1 Output */
{UDATA(&con_srvi, UNIT_CON, 0), CON_WAIT, UNIT_ADDR(0x7EFC)}, /* 0 Input */
{UDATA(&con_srvo, UNIT_CON, 0), CON_WAIT, UNIT_ADDR(0x7EFD)}, /* 1 Output */
};
DIB con_dib = {
@ -181,50 +184,131 @@ t_stat con_preio(UNIT *uptr, uint16 chan) {
t_stat con_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
DEVICE *dptr = uptr->dptr;
int unit = (uptr - con_unit); /* unit 0 is read, unit 1 is write */
uint16 chsa = GET_UADDR(uptr->CMD);
CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */
uint8 ch;
if ((uptr->CMD & CON_MSK) != 0) { /* is unit busy */
sim_debug(DEBUG_EXP, dptr,
sim_debug(DEBUG_CMD, dptr,
"con_startcmd unit %01x chan %02x cmd %02x BUSY cmd %02x uptr %p\n",
unit, chan, cmd, uptr->CMD, uptr);
return SNS_BSY; /* yes, return busy */
}
sim_debug(DEBUG_DETAIL, dptr,
"con_startcmd unit %01x chan %02x cmd %02x enter\n", unit, chan, cmd);
sim_debug(DEBUG_CMD, dptr,
"con_startcmd @%s unit %01x chan %04x cmd %02x CMD %04x enter\n",
(CPUSTATUS & ONIPU)?"IPU":"CPU", unit, chsa, cmd, uptr->CMD);
/* substitute CON_INCH2 for CON_INCH for pprocessing */
/* substitute CON_INCH2 for CON_INCH for processing */
if (cmd == CON_INCH)
cmd = CON_INCH2; /* save INCH command as 0xf0 */
/* process the commands */
switch (cmd & 0xFF) {
case CON_ECHO: /* 0x0a */ /* Read command w/ECHO */
uptr->CMD |= CON_EKO; /* save echo status */
case CON_RD: /* 0x02 */ /* Read command */
atbuf = 0; /* reset attention buffer */
uptr->CMD |= CON_READ; /* show read mode */
/* fall through */
case CON_INCH2: /* 0xf0 */ /* INCH command */
case CON_RWD: /* 0x37 */ /* TOF and write line */
case CON_WR: /* 0x01 */ /* Write command */
case CON_NOP: /* 0x03 */ /* NOP has do nothing */
case CON_RDBWD: /* 0x0c */ /* Read Backward */
uptr->SNS |= (SNS_RDY|SNS_ONLN); /* status is online & ready */
case CON_CON: /* 0x1f */ /* Connect, return Data Set ready */
uptr->SNS |= (SNS_DSR|SNS_DCD); /* Data set ready, Data Carrier detected */
sim_debug(DEBUG_CMD, dptr,
"con_startcmd CON CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd);
uptr->CMD &= LMASK; /* nothing left, command complete */
return SNS_CHNEND|SNS_DEVEND;
break;
case CON_DIS: /* 0x23 */ /* Disconnect has do nothing */
uptr->SNS &= ~(SNS_DSR|SNS_DCD); /* Data set not ready */
sim_debug(DEBUG_CMD, dptr,
"con_startcmd DIS CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd);
uptr->CMD &= LMASK; /* nothing left, command complete */
return SNS_CHNEND|SNS_DEVEND;
break;
case CON_SNS: /* 0x04 */ /* Sense */
/* value 4 is Data Set Ready */
/* value 5 is Data carrier detected n/u */
sim_debug(DEBUG_CMD, dptr,
"con_startcmd cmd %04x: Cmd Sense %02x\n", chsa, uptr->SNS);
ch = uptr->SNS & 0xff; /* Sense byte 3 */
if (chan_write_byte(chsa, &ch)) { /* write byte to memory */
/* write error */
cmd = 0; /* no cmd now */
sim_debug(DEBUG_CMD, dptr,
"con_startcmd write error unit %02x: CMD %08x read %02x u4 %02x ccw_count %02x\n",
unit, uptr->CMD, ch, uptr->u4, chp->ccw_count);
}
uptr->CMD &= LMASK; /* nothing left, command complete */
return SNS_CHNEND|SNS_DEVEND;
break;
/* if input tried from output device, error */
case CON_RD: /* 0x02 */ /* Read command */
case CON_ECHO: /* 0x0a */ /* Read command w/ECHO */
case CON_RDBWD: /* 0x0c */ /* Read Backward */
if (unit == 1) {
/* if input requested for output device, give error */
uptr->SNS |= SNS_CMDREJ; /* command rejected */
uptr->CMD &= LMASK; /* nothing left, command complete */
sim_debug(DEBUG_CMD, dptr,
"con_startcmd Read to output device CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd);
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; /* unit check */
break;
}
sim_debug(DEBUG_CMD, dptr,
"con_startcmd READ %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd);
uptr->CMD &= ~CON_MSK; /* remove old CMD */
uptr->CMD |= (cmd & CON_MSK); /* save command */
if (unit == 0) {
if (cmd == CON_ECHO) /* 0x0a */
uptr->CMD |= CON_EKO; /* save echo status */
atbuf = 0; /* reset attention buffer */
uptr->CMD |= CON_READ; /* show read mode */
uptr->SNS |= (SNS_RDY|SNS_ONLN); /* status is online & ready */
/* input is polled, so no start needed */
sim_cancel(uptr); /* stop input poll */
sim_activate(uptr, 300); /* start us off */
// sim_activate(uptr, 1000); /* start us off */
sim_activate(uptr, 250); /* start us off */
return SCPE_OK; /* no status change */
break;
case CON_RWD: /* 0x37 */ /* TOF and write line */
case CON_WR: /* 0x01 */ /* Write command */
if (unit == 0) {
/* if output requested for input device, give error */
uptr->SNS |= SNS_CMDREJ; /* command rejected */
uptr->CMD &= LMASK; /* nothing left, command complete */
sim_debug(DEBUG_CMD, dptr,
"con_startcmd Write to input device CMD %08x chsa %04x cmd = %02x\n",
uptr->CMD, chsa, cmd);
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; /* unit check */
break;
}
else
uptr->SNS |= (SNS_RDY|SNS_ONLN); /* status is online & ready */
uptr->CMD &= ~CON_MSK; /* remove old CMD */
uptr->CMD |= (cmd & CON_MSK); /* save command */
/* using value 500 or larger causes diag to fail on 32/27 */
// sim_activate(uptr, 500); /* start us off */
// sim_activate(uptr, 200); /* start us off */
sim_activate(uptr, 30); /* start us off */
/* using value 230 or larger causes UTX21B to fail on 32/67 */
/* 32/67 error sequence */
/* Starting Syslog Daemon */
/* ioi: sio at 801 failed, cc=2, retry=0 */
/* panic: ioi: sio - bad cc */
sim_activate(uptr, 200); /* start us off */
//fail sim_activate(uptr, 230); /* start us off */
//fail sim_activate(uptr, 250); /* start us off */
return SCPE_OK; /* no status change */
break;
case CON_INCH2: /* 0xf0 */ /* INCH command */
case CON_NOP: /* 0x03 */ /* NOP has do nothing */
uptr->SNS |= (SNS_RDY|SNS_ONLN); /* status is online & ready */
uptr->CMD &= ~CON_MSK; /* remove old CMD */
uptr->CMD |= (cmd & CON_MSK); /* save command */
sim_debug(DEBUG_CMD, dptr,
"con_startcmd @%s INCH/NOP cmd CMD %08x chsa %04x cmd = %02x\n",
(CPUSTATUS & ONIPU)?"IPU":"CPU", uptr->CMD, chsa, cmd);
/* input is polled, so no start needed */
if (unit == 1) { /* doing output */
sim_activate(uptr, 250); /* start us off */
} else {
sim_cancel(uptr); /* stop input poll */
sim_activate(uptr, 250); /* start us off */
}
return SCPE_OK; /* no status change */
break;
@ -233,7 +317,7 @@ t_stat con_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
}
/* invalid command */
uptr->SNS |= SNS_CMDREJ; /* command rejected */
sim_debug(DEBUG_EXP, dptr,
sim_debug(DEBUG_CMD, dptr,
"con_startcmd %04x: Invalid command %02x Sense %02x\n",
chan, cmd, uptr->SNS);
return SNS_CHNEND|SNS_DEVEND|STATUS_PCHK;
@ -259,43 +343,16 @@ t_stat con_srvo(UNIT *uptr) {
switch (cmd) {
/* if input tried from output device, error */
case CON_RD: /* 0x02 */ /* Read command */
case CON_ECHO: /* 0x0a */ /* Read command w/ECHO */
case CON_RDBWD: /* 0x0c */ /* Read Backward */
/* if input requested for output device, give error */
uptr->SNS |= SNS_CMDREJ; /* command rejected */
uptr->CMD &= LMASK; /* nothing left, command complete */
sim_debug(DEBUG_CMD, dptr,
"con_srvo Read to output device CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd);
chan_end(chsa, SNS_CHNEND|SNS_UNITCHK); /* unit check */
break;
case CON_CON: /* 0x1f */ /* Connect, return Data Set ready */
uptr->SNS |= (SNS_DSR|SNS_DCD); /* Data set ready, Data Carrier detected */
sim_debug(DEBUG_CMD, dptr,
"con_srvo CON CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd);
uptr->CMD &= ~CON_MSK; /* remove old CMD */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */
break;
case CON_DIS: /* 0x23 */ /* Disconnect has do nothing */
uptr->SNS &= ~(SNS_DSR|SNS_DCD); /* Data set not ready */
sim_debug(DEBUG_CMD, dptr,
"con_srvo DIS CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd);
uptr->CMD &= ~CON_MSK; /* remove old CMD */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */
break;
case CON_INCH2: /* 0xf0 */ /* INCH command */
uptr->CMD &= LMASK; /* nothing left, command complete */
sim_debug(DEBUG_CMD, dptr,
"con_srvo INCH unit %02x: CMD %08x cmd %02x incnt %02x u4 %02x\n",
unit, uptr->CMD, cmd, con_data[unit].incnt, uptr->u4);
"con_srvo INCH unit %02x: CMD %08x cmd %02x incnt %02x u4 %02x inch %06x in2 %06x\n",
unit, uptr->CMD, cmd, con_data[unit].incnt, uptr->u4, mema, M[mema>>2]);
/* now call set_inch() function to write and test inch buffer addresses */
/* 1-256 wd buffer is provided for 128 status dbl words */
tstart = set_inch(uptr, mema, 128); /* new address & 128 entries */
//TRY tstart = set_inch(uptr, mema, 128); /* new address & 128 entries */
tstart = set_inch(uptr, mema, 1); /* new address & 128 entries */
if ((tstart == SCPE_MEM) || (tstart == SCPE_ARG)) { /* any error */
/* we have error, bail out */
uptr->SNS |= SNS_CMDREJ;
@ -306,94 +363,21 @@ t_stat con_srvo(UNIT *uptr) {
break;
}
sim_debug(DEBUG_CMD, dptr,
"con_srvo INCH CMD %08x chsa %04x len %02x inch %06x\n", uptr->CMD, chsa, len, mema);
"con_srvo INCH CMD %08x chsa %04x len %02x inch %06x in2 %06x\n", uptr->CMD, chsa, len, mema, M[mema>>2]);
/* WARNING, if SNS_DEVEND is not set, diags fail by looping in CON diag */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */
break;
case CON_NOP: /* 0x03 */ /* NOP has do nothing */
uptr->CMD &= ~CON_MSK; /* remove old CMD */
//ZZ uptr->CMD &= ~CON_MSK; /* remove old CMD */
uptr->CMD &= LMASK; /* nothing left, command complete */
sim_debug(DEBUG_CMD, dptr,
"con_srvo NOP CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */
break;
case CON_SNS: /* 0x04 */ /* Sense */
/* value 4 is Data Set Ready */
/* value 5 is Data carrier detected n/u */
sim_debug(DEBUG_CMD, dptr,
"con_srvo cmd %04x: Cmd Sense %02x\n", chsa, uptr->SNS);
/* value 4 is Data Set Ready */
/* value 5 is Data carrier detected n/u */
ch = uptr->SNS & 0xff; /* Sense byte 3 */
if (chan_write_byte(chsa, &ch)) { /* write byte to memory */
/* write error */
cmd = 0; /* no cmd now */
sim_debug(DEBUG_CMD, dptr,
"con_srvo write error unit %02x: CMD %08x read %02x u4 %02x ccw_count %02x\n",
unit, uptr->CMD, ch, uptr->u4, chp->ccw_count);
uptr->CMD &= LMASK; /* nothing left, command complete */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we done */
break;
}
uptr->CMD &= LMASK; /* nothing left, command complete */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* good return */
break;
case CON_RWD: /* 0x37 */ /* TOF and write line */
case CON_WR: /* 0x01 */ /* Write command */
#ifdef DO_OLDWAY
/* see if write complete */
if (uptr->CMD & CON_OUTPUT) {
/* write is complete, post status */
sim_debug(DEBUG_CMD, &con_dev,
"con_srvo write CMD %08x chsa %04x cmd %02x complete\n",
uptr->CMD, chsa, cmd);
uptr->CMD &= ~CON_MSK; /* remove old CMD */
uptr->CMD &= ~CON_OUTPUT; /* remove output command */
/*RTC*/ outbusy = 0; /* output done */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */
break;
}
/*RTC*/ outbusy = 1; /* tell clock output waiting */
if (chan_read_byte(chsa, &ch) == SCPE_OK) { /* get byte from memory */
/* Write to device */
ch &= 0x7f; /* make 7 bit w/o parity */
dexp = dexp<<8; /* move up last chars */
dexp |= ch; /* insert new char */
#ifdef DO_DYNAMIC_DEBUG
// if ((cnt == 3) && (dexp == 0x4458503e)) { /* test for "DXP>" */
if ((cnt == 13) && (dexp == 0x4E542E48)) { /* test for "NT.H" */
cpu_dev.dctrl |= (DEBUG_INST|DEBUG_TRAP|DEBUG_IRQ); /* start instruction trace */
con_dev.dctrl |= DEBUG_XIO|DEBUG_CMD;
// sim_debug(DEBUG_INST, &cpu_dev, "|con_srvo DXP> received|\n");
sim_debug(DEBUG_INST, &cpu_dev, "con_srvo CV.INT.H received start debug\n");
}
if ((cnt == 13) && (dexp == 0x52502E48)) { /* test for "RP.H" */
/* turn of debug trace because we are already hung */
sim_debug(DEBUG_INST, &cpu_dev, "con_srvo got CV.TRP.H stopping debug\n");
cpu_dev.dctrl &= ~(DEBUG_INST|DEBUG_TRAP|DEBUG_IRQ); /* start instruction trace */
con_dev.dctrl &= ~(DEBUG_XIO|DEBUG_CMD);
}
#endif
sim_putchar(ch); /* output next char to device */
sim_debug(DEBUG_CMD, dptr,
"con_srvo write wait %03x CMD %08x chsa %04x cmd %02x byte %d = %02x\n",
1000, uptr->CMD, chsa, cmd, cnt, ch);
cnt++; /* count chars output */
//01132022 sim_activate(uptr, 500); /* wait for a while before next write */
sim_activate(uptr, 50); /* wait for a while before next write */
break;
}
/* nothing left, finish up */
cnt = 0; /* zero for next output */
uptr->CMD |= CON_OUTPUT; /* output command complete */
sim_debug(DEBUG_CMD, &con_dev,
"con_srvo write wait %03x CMD %08x chsa %04x cmd %02x to complete\n",
1000, uptr->CMD, chsa, cmd);
sim_activate(uptr, 500); /* wait for a while */
break;
#else
cnt = 0; /* zero count */
/*RTC*/ outbusy = 1; /* tell clock output waiting */
mema = chp->ccw_addr; /* get buffer addr */
@ -403,16 +387,6 @@ t_stat con_srvo(UNIT *uptr) {
ch &= 0x7f; /* make 7 bit w/o parity */
dexp = dexp<<8; /* move up last chars */
dexp |= ch; /* insert new char */
#ifdef DO_DYNAMIC_DEBUG
// if ((cnt == 3) && (dexp == 0x4458503e)) { /* test for "DXP>" */
if ((cnt == 3) && (dexp == 0x44454641)) { /* test for "DEFA" */
// cpu_dev.dctrl |= (DEBUG_INST|DEBUG_IRQ); /* start instruction trace */
cpu_dev.dctrl |= (DEBUG_INST|DEBUG_TRAP|DEBUG_IRQ); /* start instruction trace */
// con_dev.dctrl |= DEBUG_CMD;
// sim_debug(DEBUG_INST, &cpu_dev, "|con_srvo DXP> received|\n");
sim_debug(DEBUG_INST, &cpu_dev, "|con_srvo DEFA received|\n");
}
#endif
sim_putchar(ch); /* output next char to device */
if (isprint(ch))
sim_debug(DEBUG_CMD, dptr,
@ -433,7 +407,6 @@ t_stat con_srvo(UNIT *uptr) {
/*RTC*/ outbusy = 0; /* output done */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */
break;
#endif
}
return SCPE_OK;
}
@ -450,29 +423,18 @@ t_stat con_srvi(UNIT *uptr) {
uint32 tstart;
uint8 ch;
t_stat r;
int32 wait_time=10000;
switch (cmd) {
/* if output tried to input device, error */
case CON_RWD: /* 0x37 */ /* TOF and write line */
case CON_WR: /* 0x01 */ /* Write command */
/* if input requested for output device, give error */
uptr->SNS |= SNS_CMDREJ; /* command rejected */
uptr->CMD &= LMASK; /* nothing left, command complete */
sim_debug(DEBUG_CMD, dptr,
"con_srvi Write to input device CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd);
chan_end(chsa, SNS_CHNEND|SNS_UNITCHK); /* unit check */
break;
case CON_INCH2: /* 0xf0 */ /* INCH command */
uptr->CMD &= LMASK; /* nothing left, command complete */
sim_debug(DEBUG_CMD, dptr,
"con_srvi INCH unit %02x: CMD %08x cmd %02x incnt %02x u4 %02x inch %06x\n",
unit, uptr->CMD, cmd, con_data[unit].incnt, uptr->u4, mema);
"con_srvi INCH unit %02x: CMD %08x cmd %02x incnt %02x u4 %02x inch %06x in2 %06x\n",
unit, uptr->CMD, cmd, con_data[unit].incnt, uptr->u4, mema, M[mema>>2]);
/* now call set_inch() function to write and test inch buffer addresses */
tstart = set_inch(uptr, mema, 128); /* new address & 128 entries */
//TRY tstart = set_inch(uptr, mema, 128); /* new address & 128 entries */
tstart = set_inch(uptr, mema, 1); /* new address & 128 entries */
if ((tstart == SCPE_MEM) || (tstart == SCPE_ARG)) { /* any error */
/* we have error, bail out */
uptr->SNS |= SNS_CMDREJ;
@ -485,56 +447,21 @@ t_stat con_srvi(UNIT *uptr) {
con_data[unit].incnt = 0; /* buffer empty */
uptr->u4 = 0; /* no I/O yet */
sim_debug(DEBUG_CMD, dptr,
"con_srvi INCH CMD %08x chsa %04x len %02x inch %06x\n", uptr->CMD, chsa, len, mema);
"con_srvi INCH CMD %08x chsa %04x len %02x inch %06x in2 %06x\n", uptr->CMD, chsa, len, mema, M[mema>>2]);
/* WARNING, if SNS_DEVEND is not set, diags fail by looping in CON diag */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */
/* drop through to poll input */
break;
case CON_NOP: /* 0x03 */ /* NOP has do nothing */
uptr->CMD &= ~CON_MSK; /* remove old CMD */
//ZZ uptr->CMD &= ~CON_MSK; /* remove old CMD */
uptr->CMD &= LMASK; /* nothing left, command complete */
sim_debug(DEBUG_CMD, dptr,
"con_srvi NOP CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */
/* drop through to poll input */
break;
case CON_CON: /* 0x1f */ /* Connect, return Data Set ready */
uptr->SNS |= (SNS_DSR|SNS_DCD); /* Data set ready, Data Carrier detected */
sim_debug(DEBUG_CMD, dptr,
"con_srvi CON CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd);
uptr->CMD &= ~CON_MSK; /* remove old CMD */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */
break;
case CON_DIS: /* 0x23 */ /* Disconnect has do nothing */
uptr->SNS &= ~(SNS_DSR|SNS_DCD); /* Data set not ready */
sim_debug(DEBUG_CMD, dptr,
"con_srvi DIS CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd);
uptr->CMD &= ~CON_MSK; /* remove old CMD */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */
break;
case CON_SNS: /* 0x04 */ /* Sense */
sim_debug(DEBUG_CMD, dptr,
"con_srvi cmd %04x: Cmd Sense %02x\n", chsa, uptr->SNS);
/* value 4 is Data Set Ready */
/* value 5 is Data carrier detected n/u */
ch = uptr->SNS & 0xff; /* Sense byte 3 */
if (chan_write_byte(chsa, &ch)) { /* write byte to memory */
/* write error */
cmd = 0; /* no cmd now */
sim_debug(DEBUG_CMD, dptr,
"con_srvi write error unit %02x: CMD %08x read %02x u4 %02x ccw_count %02x\n",
unit, uptr->CMD, ch, uptr->u4, chp->ccw_count);
uptr->CMD &= LMASK; /* nothing left, command complete */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we done */
break;
}
uptr->CMD &= LMASK; /* nothing left, command complete */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we done */
break;
case CON_ECHO: /* 0x0a */ /* read from device w/ECHO */
uptr->CMD |= CON_EKO; /* save echo status */
case CON_RD: /* 0x02 */ /* read from device */
@ -551,10 +478,6 @@ t_stat con_srvi(UNIT *uptr) {
sim_debug(DEBUG_IRQ, dptr,
"con_srvi readbuf unit %02x: CMD %08x read %02x incnt %02x u4 %02x len %02x\n",
unit, uptr->CMD, ch, con_data[unit].incnt, uptr->u4, chp->ccw_count);
#ifdef DO_DYNAMIC_DEBUG
/* turn on instruction trace */
cpu_dev.dctrl |= DEBUG_INST; /* start instruction trace */
#endif
/* process any characters */
if (uptr->u4 != con_data[unit].incnt) { /* input available */
@ -593,9 +516,6 @@ t_stat con_srvi(UNIT *uptr) {
if (uptr->u4 == con_data[unit].incnt) { /* input empty */
uptr->CMD &= ~CON_INPUT; /* no input available */
}
// wait_time = 200; /* process next time */
// wait_time = 400; /* process next time */
wait_time = 800; /* process next time */
break;
}
/* command is completed */
@ -607,10 +527,6 @@ t_stat con_srvi(UNIT *uptr) {
sim_debug(DEBUG_CMD, dptr,
"con_srvi read done unit %02x CMD %08x read %02x u4 %02x ccw_count %02x incnt %02x\n",
unit, uptr->CMD, ch, uptr->u4, chp->ccw_count, con_data[unit].incnt);
#ifdef DO_DYNAMIC_DEBUG
/* turn on instruction trace */
cpu_dev.dctrl |= DEBUG_INST; /* start instruction trace */
#endif
cmd = 0; /* no cmd now */
uptr->CMD &= LMASK; /* nothing left, command complete */
if (uptr->u4 != con_data[unit].incnt) { /* input empty */
@ -648,10 +564,6 @@ t_stat con_srvi(UNIT *uptr) {
sim_debug(DEBUG_CMD, dptr,
"con_srvi handle readch unit %02x: CMD %08x read %02x u4 %02x incnt %02x r %x\n",
unit, uptr->CMD, ch, uptr->u4, con_data[unit].incnt, r);
#ifdef DO_DYNAMIC_DEBUG
/* turn on instruction trace */
cpu_dev.dctrl |= DEBUG_INST; /* start instruction trace */
#endif
/* put char in buffer */
con_data[unit].ibuff[con_data[unit].incnt++] = ch;
@ -669,7 +581,10 @@ t_stat con_srvi(UNIT *uptr) {
sim_debug(DEBUG_CMD, dptr,
"con_srvi readch unit %02x: CMD %08x read %02x u4 %02x incnt %02x\n",
unit, uptr->CMD, ch, uptr->u4, con_data[unit].incnt);
sim_activate(uptr, 30); /* do this again */
//JB sim_clock_coschedule(uptr, 1000);
//JB sim_activate(uptr, 30); /* do this again */
//?? sim_activate(uptr, 300); /* do this again */
sim_activate(uptr, 500); /* do this again */
//01172021 sim_activate(uptr, 400); /* do this again */
// sim_activate(uptr, 800); /* do this again */
return SCPE_OK;
@ -700,7 +615,9 @@ t_stat con_srvi(UNIT *uptr) {
con_data[unit].incnt = 0; /* no input data */
}
// sim_activate(uptr, wait_time); /* do this again */
sim_activate(uptr, 400); /* do this again */
//?? sim_activate(uptr, 400); /* do this again */
sim_activate(uptr, 500); /* do this again */
//JB sim_clock_coschedule(uptr, 1000);
// sim_activate(uptr, 4000); /* do this again */
return SCPE_OK;
}
@ -731,14 +648,10 @@ t_stat con_srvi(UNIT *uptr) {
sim_debug(DEBUG_CMD, dptr,
"con_srvi readch2 unit %02x: CMD %08x read %02x u4 %02x incnt %02x r %x\n",
unit, uptr->CMD, ch, uptr->u4, con_data[unit].incnt, r);
#ifdef DO_DYNAMIC_DEBUG
/* turn off debug trace because we are already hung */
sim_debug(DEBUG_INST, &cpu_dev, "con_srvi readch3 stopping debug\n");
cpu_dev.dctrl &= ~(DEBUG_INST|DEBUG_TRAP|DEBUG_IRQ); /* start instruction trace */
con_dev.dctrl &= ~(DEBUG_XIO|DEBUG_CMD);
#endif
}
sim_activate(uptr, wait_time); /* do this again */
//X sim_activate(uptr, wait_time); /* do this again */
sim_clock_coschedule(uptr, 1000); /* continue poll */
//JBsim_clock_coschedule(uptr, 1000);
return SCPE_OK;
}
@ -753,7 +666,6 @@ t_stat con_rschnlio(UNIT *uptr) {
int cmd = uptr->CMD & CON_MSK;
con_ini(uptr, 0); /* reset the unit */
sim_debug(DEBUG_EXP, &con_dev, "con_rschnl chsa %04x cmd = %02x\n", chsa, cmd);
// cpu_dev.dctrl |= (DEBUG_INST|DEBUG_TRAP|DEBUG_IRQ); /* start instruction trace */
return SCPE_OK;
}
@ -795,5 +707,5 @@ t_stat con_haltio(UNIT *uptr) {
chsa, cmd, chp->ccw_count);
return CC1BIT | SCPE_OK; /* not busy */
}
#endif
#endif /* #if NUM_DEVS_CON > 0 */

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
/* sel32_defs.h: SEL-32 Concept/32 simulator definitions
Copyright (c) 2018-2022, James C. Bevier
Copyright (c) 2018-2023, James C. Bevier
Portions provided by Richard Cornwell, Geert Rolf and other SIMH contributers
Permission is hereby granted, free of charge, to any person obtaining a
@ -21,9 +21,99 @@
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/********************Attention************************/
/* define the environment wanted for sel32 execution */
/* */
/* define CPUONLY to only run with CPU model */
/* undef CPUONLY to run with an IPU (2nd CPU) */
/* */
/* for IPU models, define the IPU support method */
/* define USE_IPU_THREAD to run IPU in a thread */
/* undef USE_IPU_THREAD to run IPU in forked task */
/* */
/* for threaded IPU models, select thread locking */
/* define USE_POSIX_SEM for POSIX semaphores */
/* undef USE_POSIX_SEM to use pthread mutexs */
/********************Attention************************/
/* define CPUONLY to run without IPU */
//#define CPUONLY /* run on CPU only */
#undef CPUONLY /* run with cpu/ipu on system */
/* undefine CPUONLY to run with IPU */
/* define USE_IPU_THREAD to use IPU thread code instead of fork code */
/* define USE_POSIX_SEM for POSIX semaphores otherwise use pthread mutex */
/* forked mode IPU must only use semaphores */
#ifndef CPUONLY
//#define USE_POSIX_SEM /* use POSIX semaphores, else pthread mutex */
//#undef USE_IPU_THREAD /* run IPU as a forked sel32 */
#define USE_IPU_THREAD /* run IPU in sel32_ipu.c thread */
#endif
/* enforce proper option combinations for CPU/IPU */
#ifndef CPUONLY
#define DEFINE_IPU_MODELS /* IPU devices must be define for IPU */
#ifndef USE_IPU_THREAD
#define USE_POSIX_SEM /* forked mode IPU can only use semaphores */
#endif
#else /* CPUONLY */
#undef USE_IPU_THREAD /* make sure IPU code undefined for CPUONLY */
#undef DEFINE_IPU_MODELS /* make sure IPU models undefine too */
#endif /* CPU_ONLY */
/* use correct variable type for thread IPU */
#ifdef USE_IPU_THREAD
#ifdef USE_IPU_CODE
#define LOCAL static /* IPU in thread needs static variables */
#else /* USE_IPU_CODE */
#define LOCAL /* IPU in fork needs regular variables */
#endif /* USE_IPU_CODE */
#else /* USE_IPU_THREAD */
#define LOCAL /* IPU in fork needs regular variables */
#endif /* USE_IPU_THREAD */
#define HASIPU 0x1000 /* BIT19 */
#define ONIPU 0x0010 /* BIT27 */
#include "sim_defs.h" /* simh simulator defns */
#ifndef CPUONLY
#ifdef USE_POSIX_SEM
#include <semaphore.h>
/* shared Interprocessor Com for SIPU [0] for CPU [1] for IPU */
struct ipcom {
int pid[2]; /* process id for each */
int atrap[2]; /* any Async TRAP to peer */
int sent[2]; /* counting send calls */
int received[2]; /* counting received calls */
int blocked[2]; /* counting blocked calls */
int dropped[2]; /* counting dropped calls */
/* anything for semaphores here */
sem_t simsem; /* the semaphore */
int pass[2]; /* count passing */
int wait[2]; /* count waiting */
};
#else
/* Use pthread mutexs */
#include <pthread.h>
/* shared Interprocessor Com for SIPU [0] for CPU [1] for IPU */
struct ipcom {
int pid[2]; /* process id for each */
int atrap[2]; /* any Async TRAP to peer */
int sent[2]; /* counting send calls */
int received[2]; /* counting received calls */
int blocked[2]; /* counting blocked calls */
int dropped[2]; /* counting dropped calls */
/* anything for mutexs here */
pthread_mutex_t mutex; /* the mutex for controlling access */
pthread_cond_t cond; /* conditional wait condition */
int pass[2]; /* count passing */
int wait[2]; /* count waiting */
};
#endif
#endif
/* Simulator stop codes */
#define STOP_IONRDY 1 /* I/O dev not ready */
#define STOP_HALT 2 /* HALT */
@ -142,6 +232,10 @@
extern DEVICE cpu_dev; /* cpu device */
extern UNIT cpu_unit; /* the cpu unit */
#ifdef USE_IPU_THREAD
extern DEVICE ipu_dev; /* cpu device */
extern UNIT ipu_unit; /* the cpu unit */
#endif
#ifdef NUM_DEVS_IOP
extern DEVICE iop_dev; /* IOP channel controller */
#endif
@ -344,14 +438,17 @@ extern DEBTAB dev_debug[];
#define DSEXT32(x) (x&0x8000?(l_uint64)(((l_uint64)x&D32RMASK)|D32LMASK):(t_uint64)x)
#define NEGATE32(val) ((~val) + 1) /* negate a value 16/32/64 bits */
/* defined in rightmost 8 bits of upper 16 bits of uptr->flags */
/* defined in rightmost 9 bits of upper 16 bits of uptr->flags */
#define UNIT_V_MODEL (UNIT_V_UF + 0)
#define UNIT_MODEL (7 << UNIT_V_MODEL)
#define UNIT_MODEL (0xf << UNIT_V_MODEL)
#define MODEL(x) (x << UNIT_V_MODEL)
#define UNIT_V_MSIZE (UNIT_V_MODEL + 3)
#define UNIT_V_MSIZE (UNIT_V_MODEL + 4)
#define UNIT_V_IPU (UNIT_V_MODEL + 4)
#define UNIT_MSIZE (0x1F << UNIT_V_MSIZE)
#define UNIT_IPU (0x1 << UNIT_V_IPU)
#define MEMAMOUNT(x) (x << UNIT_V_MSIZE)
#define CPU_MODEL ((cpu_unit.flags >> UNIT_V_MODEL) & 0x7) /* cpu model 0-7 */
#define CPU_MODEL ((cpu_unit.flags >> UNIT_V_MODEL) & 0x7)/* cpu model 0-7 */
#define IPU_MODEL ((cpu_unit.flags >> UNIT_V_IPU) & 0x1) /* ipu model 1 */
#define MODEL_55 0 /* 512K Mode Only */
#define MODEL_75 1 /* Extended */
@ -361,6 +458,12 @@ extern DEBTAB dev_debug[];
#define MODEL_97 5 /* */
#define MODEL_V6 6 /* V6 CPU */
#define MODEL_V9 7 /* V9 CPU */
#define MODEL_7780 9 /* */
#define MODEL_6780 11 /* */
#define MODEL_8780 12 /* */
#define MODEL_9780 13 /* */
#define MODEL_V6IPU 14 /* */
#define MODEL_V9IPU 15 /* */
#define TMR_RTC 1 /* RTC will not work if set to 0!! */
//#define TMR_RTC 0
@ -375,10 +478,12 @@ extern DEBTAB dev_debug[];
#define CC3BIT 0x10000000 /* CC3 in PSD1 */
#define CC4BIT 0x08000000 /* CC4 in PSD1 */
#define MAPMODE 0x40 /* Map mode, PSD 2 bit 0 */
#define RETMODE 0x20 /* Retain current maps, PSD 2 bit 15 */
#define RETBLKM 0x10 /* Set retain blocked mode, PSD 2 bit 16 */
#define IPUMODE 0x20 /* This is running on IPU, bit 27 of CPUSTATUS */
#define INTBLKD 0x10 /* bit 24 of CPUSTATUS word, set if ints blocked */
#define BLKMODE 0x08 /* Set blocked mode, PSD 2 bit 17 */
#define MAPMODE 0x04 /* Map mode, PSD 2 bit 0 */
#define RETMODE 0x02 /* Retain current maps, PSD 2 bit 15 */
#define RETBLKM 0x01 /* Set retain blocked mode, PSD 2 bit 16 */
/* PSD mode bits in PSD words 1&2 variable */
#define PRIVBIT 0x80000000 /* Privileged mode PSD 1 bit 0 */
@ -482,6 +587,64 @@ extern DEBTAB dev_debug[];
/* Rename of global PC variable to avoid namespace conflicts on some platforms */
#define PC PC_Global
/* Definitions for commonly used functions */
extern t_stat set_dev_addr(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
extern t_stat show_dev_addr(FILE * st, UNIT *uptr, int32 v, CONST void *desc);
extern void chan_end(uint16 chan, uint16 flags);
extern int chan_read_byte(uint16 chsa, uint8 *data);
extern int chan_write_byte(uint16 chsa, uint8 *data);
extern void set_devattn(uint16 addr, uint16 flags);
extern void set_devwake(uint16 chsa, uint16 flags);
extern t_stat chan_boot(uint16 addr, DEVICE *dptr);
extern int test_write_byte_end(uint16 chsa);
extern DEVICE *get_dev(UNIT *uptr);
extern t_stat set_inch(UNIT *uptr, uint32 inch_addr, uint32 num_inch); /* set inch addr */
extern CHANP *find_chanp_ptr(uint16 chsa); /* find chanp pointer */
#ifndef CPUONLY
#ifndef USE_IPU_THREAD
extern struct ipcom *IPC;
extern uint32 *M; /* our memory shared with fork IPU */
#else
extern struct ipcom *IPC;
extern uint32 M[]; /* our local memory with thread IPU */
#endif
#else
extern uint32 M[]; /* our local memory without IPU */
#endif
#ifndef USE_IPU_CODE
extern uint32 SPAD[]; /* cpu SPAD memory */
#endif
extern uint32 attention_trap;
extern int irq_pend; /* pending interrupt flag */
#ifdef NOT_USED
extern uint32 RDYQ[]; /* ready queue */
extern uint32 RDYQIN; /* input index */
extern uint32 RDYQOUT; /* output index */
extern int32 RDYQ_Put(uint32 entry);
extern int32 RDYQ_Get(uint32 *old);
extern int32 RDYQ_Num(void);
#define RDYQ_SIZE 128
#endif
struct InstHistory
{
uint32 opsd1; /* original PSD1 */
uint32 opsd2; /* original PSD2 */
uint32 npsd1; /* new PSD1 after instruction */
uint32 npsd2; /* new PSD2 after instruction */
uint32 oir; /* the instruction itself */
uint32 modes; /* current ipu mode bits */
uint32 reg[16]; /* regs/bregs for operation */
};
extern char *dump_mem(uint32 mp, int cnt);
extern char *dump_buf(uint8 *mp, int32 off, int cnt);
#define get_chan(chsa) ((chsa>>8)&0x7f) /* get channel number from ch/sa */
/* memory access macros */
/* The RMW and WMW macros are used to read/write memory words */
/* RMW(addr) or WMW(addr, data) where addr is a byte alligned word address */
@ -503,33 +666,4 @@ extern DEBTAB dev_debug[];
/* write halfword map register to MAP cache address */
#define WMR(a,d) ((a)&2?(MAPC[(a)>>2]=(MAPC[(a)>>2]&LMASK)|((d)&RMASK)):(MAPC[(a)>>2]=(MAPC[(a)>>2]&RMASK)|((d)<<16)))
/* Definitions for commonly used functions */
extern t_stat set_dev_addr(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
extern t_stat show_dev_addr(FILE * st, UNIT *uptr, int32 v, CONST void *desc);
extern void chan_end(uint16 chan, uint16 flags);
extern int chan_read_byte(uint16 chsa, uint8 *data);
extern int chan_write_byte(uint16 chsa, uint8 *data);
extern void set_devattn(uint16 addr, uint16 flags);
extern void set_devwake(uint16 chsa, uint16 flags);
extern t_stat chan_boot(uint16 addr, DEVICE *dptr);
extern int test_write_byte_end(uint16 chsa);
extern DEVICE *get_dev(UNIT *uptr);
extern t_stat set_inch(UNIT *uptr, uint32 inch_addr, uint32 num_inch); /* set inch addr */
extern CHANP *find_chanp_ptr(uint16 chsa); /* find chanp pointer */
extern uint32 M[]; /* our memory */
extern uint32 SPAD[]; /* cpu SPAD memory */
extern uint32 attention_trap;
extern uint32 RDYQ[]; /* ready queue */
extern uint32 RDYQIN; /* input index */
extern uint32 RDYQOUT; /* output index */
#define RDYQ_SIZE 128
extern int32 RDYQ_Put(uint32 entry);
extern int32 RDYQ_Get(uint32 *old);
extern int32 RDYQ_Num(void);
extern char *dump_mem(uint32 mp, int cnt);
extern char *dump_buf(uint8 *mp, int32 off, int cnt);
#define get_chan(chsa) ((chsa>>8)&0x7f) /* get channel number from ch/sa */

View file

@ -1,6 +1,6 @@
/* sel32_disk.c: SEL-32 2311/2314 Disk Processor II
Copyright (c) 2018-2022, James C. Bevier
Copyright (c) 2018-2023, James C. Bevier
Portions provided by Richard Cornwell and other SIMH contributers
Permission is hereby granted, free of charge, to any person obtaining a
@ -32,6 +32,8 @@
#define UNIT_DISK UNIT_ATTABLE | UNIT_IDLE | UNIT_DISABLE
extern uint32 SPAD[]; /* cpu SPAD memory */
/* useful conversions */
/* Fill STAR value from cyl, trk, sec data */
#define CHS2STAR(c,h,s) (((c<<16) & LMASK)|((h<<8) & 0xff00)|(s & 0xff))
@ -963,6 +965,8 @@ t_stat disk_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
DEVICE *dptr = get_dev(uptr);
int32 unit = (uptr - dptr->units);
CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */
DIB *pdibp = dib_chan[get_chan(chsa)]; /* channel DIB */
CHANP *pchp = pdibp->chan_prg; /* get channel chp */
sim_debug(DEBUG_DETAIL, dptr,
"disk_startcmd chsa %04x unit %02x cmd %02x CMD %08x\n",
@ -990,7 +994,7 @@ t_stat disk_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
case DSK_INCH: /* INCH cmd 0x0 */
sim_debug(DEBUG_CMD, dptr,
"disk_startcmd starting INCH %06x cmd, chsa %04x MemBuf %06x cnt %04x\n",
chp->chan_inch_addr, chsa, chp->ccw_addr, chp->ccw_count);
pchp->chan_inch_addr, chsa, chp->ccw_addr, chp->ccw_count);
uptr->SNS &= ~SNS_CMDREJ; /* not rejected yet */
uptr->CMD |= DSK_INCH2; /* use 0xF0 for inch, just need int */
@ -1105,6 +1109,8 @@ t_stat disk_srv(UNIT *uptr)
uint16 chsa = GET_UADDR(uptr->CMD);
DEVICE *dptr = get_dev(uptr);
CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */
DIB *pdibp = dib_chan[get_chan(chsa)]; /* channel DIB */
CHANP *pchp = pdibp->chan_prg; /* get channel chp */
int cmd = uptr->CMD & DSK_CMDMSK;
int type = GET_TYPE(uptr->flags);
uint32 tcyl=0, trk=0, cyl=0, sec=0, tempt=0;
@ -1146,7 +1152,7 @@ t_stat disk_srv(UNIT *uptr)
mema = chp->ccw_addr; /* get inch or buffer addr */
sim_debug(DEBUG_CMD, dptr,
"disk_srv cmd CONT INCH %06x chsa %04x addr %06x count %04x completed\n",
chp->chan_inch_addr, chsa, mema, chp->ccw_count);
pchp->chan_inch_addr, chsa, mema, chp->ccw_count);
/* to use this inch method, byte count must be 896 */
if (len != 896) {
/* we have invalid count, error, bail out */
@ -1172,7 +1178,7 @@ t_stat disk_srv(UNIT *uptr)
mema = chp->ccw_addr; /* get inch or buffer addr */
sim_debug(DEBUG_CMD, dptr,
"disk_srv starting INCH %06x cmd, chsa %04x MemBuf %06x cnt %04x\n",
chp->chan_inch_addr, chsa, chp->ccw_addr, chp->ccw_count);
pchp->chan_inch_addr, chsa, chp->ccw_addr, chp->ccw_count);
/* mema has IOCD word 1 contents. For the disk processor it contains */
/* a pointer to the INCH buffer followed by 8 drive attribute words that */
@ -1232,7 +1238,7 @@ t_stat disk_srv(UNIT *uptr)
uptr->CMD &= LMASK; /* remove old status bits & cmd */
sim_debug(DEBUG_CMD, dptr,
"disk_srv cmd INCH %06x chsa %04x addr %06x count %04x completed\n",
chp->chan_inch_addr, chsa, mema, chp->ccw_count);
pchp->chan_inch_addr, chsa, mema, chp->ccw_count);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */
break;

View file

@ -1,6 +1,6 @@
/* sel32_ec.c: SEL-32 8516 Ethernet controller.
Copyright (c) 2020-2022, Richard Cornwell
Copyright (c) 2020-2023, Richard Cornwell
Portions provided by James C. Bevier and other SIMH contributers
Permission is hereby granted, free of charge, to any person obtaining a
@ -770,6 +770,8 @@ t_stat ec_srv(UNIT *uptr)
uint8 buf[1520];
uint8 *pck;
struct ec_eth_hdr *hdr;
DIB *pdibp = dib_chan[get_chan(chsa)]; /* channel DIB */
CHANP *pchp = pdibp->chan_prg; /* get channel chp */
sim_debug(DEBUG_CMD, dptr,
"ec_srv chp %p cmd=%02x chsa %04x count %04x SNS %08x\n",
@ -782,7 +784,7 @@ t_stat ec_srv(UNIT *uptr)
mema = chp->ccw_addr; /* get inch or buffer addr */
sim_debug(DEBUG_CMD, dptr,
"ec_srv starting INCH %06x cmd, chsa %04x addr %06x cnt %04x\n",
chp->chan_inch_addr, chsa, chp->ccw_addr, chp->ccw_count);
pchp->chan_inch_addr, chsa, chp->ccw_addr, chp->ccw_count);
/* now call set_inch() function to write and test inch buffer addresses */
/* Ethernet uses 1 dbl wd */
i = set_inch(uptr, mema, 1); /* new address */

View file

@ -1,6 +1,6 @@
/* sel32_fltpt.c: SEL 32 floating point instructions processing.
Copyright (c) 2018-2021, James C. Bevier
Copyright (c) 2018-2023, James C. Bevier
Portions provided by Richard Cornwell, Geert Rolf and other SIMH contributers
Permission is hereby granted, free of charge, to any person obtaining a

View file

@ -1,6 +1,6 @@
/* sel32_hsdp.c: SEL-32 8064 High Speed Disk Processor
Copyright (c) 2018-2022, James C. Bevier
Copyright (c) 2018-2023, James C. Bevier
Portions provided by Richard Cornwell and other SIMH contributers
Permission is hereby granted, free of charge, to any person obtaining a
@ -32,6 +32,8 @@
#define UNIT_HSDP UNIT_ATTABLE | UNIT_IDLE | UNIT_DISABLE
extern uint32 SPAD[]; /* cpu SPAD memory */
/* useful conversions */
/* Fill STAR value from cyl, trk, sec data */
#define CHS2STAR(c,h,s) (((c<<16) & LMASK)|((h<<8) & 0xff00)|(s & 0xff))
@ -1232,7 +1234,7 @@ t_stat hsdp_rsctl(UNIT *uptr) {
sim_cancel(uptr); /* clear the input timer */
chp->ccw_count = 0; /* zero the count */
chp->chan_caw = 0; /* zero iocd address for diags */
chp->ccw_flags &= ~(FLAG_DC|FLAG_CC);/* stop any chaining */
chp->ccw_flags &= ~(FLAG_DC|FLAG_CC); /* stop any chaining */
}
uptr->CMD &= LMASK; /* make non-busy */
uptr->SNS2 |= (SNS_ONC|SNS_UNR); /* on cylinder & ready */
@ -1247,6 +1249,8 @@ t_stat hsdp_srv(UNIT *uptr)
uint16 chsa = GET_UADDR(uptr->CMD);
DEVICE *dptr = get_dev(uptr);
CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */
DIB *pdibp = dib_chan[get_chan(chsa)]; /* channel DIB */
CHANP *pchp = pdibp->chan_prg; /* get channel chp */
int cmd = uptr->CMD & DSK_CMDMSK;
int type = GET_TYPE(uptr->flags);
uint32 tcyl=0, trk=0, cyl=0, sec=0, tempt=0;
@ -1298,7 +1302,7 @@ t_stat hsdp_srv(UNIT *uptr)
mema = chp->ccw_addr; /* get inch or buffer addr */
sim_debug(DEBUG_CMD, dptr,
"hsdp_srv cmd CONT INC %06x chsa %04x addr %06x count %04x completed\n",
chp->chan_inch_addr, chsa, mema, chp->ccw_count);
pchp->chan_inch_addr, chsa, mema, chp->ccw_count);
/* to use this inch method, byte count must be 0x20 */
if (len != 0x20) {
/* we have invalid count, error, bail out */
@ -1357,7 +1361,7 @@ t_stat hsdp_srv(UNIT *uptr)
mema = chp->ccw_addr; /* get inch or buffer addr */
sim_debug(DEBUG_CMD, dptr,
"hsdp_srv starting INCH %06x cmd, chsa %04x MemBuf %06x cnt %04x\n",
chp->chan_inch_addr, chsa, chp->ccw_addr, chp->ccw_count);
pchp->chan_inch_addr, chsa, chp->ccw_addr, chp->ccw_count);
/* mema has IOCD word 1 contents. For the disk processor it contains */
/* a pointer to the INCH buffer followed by 8 drive attribute words that */
@ -1434,7 +1438,7 @@ t_stat hsdp_srv(UNIT *uptr)
uptr->CMD &= LMASK; /* remove old cmd */
sim_debug(DEBUG_CMD, dptr,
"hsdp_srv cmd INCH %06x chsa %04x addr %06x count %04x mode %08x completed\n",
chp->chan_inch_addr, chsa, mema, chp->ccw_count, tcyl);
pchp->chan_inch_addr, chsa, mema, chp->ccw_count, tcyl);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */
break;

View file

@ -198,7 +198,9 @@ t_stat iop_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
iop_chp[0].chan_inch_addr = iop_chp[0].ccw_addr; /* set inch buffer addr */
iop_chp[0].base_inch_addr = iop_chp[0].ccw_addr; /* set inch buffer addr */
iop_chp[0].max_inch_addr = iop_chp[0].ccw_addr + (128 * 8); /* set last inch buffer addr */
//??? iop_chp[0].max_inch_addr = iop_chp[0].ccw_addr + (127 * 8); /* set last inch buffer addr */
/* IOP manual says it uses 128 dbl wds (256 wds) but diag aborts if gtr than 1 dbl wd */
iop_chp[0].max_inch_addr = iop_chp[0].ccw_addr; /* set last inch buffer addr */
uptr->u3 |= IOP_INCH2; /* save INCH command as 0xf0 */
sim_activate(uptr, 40); /* go on */
@ -262,7 +264,8 @@ t_stat iop_srv(UNIT *uptr)
/* now call set_inch() function to write and test inch buffer addresses */
/* the chp->ccw_addr location contains the inch address */
/* 1-256 wd buffer is provided for 128 status dbl words */
tstart = set_inch(uptr, mema, 128); /* new address of 128 entries */
//?? tstart = set_inch(uptr, mema, 128); /* new address of 128 entries */
tstart = set_inch(uptr, mema, 1); /* new address of 128 entries */
if ((tstart == SCPE_MEM) || (tstart == SCPE_ARG)) { /* any error */
/* we have error, bail out */
uptr->u5 |= SNS_CMDREJ;

7214
SEL32/sel32_ipu.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
/* sel32_lpr.c: SEL32 922x & 924x High Speed Line Printer
Copyright (c) 2018-2022, James C. Bevier
Copyright (c) 2018-2023, James C. Bevier
Portions provided by Richard Cornwell and other SIMH contributers
Permission is hereby granted, free of charge, to any person obtaining a

View file

@ -1,6 +1,6 @@
/* sel32_mfp.c: SEL-32 Model 8002 MFP processor controller
Copyright (c) 2018-2022, James C. Bevier
Copyright (c) 2018-2023, James C. Bevier
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -202,8 +202,9 @@ t_stat mfp_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
mfp_chp[0].chan_inch_addr = mfp_chp[0].ccw_addr; /* set inch buffer addr */
mfp_chp[0].base_inch_addr = mfp_chp[0].ccw_addr; /* set inch buffer addr */
mfp_chp[0].max_inch_addr = mfp_chp[0].ccw_addr + (128 * 8); /* set last inch buffer addr */
//??? mfp_chp[0].max_inch_addr = mfp_chp[0].ccw_addr + (127 * 8); /* set last inch buffer addr */
/* MFP manual says it uses 128 dbl wds (256 wds) but diag aborts if gtr than 1 dbl wd */
mfp_chp[0].max_inch_addr = mfp_chp[0].ccw_addr; /* set last inch buffer addr */
uptr->u3 |= MFP_INCH2; /* save INCH command as 0xf0 */
sim_activate(uptr, 40); /* go on */
return 0; /* no status change */
@ -318,7 +319,8 @@ t_stat mfp_srv(UNIT *uptr)
/* now call set_inch() function to write and test inch buffer addresses */
/* the chp->ccw_addr location contains the inch address */
/* 1-256 wd buffer is provided for 128 status dbl words */
tstart = set_inch(uptr, mema, 128); /* new address of 128 entries */
///?? tstart = set_inch(uptr, mema, 128); /* new address of 128 entries */
tstart = set_inch(uptr, mema, 1); /* new address of 1 entrie */
if ((tstart == SCPE_MEM) || (tstart == SCPE_ARG)) { /* any error */
/* we have error, bail out */
uptr->u5 |= SNS_CMDREJ;

View file

@ -1,6 +1,6 @@
/* sel32_mt.c: SEL-32 8051 Buffered Tape Processor
Copyright (c) 2018-2022, James C. Bevier
Copyright (c) 2018-2023, James C. Bevier
Portions provided by Richard Cornwell and other SIMH contributers
Permission is hereby granted, free of charge, to any person obtaining a
@ -41,6 +41,8 @@
#if NUM_DEVS_MT > 0
extern uint32 SPAD[]; /* cpu SPAD memory */
#define BUFFSIZE (64 * 1024)
#define UNIT_MT UNIT_ATTABLE | UNIT_DISABLE | UNIT_ROABLE
@ -389,6 +391,8 @@ t_stat mt_iocl(CHANP *chp, int32 tic_ok)
uint16 chsa = chp->chan_dev;
uint16 devstat = 0;
DEVICE *dptr = get_dev(uptr);
DIB *pdibp = dib_chan[get_chan(chsa)]; /* channel DIB */
CHANP *pchp = pdibp->chan_prg; /* get channel chp */
/* check for valid iocd address if 1st iocd */
if (chp->chan_info & INFO_SIOCD) { /* see if 1st IOCD in channel prog */
@ -461,7 +465,7 @@ loop:
case MT_RDBK: case MT_RDCMP: case MT_REW: case MT_RUN: case MT_FSR:
case MT_BSR: case MT_FSF: case MT_BSF: case MT_SETM: case MT_WTM: case MT_ERG:
/* the inch command must be first command issued */
if ((!loading) && (chp->chan_inch_addr == 0)) {
if ((!loading) && (pchp->chan_inch_addr == 0)) {
chp->chan_status |= STATUS_PCHK; /* program check for invalid cmd */
uptr->SNS |= SNS_CMDREJ; /* cmd rejected */
sim_debug(DEBUG_EXP, dptr,
@ -628,11 +632,12 @@ t_stat mt_preio(UNIT *uptr, uint16 chan) {
DEVICE *dptr = get_dev(uptr);
int unit = (uptr - dptr->units);
uint16 chsa = GET_UADDR(uptr->CMD);
CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */
DIB *pdibp = dib_chan[get_chan(chsa)]; /* channel DIB */
CHANP *pchp = pdibp->chan_prg; /* get channel chp */
sim_debug(DEBUG_CMD, dptr, "mt_preio CMD %08x unit %02x chsa %04x incha %08x\n",
uptr->CMD, unit, chsa, chp->chan_inch_addr);
if ((!loading) && (chp->chan_inch_addr == 0)) {
uptr->CMD, unit, chsa, pchp->chan_inch_addr);
if ((!loading) && (pchp->chan_inch_addr == 0)) {
sim_debug(DEBUG_CMD, dptr,
"mt_preio unit %02x chsa %04x NO INCH\n", unit, chsa);
/* no INCH yet, so do nothing */

View file

@ -1,6 +1,6 @@
/* sel32_scfi.c: SEL-32 SCFI SCSI Disk Controller
Copyright (c) 2018-2022, James C. Bevier
Copyright (c) 2018-2023, James C. Bevier
Portions provided by Richard Cornwell and other SIMH contributers
Permission is hereby granted, free of charge, to any person obtaining a
@ -32,6 +32,8 @@
#define UNIT_SCFI UNIT_ATTABLE | UNIT_IDLE | UNIT_DISABLE
extern uint32 SPAD[]; /* cpu SPAD memory */
/* useful conversions */
/* Fill STAR value from cyl, trk, sec data */
#define CHS2STAR(c,h,s) (((c<<16) & LMASK)|((h<<8) & 0xff00)|(s & 0xff))
@ -671,6 +673,8 @@ t_stat scfi_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
DEVICE *dptr = get_dev(uptr);
int32 unit = (uptr - dptr->units);
CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */
DIB *pdibp = dib_chan[get_chan(chsa)]; /* channel DIB */
CHANP *pchp = pdibp->chan_prg; /* get channel chp */
sim_debug(DEBUG_CMD, dptr,
"scfi_startcmd chsa %04x unit %02x cmd %02x CMD %08x\n",
@ -698,7 +702,7 @@ t_stat scfi_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
case DSK_INCH: /* INCH cmd 0x0 */
sim_debug(DEBUG_CMD, dptr,
"scfi_startcmd starting INCH %06x cmd, chsa %04x MemBuf %06x cnt %04x\n",
chp->chan_inch_addr, chsa, chp->ccw_addr, chp->ccw_count);
pchp->chan_inch_addr, chsa, chp->ccw_addr, chp->ccw_count);
uptr->SNS &= ~SNS_CMDREJ; /* not rejected yet */
uptr->CMD |= DSK_INCH2; /* use 0xF0 for inch, just need int */
@ -797,7 +801,9 @@ t_stat scfi_srv(UNIT *uptr)
{
uint16 chsa = GET_UADDR(uptr->CMD);
DEVICE *dptr = get_dev(uptr);
CHANP *chp = find_chanp_ptr(chsa);/* get channel prog pointer */
CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */
DIB *pdibp = dib_chan[get_chan(chsa)]; /* channel DIB */
CHANP *pchp = pdibp->chan_prg; /* get channel chp */
int cmd = uptr->CMD & DSK_CMDMSK;
int type = GET_TYPE(uptr->flags);
uint32 tcyl=0, trk=0, cyl=0, sec=0;
@ -837,7 +843,7 @@ t_stat scfi_srv(UNIT *uptr)
mema = chp->ccw_addr; /* get inch or buffer addr */
sim_debug(DEBUG_CMD, dptr,
"scfi_srv cmd CONT ICH %06x chsa %04x addr %06x count %04x completed\n",
chp->chan_inch_addr, chsa, mema, chp->ccw_count);
pchp->chan_inch_addr, chsa, mema, chp->ccw_count);
if (len == 0x14) {
/* read all 20 bytes, stopping every 4 bytes to make words */
/* the first word has the inch buffer address */
@ -860,7 +866,7 @@ t_stat scfi_srv(UNIT *uptr)
mema = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | (buf[3]);
sim_debug(DEBUG_CMD, dptr,
"scfi_srv cmd CONT ICH %06x chsa %04x mema %06x completed\n",
chp->chan_inch_addr, chsa, mema);
pchp->chan_inch_addr, chsa, mema);
} else {
/* drive attribute registers */
/* may want to use this later */
@ -868,7 +874,7 @@ t_stat scfi_srv(UNIT *uptr)
tstart = (buf[i-3]<<24) | (buf[i-2]<<16) | (buf[i-1]<<8) | (buf[i]);
sim_debug(DEBUG_CMD, dptr,
"scfi_srv cmd CONT ICH %06x chsa %04x data %06x completed\n",
chp->chan_inch_addr, chsa, tstart);
pchp->chan_inch_addr, chsa, tstart);
}
}
}
@ -899,7 +905,7 @@ t_stat scfi_srv(UNIT *uptr)
mema = chp->ccw_addr; /* get inch or buffer addr */
sim_debug(DEBUG_CMD, dptr,
"scfi_srv starting INCH %06x cmd, chsa %04x MemBuf %06x cnt %04x\n",
chp->chan_inch_addr, chsa, chp->ccw_addr, chp->ccw_count);
pchp->chan_inch_addr, chsa, chp->ccw_addr, chp->ccw_count);
/* mema has IOCD word 1 contents. For the disk processor it contains */
/* a pointer to the INCH buffer followed by 8 drive attribute words that */
@ -979,7 +985,7 @@ gohere:
uptr->CMD &= LMASK; /* remove old status bits & cmd */
sim_debug(DEBUG_CMD, dptr,
"scfi_srv cmd INCH %06x chsa %04x addr %06x count %04x completed\n",
chp->chan_inch_addr, chsa, mema, chp->ccw_count);
pchp->chan_inch_addr, chsa, mema, chp->ccw_count);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */
break;

View file

@ -1,6 +1,6 @@
/* sel32_scsi.c: SEL-32 MFP SCSI Disk controller
Copyright (c) 2018-2022, James C. Bevier
Copyright (c) 2018-2023, James C. Bevier
Portions provided by Richard Cornwell and other SIMH contributers
Permission is hereby granted, free of charge, to any person obtaining a
@ -32,6 +32,8 @@
#define UNIT_SCSI UNIT_ATTABLE | UNIT_IDLE | UNIT_DISABLE
extern uint32 SPAD[]; /* cpu SPAD memory */
/* useful conversions */
/* Fill STAR value from cyl, trk, sec data */
#define CHS2STAR(c,h,s) (((c<<16) & LMASK)|((h<<8) & 0xff00)|(s & 0xff))
@ -565,7 +567,9 @@ t_stat scsi_srv(UNIT *uptr)
/* now call set_inch() function to write and test inch buffer addresses */
/* 1-256 wd buffer is provided for 128 status dbl words */
i = set_inch(uptr, mema, 128); /* new address of 33 entries */
/* manual says 128 entries, but diag aborts if more than 1 */
///?? i = set_inch(uptr, mema, 128); /* new address of 33 entries */
i = set_inch(uptr, mema, 1); /* new address of 1 entrie */
if ((i == SCPE_MEM) || (i == SCPE_ARG)) { /* any error */
/* we have error, bail out */
uptr->CMD &= LMASK; /* remove old status bits & cmd */

View file

@ -1,6 +1,6 @@
/* sel32_sys.c: SEL-32 Gould Concept/32 (orignal SEL-32) Simulator system interface.
Copyright (c) 2018-2022, James C. Bevier
Copyright (c) 2018-2023, James C. Bevier
Portions provided by Richard Cornwell, Geert Rolf and other SIMH contributers
Permission is hereby granted, free of charge, to any person obtaining a
@ -21,11 +21,175 @@
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/* Concept 32 PSD Mode Trap/Interrupt Priorities */
/* Relative|Logical |Int Vect|TCW |IOCD|Description */
/* Priority|Priority|Location|Addr|Addr */
/* - 080 Power Fail Safe Trap */
/* - 084 Power On Trap */
/* - 088 Memory Parity Trap */
/* - 08C Nonpresent Memory Trap */
/* - 090 Undefined Instruction Trap */
/* - 094 Privilege Violation Trap */
/* - 098 Supervisor Call Trap (SVC) */
/* - 09C Machine Check Trap */
/* - 0A0 System Check Trap */
/* - 0A4 Map Fault Trap */
/* - 0A8 CALM or Undefined IPU Instruction Trap */
/* - 0AC Signal CPU or Signal IPU Trap */
/* - 0B0 Address Specification Trap */
/* - 0B4 Console Attention Trap */
/* - 0B8 Privlege Mode Halt Trap */
/* - 0BC Arithmetic Exception Trap */
/* - 0C0 Cache Error Trap (V9 Only) */
/* - 0C4 Demand Page Fault Trap (V6&V9 Only) */
/* */
/* 0 00 100 External/software Interrupt 0 */
/* 1 01 104 External/software Interrupt 1 */
/* 2 02 108 External/software Interrupt 2 */
/* 3 03 10C External/software Interrupt 3 */
/* 4 04 110 704 700 I/O Channel 0 interrupt */
/* 5 05 114 70C 708 I/O Channel 1 interrupt */
/* 6 06 118 714 710 I/O Channel 2 interrupt */
/* 7 07 11C 71C 718 I/O Channel 3 interrupt */
/* 8 08 120 724 720 I/O Channel 4 interrupt */
/* 9 09 124 72C 728 I/O Channel 5 interrupt */
/* A 0A 128 734 730 I/O Channel 6 interrupt */
/* B 0B 12C 73C 738 I/O Channel 7 interrupt */
/* C 0C 130 744 740 I/O Channel 8 interrupt */
/* D 0D 134 74C 748 I/O Channel 9 interrupt */
/* E 0E 138 754 750 I/O Channel A interrupt */
/* F 0F 13C 75C 758 I/O Channel B interrupt */
/* 10 10 140 764 760 I/O Channel C interrupt */
/* 11 11 144 76C 768 I/O Channel D interrupt */
/* 12 12 148 774 770 I/O Channel E interrupt */
/* 13 13 14c 77C 778 I/O Channel F interrupt */
/* 14 14 150 External/Software Interrupt */
/* 15 15 154 External/Software Interrupt */
/* 16 16 158 External/Software Interrupt */
/* 17 17 15C External/Software Interrupt */
/* 18 18 160 Real-Time Clock Interrupt */
/* 19 19 164 External/Software Interrupt */
/* 1A 1A 1A8 External/Software Interrupt */
/* 1B 1B 1AC External/Software Interrupt */
/* 1C 1C 1B0 External/Software Interrupt */
/* THRU THRU THRU THRU */
/* 6C 6C 2B0 External/Software Interrupt */
/* 6D 6D 2B4 External/Software Interrupt */
/* 6E 6E 2B8 External/Software Interrupt */
/* 6F 6F 2BC Interval Timer Interrupt */
/* IVL ------------> ICB Trap/Interrupt Vector Location points to Interrupt Context Block */
/* Wd 0 - Old PSD Word 1 points to return location */
/* Wd 1 - Old PSD Word 2 */
/* Wd 2 - New PSD Word 1 points to first instruction of service routine */
/* Wd 3 - New PSD Word 2 */
/* Wd 4 - CPU Status word at time of interrupt/trap */
/* Wd 5 - N/U For Traps/Interrupts */
/* IVL ------------> ICB XIO Interrupt Vector Location */
/* Wd 0 - Old PSD Word 1 points to return location */
/* Wd 1 - Old PSD Word 2 */
/* Wd 2 - New PSD Word 1 points to first instruction of service routine */
/* Wd 3 - New PSD Word 2 */
/* Wd 4 - Input/Output Command List Address (IOCL) for the Class F I/O CHannel */
/* Wd 5 - 24 bit real address of the channel status word */
/*-----------------------------------------------------------------------------------------------*/
/* Map image descriptor 32/77 */
/* |--------------------------------------| */
/* |0|1|2|3 4 5 6|7 8 9 10 11 12 13 14 15| */
/* |N|V|P| n/u | 9 bit map block entry | */
/* |U| | | | 32kb/block | */
/* | | 32 8kb maps per task | */
/* | | 1 mb address space | */
/* |--------------------------------------| */
/* Map image descriptor 32/27 */
/* |--------------------------------------| */
/* |0|1|2|3|4|5 6 7 8 9 10 11 12 13 14 15| */
/* |V|P|P|P|P| 11 bit map block entry | */
/* | |1|2|3|4| 8kb/block | */
/* | | 256 8kb maps per task | */
/* | | 2 mb address space | */
/* |--------------------------------------| */
/* Map image descriptor 32/67, 32/87, 32/97 */
/* |--------------------------------------| */
/* |0|1|2|3|4|5 6 7 8 9 10 11 12 13 14 15| */
/* |V|P|P|P|P| 11 bit map block entry | */
/* | |1|2|3|4| 2kb/block | */
/* | | 2048 8kb maps per task | */
/* | | 16 mb address space | */
/* |--------------------------------------| */
/* BIT 0 = 0 Invalid map block (page) entry */
/* = 1 Valid map block (page) entry */
/* 1 = 0 000-7ff of 8kb page is not write protected */
/* = 1 000-7ff of 8kb page is write protected */
/* 2 = 0 800-fff of 8kb page is not write protected */
/* = 1 800-fff of 8kb page is write protected */
/* 3 = 0 1000-17ff of 8kb page is not write protected */
/* = 1 1000-17ff of 8kb page is write protected */
/* 4 = 0 1800-1fff of 8kb page is not write protected */
/* = 1 1800-1fff of 8kb page is write protected */
/* 5-15 = 11 most significant bits of the 24 bit real address for page */
/* Map image descriptor V6 & V9 */
/* |--------------------------------------| */
/* |0|1|2|3|4|5 6 7 8 9 10 11 12 13 14 15| */
/* |V|P|P|M|M| 11 bit map block entry | */
/* | |1|2|M|A| 2kb/map | */
/* | | 2048 8kb maps per task | */
/* | | 16 mb address space | */
/* |--------------------------------------| */
/* BIT 0 = 0 Invalid map block (page) entry */
/* = 1 Valid map block (page) entry */
/* */
/* PSD 1 BIT 0 - Map Bit 1 - Map Bit 2 - Access state */
/* Priv Bits with ECO for Access Protection change */
/* 0 0 0 No access allowed to page */
/* 0 0 1 No access allowed to page */
/* 0 1 0 Read/Write/Execute access */
/* 0 1 1 Read/Execute access only */
/*O/S*/
/* 1 0 0 Read/Write/Execute access */
/* 1 0 1 Read/Execute access only */
/* 1 1 0 Read/Write/Execute access */
/* 1 1 1 Read/Execute access only */
/* Priv Bits without ECO for Access Protection change */
/* 0 0 0 No access allowed to page */
/* 0 0 1 Read/Execute access only */
/* 0 1 0 Read//Execute access only */
/* 0 1 1 Read/Write/Execute access */
/*O/S*/
/* 1 0 0 Read/Write/Execute only */
/* 1 0 1 Read/Execute access only */
/* 1 1 0 Read/Write/Execute access */
/* 1 1 1 Read/Write/Execute access */
/* */
/* BIT 3 = 0 (MM) A first write (modify) to the map block (page) has not occurred */
/* = 1 (MM) A first write (modify) to the map block (page) has occurred */
/* BIT 4 = 0 (MA) A first read or write (access) to the map block (page) has not occurred */
/* = 1 (MA) A first read or write (access) to the map block (page) has occurred */
/* 5-15 = 11 most significant bits of the 24 bit real address for page */
/* Note */
/* If a map is valid, a MAP (page) hit occurs and logical to physical translation occures */
/* If the map is not valid, a demand MAP (page) fault occures and the faulting page is provided */
/* P1 and P2 are used with Bit 0 of PSD to define the access rights */
/* A privilege violation trap occurres if access it denied */
/* Bits 5-15 contain the 11 most-significant bits of the physical address */
/* MSD 0 page limit is used to verify access to O/S pages */
/* CPIXPL page limit is used to verify access to user pages and page faults */
/* CPIX CPIX of user MPL offset */
/* Access to pages outside the limit registers results in a map fault */
/*-----------------------------------------------------------------------------------------------*/
#include "sel32_defs.h"
#include <ctype.h>
extern REG cpu_reg[];
extern uint32 M[MAXMEMSIZE];
extern uint32 SPAD[];
extern uint32 PSD[];
char *dump_mem(uint32 mp, int cnt);
@ -59,6 +223,9 @@ int32 sim_emax = 4; /* maximum number of instructions/wo
DEVICE *sim_devices[] = {
&cpu_dev,
#ifdef USE_IPU_THREAD
&ipu_dev,
#endif
#ifdef NUM_DEVS_IOP
&iop_dev, /* IOP channel controller */
#endif
@ -231,8 +398,6 @@ char *dump_buf(uint8 *mp, int32 off, int cnt)
return (line); /* return pointer to caller */
}
/*
* get_word - function to load a 32 bit word from the input file
* return 1 - OK

View file

@ -242,6 +242,10 @@
RelativePath="..\SEL32\sel32_iop.c"
>
</File>
<File
RelativePath="..\SEL32\sel32_ipu.c"
>
</File>
<File
RelativePath="..\SEL32\sel32_lpr.c"
>

View file

@ -2124,7 +2124,7 @@ SEL32 = ${SEL32D}/sel32_cpu.c ${SEL32D}/sel32_sys.c ${SEL32D}/sel32_chan.c \
${SEL32D}/sel32_clk.c ${SEL32D}/sel32_mt.c ${SEL32D}/sel32_lpr.c \
${SEL32D}/sel32_scfi.c ${SEL32D}/sel32_fltpt.c ${SEL32D}/sel32_disk.c \
${SEL32D}/sel32_hsdp.c ${SEL32D}/sel32_mfp.c ${SEL32D}/sel32_scsi.c \
${SEL32D}/sel32_ec.c
${SEL32D}/sel32_ec.c ${SEL32D}/sel32_ipu.c
SEL32_OPT = -I $(SEL32D) -DUSE_INT32 -DSEL32 ${NETWORK_OPT}
###