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:
parent
5e01c0516b
commit
4e159a04ed
21 changed files with 10185 additions and 1997 deletions
|
@ -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
|
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
|
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
|
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
|
# 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
|
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
|
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
|
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
|
set and a virtual memory system supported by the V6 & V9 CPUs. The IPU is
|
||||||
needs further testing to solidify the SEL32 simulator code in all of the
|
also supported by UTX and MPX-32. The system needs further testing to
|
||||||
supported environmenets and hardware configurations.
|
solidify the SEL32 simulator code in all of the supported environmenets
|
||||||
|
and hardware configurations.
|
||||||
|
|
||||||
# SEL32 installation configuration files in the installs directory:
|
# 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
|
Testing is extremely difficult without any source for the
|
||||||
diagnostics. Updates to follow as tests are corrected.
|
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:
|
Other MPX versions support:
|
||||||
I have recently received some old MPX 3.X save tapes. Using
|
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
|
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.
|
thankfull. Please keep looking.
|
||||||
|
|
||||||
James C. Bevier
|
James C. Bevier
|
||||||
02/28/2022
|
01/03/2023
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
||||||
/* sel32_clk.c: SEL 32 Class F IOP processor RTOM functions.
|
/* 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
|
Portions provided by Richard Cornwell, Geert Rolf and other SIMH contributers
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
@ -44,12 +44,11 @@ t_stat rtc_show_freq (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
||||||
t_stat rtc_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, CONST char *cptr);
|
t_stat rtc_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, CONST char *cptr);
|
||||||
const char *rtc_desc(DEVICE *dptr);
|
const char *rtc_desc(DEVICE *dptr);
|
||||||
|
|
||||||
extern int irq_pend; /* go scan for pending int or I/O */
|
extern int irq_pend; /* go scan for pending int or I/O */
|
||||||
extern uint32 INTS[]; /* interrupt control flags */
|
extern uint32 INTS[]; /* interrupt control flags */
|
||||||
extern uint32 SPAD[]; /* computer SPAD */
|
extern uint32 SPAD[]; /* computer SPAD */
|
||||||
extern uint32 M[]; /* system memory */
|
extern uint32 outbusy; /* output waiting on timeout */
|
||||||
extern uint32 outbusy; /* output waiting on timeout */
|
extern uint32 inbusy; /* input waiting on timeout */
|
||||||
extern uint32 inbusy; /* input waiting on timeout */
|
|
||||||
|
|
||||||
int32 rtc_pie = 0; /* rtc pulse ie */
|
int32 rtc_pie = 0; /* rtc pulse ie */
|
||||||
int32 rtc_tps = 60; /* rtc ticks/sec */
|
int32 rtc_tps = 60; /* rtc ticks/sec */
|
||||||
|
@ -112,7 +111,7 @@ t_stat rtc_srv (UNIT *uptr)
|
||||||
#endif
|
#endif
|
||||||
/* if clock disabled, do not do interrupts */
|
/* if clock disabled, do not do interrupts */
|
||||||
if (((rtc_dev.flags & DEV_DIS) == 0) && rtc_pie) {
|
if (((rtc_dev.flags & DEV_DIS) == 0) && rtc_pie) {
|
||||||
int lev = 0x13;
|
int lev = rtc_lvl;
|
||||||
sim_debug(DEBUG_CMD, &rtc_dev,
|
sim_debug(DEBUG_CMD, &rtc_dev,
|
||||||
"RT Clock mfp INTS[%02x] %08x SPAD[%02x] %08x\n",
|
"RT Clock mfp INTS[%02x] %08x SPAD[%02x] %08x\n",
|
||||||
lev, INTS[lev], lev+0x80, SPAD[lev+0x80]);
|
lev, INTS[lev], lev+0x80, SPAD[lev+0x80]);
|
||||||
|
@ -127,22 +126,24 @@ t_stat rtc_srv (UNIT *uptr)
|
||||||
/* HACK for console I/O stopping */
|
/* HACK for console I/O stopping */
|
||||||
/* This reduces the number of console I/O stopping errors */
|
/* This reduces the number of console I/O stopping errors */
|
||||||
/* need to find real cause of I/O stopping on clock interrupt */
|
/* 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 */
|
INTS[rtc_lvl] |= INTS_REQ; /* request the interrupt */
|
||||||
else
|
irq_pend = 1; /* make sure we scan for int */
|
||||||
sim_debug(DEBUG_CMD, &rtc_dev,
|
} else {
|
||||||
"RT Clock int console busy\n");
|
sim_debug(DEBUG_CMD, &rtc_dev,
|
||||||
|
"RT Clock int console busy\n");
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
INTS[rtc_lvl] |= INTS_REQ; /* request the interrupt */
|
INTS[rtc_lvl] |= INTS_REQ; /* request the interrupt */
|
||||||
#endif
|
|
||||||
irq_pend = 1; /* make sure we scan for int */
|
irq_pend = 1; /* make sure we scan for int */
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
sim_debug(DEBUG_CMD, &rtc_dev,
|
sim_debug(DEBUG_CMD, &rtc_dev,
|
||||||
"RT Clock int INTS[%02x] %08x SPAD[%02x] %08x\n",
|
"RT Clock int INTS[%02x] %08x SPAD[%02x] %08x\n",
|
||||||
rtc_lvl, INTS[rtc_lvl], rtc_lvl+0x80, SPAD[rtc_lvl+0x80]);
|
rtc_lvl, INTS[rtc_lvl], rtc_lvl+0x80, SPAD[rtc_lvl+0x80]);
|
||||||
}
|
}
|
||||||
// temp = sim_rtcn_calb(rtc_tps, TMR_RTC); /* timer 0 for RTC */
|
// temp = sim_rtcn_calb(rtc_tps, TMR_RTC); /* timer 0 for RTC */
|
||||||
sim_rtcn_calb(rtc_tps, TMR_RTC); /* timer 0 for RTC */
|
sim_rtcn_calb(rtc_tps, TMR_RTC); /* timer 0 for RTC */
|
||||||
sim_activate_after(uptr, 1000000/rtc_tps); /* reactivate 16666 tics / sec */
|
sim_activate_after(uptr, 1000000/rtc_tps); /* reactivate 16666 tics / sec */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
@ -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_reset (DEVICE *dptr);
|
||||||
t_stat itm_show_freq (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
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);
|
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);
|
const char *itm_desc(DEVICE *dptr);
|
||||||
|
|
||||||
/* Clock data structures
|
/* Clock data structures
|
||||||
|
@ -370,6 +372,9 @@ int32 itm_rdwr(uint32 cmd, int32 cnt, uint32 level)
|
||||||
|
|
||||||
cmd &= 0x7f; /* just need the cmd */
|
cmd &= 0x7f; /* just need the cmd */
|
||||||
itm_cmd = cmd; /* save last cmd */
|
itm_cmd = cmd; /* save last cmd */
|
||||||
|
if (itm_pie == 0) { /* timer enabled? */
|
||||||
|
itm_setup(1, level); /* no, initialize it */
|
||||||
|
}
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case 0x20: /* stop timer */
|
case 0x20: /* stop timer */
|
||||||
/* stop the timer and save the curr value for later */
|
/* 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 */
|
/* level = interrupt level */
|
||||||
void itm_setup(uint32 ss, uint32 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_lvl = level; /* save the interrupt level */
|
||||||
itm_load = 0; /* not loaded */
|
itm_load = 0; /* not loaded */
|
||||||
itm_src = 0; /* use itm for freq */
|
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 */
|
itm_cnt = 0; /* no count reset value */
|
||||||
sim_cancel (&itm_unit); /* not running yet */
|
sim_cancel (&itm_unit); /* not running yet */
|
||||||
if (ss == 1) { /* starting? */
|
if (ss == 1) { /* starting? */
|
||||||
|
#ifdef NOT_HERE_112422
|
||||||
INTS[level] |= INTS_ENAB; /* make sure enabled */
|
INTS[level] |= INTS_ENAB; /* make sure enabled */
|
||||||
SPAD[level+0x80] |= SINT_ENAB; /* in spad too */
|
SPAD[level+0x80] |= SINT_ENAB; /* in spad too */
|
||||||
|
#endif
|
||||||
sim_debug(DEBUG_CMD, &itm_dev,
|
sim_debug(DEBUG_CMD, &itm_dev,
|
||||||
"Intv Timer setup enable int %02x value %08x itm_pie %01x ss %01x\n",
|
"Intv Timer setup enable int %02x value %08x itm_pie %01x ss %01x\n",
|
||||||
itm_lvl, itm_cnt, itm_pie, ss);
|
itm_lvl, itm_cnt, itm_pie, ss);
|
||||||
} else {
|
} else {
|
||||||
|
#ifdef NOT_HERE_112422
|
||||||
INTS[level] &= ~INTS_ENAB; /* make sure disabled */
|
INTS[level] &= ~INTS_ENAB; /* make sure disabled */
|
||||||
SPAD[level+0x80] &= ~SINT_ENAB; /* in spad too */
|
SPAD[level+0x80] &= ~SINT_ENAB; /* in spad too */
|
||||||
|
#endif
|
||||||
sim_debug(DEBUG_CMD, &itm_dev,
|
sim_debug(DEBUG_CMD, &itm_dev,
|
||||||
"Intv Timer setup disable int %02x value %08x itm_pie %01x ss %01x\n",
|
"Intv Timer setup disable int %02x value %08x itm_pie %01x ss %01x\n",
|
||||||
itm_lvl, itm_cnt, itm_pie, ss);
|
itm_lvl, itm_cnt, itm_pie, ss);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* sel32_com.c: SEL 32 8-Line IOP communications controller
|
/* 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
|
Portions provided by Richard Cornwell and other SIMH contributers
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* sel32_con.c: SEL 32 Class F IOP processor console.
|
/* 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
|
Portions provided by Richard Cornwell, Geert Rolf and other SIMH contributers
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
@ -34,8 +34,11 @@
|
||||||
|
|
||||||
#if NUM_DEVS_CON > 0
|
#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
|
#define CMD u3
|
||||||
/* Held in u3 is the device command and status */
|
/* Held in u3 is the device command and status */
|
||||||
#define CON_INCH 0x00 /* Initialize channel command */
|
#define CON_INCH 0x00 /* Initialize channel command */
|
||||||
|
@ -113,8 +116,8 @@ MTAB con_mod[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
UNIT con_unit[] = {
|
UNIT con_unit[] = {
|
||||||
{UDATA(&con_srvi, UNIT_CON, 0), 0, UNIT_ADDR(0x7EFC)}, /* 0 Input */
|
{UDATA(&con_srvi, UNIT_CON, 0), CON_WAIT, UNIT_ADDR(0x7EFC)}, /* 0 Input */
|
||||||
{UDATA(&con_srvo, UNIT_CON, 0), 0, UNIT_ADDR(0x7EFD)}, /* 1 Output */
|
{UDATA(&con_srvo, UNIT_CON, 0), CON_WAIT, UNIT_ADDR(0x7EFD)}, /* 1 Output */
|
||||||
};
|
};
|
||||||
|
|
||||||
DIB con_dib = {
|
DIB con_dib = {
|
||||||
|
@ -179,52 +182,133 @@ t_stat con_preio(UNIT *uptr, uint16 chan) {
|
||||||
|
|
||||||
/* start an I/O operation */
|
/* start an I/O operation */
|
||||||
t_stat con_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
|
t_stat con_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
|
||||||
DEVICE *dptr = uptr->dptr;
|
DEVICE *dptr = uptr->dptr;
|
||||||
int unit = (uptr - con_unit); /* unit 0 is read, unit 1 is write */
|
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 */
|
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",
|
"con_startcmd unit %01x chan %02x cmd %02x BUSY cmd %02x uptr %p\n",
|
||||||
unit, chan, cmd, uptr->CMD, uptr);
|
unit, chan, cmd, uptr->CMD, uptr);
|
||||||
return SNS_BSY; /* yes, return busy */
|
return SNS_BSY; /* yes, return busy */
|
||||||
}
|
}
|
||||||
|
|
||||||
sim_debug(DEBUG_DETAIL, dptr,
|
sim_debug(DEBUG_CMD, dptr,
|
||||||
"con_startcmd unit %01x chan %02x cmd %02x enter\n", unit, chan, cmd);
|
"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)
|
if (cmd == CON_INCH)
|
||||||
cmd = CON_INCH2; /* save INCH command as 0xf0 */
|
cmd = CON_INCH2; /* save INCH command as 0xf0 */
|
||||||
|
|
||||||
/* process the commands */
|
/* process the commands */
|
||||||
switch (cmd & 0xFF) {
|
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 */
|
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 */
|
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 */
|
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 &= ~CON_MSK; /* remove old CMD */
|
||||||
uptr->CMD |= (cmd & CON_MSK); /* save command */
|
uptr->CMD |= (cmd & CON_MSK); /* save command */
|
||||||
|
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, 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 (unit == 0) {
|
||||||
sim_cancel(uptr); /* stop input poll */
|
/* if output requested for input device, give error */
|
||||||
sim_activate(uptr, 300); /* start us off */
|
uptr->SNS |= SNS_CMDREJ; /* command rejected */
|
||||||
// sim_activate(uptr, 1000); /* start us off */
|
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 */
|
/* using value 500 or larger causes diag to fail on 32/27 */
|
||||||
// sim_activate(uptr, 500); /* start us off */
|
/* using value 230 or larger causes UTX21B to fail on 32/67 */
|
||||||
// sim_activate(uptr, 200); /* start us off */
|
/* 32/67 error sequence */
|
||||||
sim_activate(uptr, 30); /* start us off */
|
/* 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 */
|
return SCPE_OK; /* no status change */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -233,7 +317,7 @@ t_stat con_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
|
||||||
}
|
}
|
||||||
/* invalid command */
|
/* invalid command */
|
||||||
uptr->SNS |= SNS_CMDREJ; /* command rejected */
|
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",
|
"con_startcmd %04x: Invalid command %02x Sense %02x\n",
|
||||||
chan, cmd, uptr->SNS);
|
chan, cmd, uptr->SNS);
|
||||||
return SNS_CHNEND|SNS_DEVEND|STATUS_PCHK;
|
return SNS_CHNEND|SNS_DEVEND|STATUS_PCHK;
|
||||||
|
@ -259,43 +343,16 @@ t_stat con_srvo(UNIT *uptr) {
|
||||||
|
|
||||||
switch (cmd) {
|
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 */
|
case CON_INCH2: /* 0xf0 */ /* INCH command */
|
||||||
uptr->CMD &= LMASK; /* nothing left, command complete */
|
uptr->CMD &= LMASK; /* nothing left, command complete */
|
||||||
sim_debug(DEBUG_CMD, dptr,
|
sim_debug(DEBUG_CMD, dptr,
|
||||||
"con_srvo INCH unit %02x: CMD %08x cmd %02x incnt %02x u4 %02x\n",
|
"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);
|
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 */
|
/* now call set_inch() function to write and test inch buffer addresses */
|
||||||
/* 1-256 wd buffer is provided for 128 status dbl words */
|
/* 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 */
|
if ((tstart == SCPE_MEM) || (tstart == SCPE_ARG)) { /* any error */
|
||||||
/* we have error, bail out */
|
/* we have error, bail out */
|
||||||
uptr->SNS |= SNS_CMDREJ;
|
uptr->SNS |= SNS_CMDREJ;
|
||||||
|
@ -306,94 +363,21 @@ t_stat con_srvo(UNIT *uptr) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sim_debug(DEBUG_CMD, dptr,
|
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 */
|
/* WARNING, if SNS_DEVEND is not set, diags fail by looping in CON diag */
|
||||||
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */
|
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CON_NOP: /* 0x03 */ /* NOP has do nothing */
|
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,
|
sim_debug(DEBUG_CMD, dptr,
|
||||||
"con_srvo NOP CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd);
|
"con_srvo NOP CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd);
|
||||||
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */
|
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */
|
||||||
break;
|
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_RWD: /* 0x37 */ /* TOF and write line */
|
||||||
case CON_WR: /* 0x01 */ /* Write command */
|
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 */
|
cnt = 0; /* zero count */
|
||||||
/*RTC*/ outbusy = 1; /* tell clock output waiting */
|
/*RTC*/ outbusy = 1; /* tell clock output waiting */
|
||||||
mema = chp->ccw_addr; /* get buffer addr */
|
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 */
|
ch &= 0x7f; /* make 7 bit w/o parity */
|
||||||
dexp = dexp<<8; /* move up last chars */
|
dexp = dexp<<8; /* move up last chars */
|
||||||
dexp |= ch; /* insert new char */
|
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 */
|
sim_putchar(ch); /* output next char to device */
|
||||||
if (isprint(ch))
|
if (isprint(ch))
|
||||||
sim_debug(DEBUG_CMD, dptr,
|
sim_debug(DEBUG_CMD, dptr,
|
||||||
|
@ -433,7 +407,6 @@ t_stat con_srvo(UNIT *uptr) {
|
||||||
/*RTC*/ outbusy = 0; /* output done */
|
/*RTC*/ outbusy = 0; /* output done */
|
||||||
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */
|
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
@ -450,29 +423,18 @@ t_stat con_srvi(UNIT *uptr) {
|
||||||
uint32 tstart;
|
uint32 tstart;
|
||||||
uint8 ch;
|
uint8 ch;
|
||||||
t_stat r;
|
t_stat r;
|
||||||
int32 wait_time=10000;
|
|
||||||
|
|
||||||
switch (cmd) {
|
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 */
|
case CON_INCH2: /* 0xf0 */ /* INCH command */
|
||||||
uptr->CMD &= LMASK; /* nothing left, command complete */
|
uptr->CMD &= LMASK; /* nothing left, command complete */
|
||||||
sim_debug(DEBUG_CMD, dptr,
|
sim_debug(DEBUG_CMD, dptr,
|
||||||
"con_srvi INCH unit %02x: CMD %08x cmd %02x incnt %02x u4 %02x inch %06x\n",
|
"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);
|
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 */
|
/* 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 */
|
if ((tstart == SCPE_MEM) || (tstart == SCPE_ARG)) { /* any error */
|
||||||
/* we have error, bail out */
|
/* we have error, bail out */
|
||||||
uptr->SNS |= SNS_CMDREJ;
|
uptr->SNS |= SNS_CMDREJ;
|
||||||
|
@ -485,56 +447,21 @@ t_stat con_srvi(UNIT *uptr) {
|
||||||
con_data[unit].incnt = 0; /* buffer empty */
|
con_data[unit].incnt = 0; /* buffer empty */
|
||||||
uptr->u4 = 0; /* no I/O yet */
|
uptr->u4 = 0; /* no I/O yet */
|
||||||
sim_debug(DEBUG_CMD, dptr,
|
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 */
|
/* WARNING, if SNS_DEVEND is not set, diags fail by looping in CON diag */
|
||||||
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */
|
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */
|
||||||
/* drop through to poll input */
|
/* drop through to poll input */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CON_NOP: /* 0x03 */ /* NOP has do nothing */
|
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,
|
sim_debug(DEBUG_CMD, dptr,
|
||||||
"con_srvi NOP CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd);
|
"con_srvi NOP CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd);
|
||||||
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */
|
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */
|
||||||
/* drop through to poll input */
|
/* drop through to poll input */
|
||||||
break;
|
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 */
|
case CON_ECHO: /* 0x0a */ /* read from device w/ECHO */
|
||||||
uptr->CMD |= CON_EKO; /* save echo status */
|
uptr->CMD |= CON_EKO; /* save echo status */
|
||||||
case CON_RD: /* 0x02 */ /* read from device */
|
case CON_RD: /* 0x02 */ /* read from device */
|
||||||
|
@ -551,10 +478,6 @@ t_stat con_srvi(UNIT *uptr) {
|
||||||
sim_debug(DEBUG_IRQ, dptr,
|
sim_debug(DEBUG_IRQ, dptr,
|
||||||
"con_srvi readbuf unit %02x: CMD %08x read %02x incnt %02x u4 %02x len %02x\n",
|
"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);
|
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 */
|
/* process any characters */
|
||||||
if (uptr->u4 != con_data[unit].incnt) { /* input available */
|
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 */
|
if (uptr->u4 == con_data[unit].incnt) { /* input empty */
|
||||||
uptr->CMD &= ~CON_INPUT; /* no input available */
|
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;
|
break;
|
||||||
}
|
}
|
||||||
/* command is completed */
|
/* command is completed */
|
||||||
|
@ -607,10 +527,6 @@ t_stat con_srvi(UNIT *uptr) {
|
||||||
sim_debug(DEBUG_CMD, dptr,
|
sim_debug(DEBUG_CMD, dptr,
|
||||||
"con_srvi read done unit %02x CMD %08x read %02x u4 %02x ccw_count %02x incnt %02x\n",
|
"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);
|
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 */
|
cmd = 0; /* no cmd now */
|
||||||
uptr->CMD &= LMASK; /* nothing left, command complete */
|
uptr->CMD &= LMASK; /* nothing left, command complete */
|
||||||
if (uptr->u4 != con_data[unit].incnt) { /* input empty */
|
if (uptr->u4 != con_data[unit].incnt) { /* input empty */
|
||||||
|
@ -648,10 +564,6 @@ t_stat con_srvi(UNIT *uptr) {
|
||||||
sim_debug(DEBUG_CMD, dptr,
|
sim_debug(DEBUG_CMD, dptr,
|
||||||
"con_srvi handle readch unit %02x: CMD %08x read %02x u4 %02x incnt %02x r %x\n",
|
"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);
|
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 */
|
/* put char in buffer */
|
||||||
con_data[unit].ibuff[con_data[unit].incnt++] = ch;
|
con_data[unit].ibuff[con_data[unit].incnt++] = ch;
|
||||||
|
@ -669,7 +581,10 @@ t_stat con_srvi(UNIT *uptr) {
|
||||||
sim_debug(DEBUG_CMD, dptr,
|
sim_debug(DEBUG_CMD, dptr,
|
||||||
"con_srvi readch unit %02x: CMD %08x read %02x u4 %02x incnt %02x\n",
|
"con_srvi readch unit %02x: CMD %08x read %02x u4 %02x incnt %02x\n",
|
||||||
unit, uptr->CMD, ch, uptr->u4, con_data[unit].incnt);
|
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 */
|
//01172021 sim_activate(uptr, 400); /* do this again */
|
||||||
// sim_activate(uptr, 800); /* do this again */
|
// sim_activate(uptr, 800); /* do this again */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
@ -700,7 +615,9 @@ t_stat con_srvi(UNIT *uptr) {
|
||||||
con_data[unit].incnt = 0; /* no input data */
|
con_data[unit].incnt = 0; /* no input data */
|
||||||
}
|
}
|
||||||
// sim_activate(uptr, wait_time); /* do this again */
|
// 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 */
|
// sim_activate(uptr, 4000); /* do this again */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
@ -731,14 +648,10 @@ t_stat con_srvi(UNIT *uptr) {
|
||||||
sim_debug(DEBUG_CMD, dptr,
|
sim_debug(DEBUG_CMD, dptr,
|
||||||
"con_srvi readch2 unit %02x: CMD %08x read %02x u4 %02x incnt %02x r %x\n",
|
"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);
|
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;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -753,7 +666,6 @@ t_stat con_rschnlio(UNIT *uptr) {
|
||||||
int cmd = uptr->CMD & CON_MSK;
|
int cmd = uptr->CMD & CON_MSK;
|
||||||
con_ini(uptr, 0); /* reset the unit */
|
con_ini(uptr, 0); /* reset the unit */
|
||||||
sim_debug(DEBUG_EXP, &con_dev, "con_rschnl chsa %04x cmd = %02x\n", chsa, cmd);
|
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;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -795,5 +707,5 @@ t_stat con_haltio(UNIT *uptr) {
|
||||||
chsa, cmd, chp->ccw_count);
|
chsa, cmd, chp->ccw_count);
|
||||||
return CC1BIT | SCPE_OK; /* not busy */
|
return CC1BIT | SCPE_OK; /* not busy */
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* #if NUM_DEVS_CON > 0 */
|
||||||
|
|
||||||
|
|
3223
SEL32/sel32_cpu.c
3223
SEL32/sel32_cpu.c
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
||||||
/* sel32_defs.h: SEL-32 Concept/32 simulator definitions
|
/* 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
|
Portions provided by Richard Cornwell, Geert Rolf and other SIMH contributers
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
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.
|
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 */
|
#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 */
|
/* Simulator stop codes */
|
||||||
#define STOP_IONRDY 1 /* I/O dev not ready */
|
#define STOP_IONRDY 1 /* I/O dev not ready */
|
||||||
#define STOP_HALT 2 /* HALT */
|
#define STOP_HALT 2 /* HALT */
|
||||||
|
@ -142,6 +232,10 @@
|
||||||
|
|
||||||
extern DEVICE cpu_dev; /* cpu device */
|
extern DEVICE cpu_dev; /* cpu device */
|
||||||
extern UNIT cpu_unit; /* the cpu unit */
|
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
|
#ifdef NUM_DEVS_IOP
|
||||||
extern DEVICE iop_dev; /* IOP channel controller */
|
extern DEVICE iop_dev; /* IOP channel controller */
|
||||||
#endif
|
#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 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 */
|
#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_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 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_MSIZE (0x1F << UNIT_V_MSIZE)
|
||||||
|
#define UNIT_IPU (0x1 << UNIT_V_IPU)
|
||||||
#define MEMAMOUNT(x) (x << UNIT_V_MSIZE)
|
#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_55 0 /* 512K Mode Only */
|
||||||
#define MODEL_75 1 /* Extended */
|
#define MODEL_75 1 /* Extended */
|
||||||
|
@ -361,6 +458,12 @@ extern DEBTAB dev_debug[];
|
||||||
#define MODEL_97 5 /* */
|
#define MODEL_97 5 /* */
|
||||||
#define MODEL_V6 6 /* V6 CPU */
|
#define MODEL_V6 6 /* V6 CPU */
|
||||||
#define MODEL_V9 7 /* V9 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 1 /* RTC will not work if set to 0!! */
|
||||||
//#define TMR_RTC 0
|
//#define TMR_RTC 0
|
||||||
|
@ -375,10 +478,12 @@ extern DEBTAB dev_debug[];
|
||||||
#define CC3BIT 0x10000000 /* CC3 in PSD1 */
|
#define CC3BIT 0x10000000 /* CC3 in PSD1 */
|
||||||
#define CC4BIT 0x08000000 /* CC4 in PSD1 */
|
#define CC4BIT 0x08000000 /* CC4 in PSD1 */
|
||||||
|
|
||||||
#define MAPMODE 0x40 /* Map mode, PSD 2 bit 0 */
|
#define IPUMODE 0x20 /* This is running on IPU, bit 27 of CPUSTATUS */
|
||||||
#define RETMODE 0x20 /* Retain current maps, PSD 2 bit 15 */
|
#define INTBLKD 0x10 /* bit 24 of CPUSTATUS word, set if ints blocked */
|
||||||
#define RETBLKM 0x10 /* Set retain blocked mode, PSD 2 bit 16 */
|
|
||||||
#define BLKMODE 0x08 /* Set blocked mode, PSD 2 bit 17 */
|
#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 */
|
/* PSD mode bits in PSD words 1&2 variable */
|
||||||
#define PRIVBIT 0x80000000 /* Privileged mode PSD 1 bit 0 */
|
#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 */
|
/* Rename of global PC variable to avoid namespace conflicts on some platforms */
|
||||||
#define PC PC_Global
|
#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 */
|
/* memory access macros */
|
||||||
/* The RMW and WMW macros are used to read/write memory words */
|
/* 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 */
|
/* 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 */
|
/* 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)))
|
#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 */
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* sel32_disk.c: SEL-32 2311/2314 Disk Processor II
|
/* 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
|
Portions provided by Richard Cornwell and other SIMH contributers
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
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
|
#define UNIT_DISK UNIT_ATTABLE | UNIT_IDLE | UNIT_DISABLE
|
||||||
|
|
||||||
|
extern uint32 SPAD[]; /* cpu SPAD memory */
|
||||||
|
|
||||||
/* useful conversions */
|
/* useful conversions */
|
||||||
/* Fill STAR value from cyl, trk, sec data */
|
/* Fill STAR value from cyl, trk, sec data */
|
||||||
#define CHS2STAR(c,h,s) (((c<<16) & LMASK)|((h<<8) & 0xff00)|(s & 0xff))
|
#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);
|
DEVICE *dptr = get_dev(uptr);
|
||||||
int32 unit = (uptr - dptr->units);
|
int32 unit = (uptr - dptr->units);
|
||||||
CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */
|
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,
|
sim_debug(DEBUG_DETAIL, dptr,
|
||||||
"disk_startcmd chsa %04x unit %02x cmd %02x CMD %08x\n",
|
"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 */
|
case DSK_INCH: /* INCH cmd 0x0 */
|
||||||
sim_debug(DEBUG_CMD, dptr,
|
sim_debug(DEBUG_CMD, dptr,
|
||||||
"disk_startcmd starting INCH %06x cmd, chsa %04x MemBuf %06x cnt %04x\n",
|
"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->SNS &= ~SNS_CMDREJ; /* not rejected yet */
|
||||||
uptr->CMD |= DSK_INCH2; /* use 0xF0 for inch, just need int */
|
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);
|
uint16 chsa = GET_UADDR(uptr->CMD);
|
||||||
DEVICE *dptr = get_dev(uptr);
|
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 cmd = uptr->CMD & DSK_CMDMSK;
|
||||||
int type = GET_TYPE(uptr->flags);
|
int type = GET_TYPE(uptr->flags);
|
||||||
uint32 tcyl=0, trk=0, cyl=0, sec=0, tempt=0;
|
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 */
|
mema = chp->ccw_addr; /* get inch or buffer addr */
|
||||||
sim_debug(DEBUG_CMD, dptr,
|
sim_debug(DEBUG_CMD, dptr,
|
||||||
"disk_srv cmd CONT INCH %06x chsa %04x addr %06x count %04x completed\n",
|
"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 */
|
/* to use this inch method, byte count must be 896 */
|
||||||
if (len != 896) {
|
if (len != 896) {
|
||||||
/* we have invalid count, error, bail out */
|
/* 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 */
|
mema = chp->ccw_addr; /* get inch or buffer addr */
|
||||||
sim_debug(DEBUG_CMD, dptr,
|
sim_debug(DEBUG_CMD, dptr,
|
||||||
"disk_srv starting INCH %06x cmd, chsa %04x MemBuf %06x cnt %04x\n",
|
"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 */
|
/* 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 */
|
/* 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 */
|
uptr->CMD &= LMASK; /* remove old status bits & cmd */
|
||||||
sim_debug(DEBUG_CMD, dptr,
|
sim_debug(DEBUG_CMD, dptr,
|
||||||
"disk_srv cmd INCH %06x chsa %04x addr %06x count %04x completed\n",
|
"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 */
|
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* sel32_ec.c: SEL-32 8516 Ethernet controller.
|
/* 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
|
Portions provided by James C. Bevier and other SIMH contributers
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
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 buf[1520];
|
||||||
uint8 *pck;
|
uint8 *pck;
|
||||||
struct ec_eth_hdr *hdr;
|
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,
|
sim_debug(DEBUG_CMD, dptr,
|
||||||
"ec_srv chp %p cmd=%02x chsa %04x count %04x SNS %08x\n",
|
"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 */
|
mema = chp->ccw_addr; /* get inch or buffer addr */
|
||||||
sim_debug(DEBUG_CMD, dptr,
|
sim_debug(DEBUG_CMD, dptr,
|
||||||
"ec_srv starting INCH %06x cmd, chsa %04x addr %06x cnt %04x\n",
|
"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 */
|
/* now call set_inch() function to write and test inch buffer addresses */
|
||||||
/* Ethernet uses 1 dbl wd */
|
/* Ethernet uses 1 dbl wd */
|
||||||
i = set_inch(uptr, mema, 1); /* new address */
|
i = set_inch(uptr, mema, 1); /* new address */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* sel32_fltpt.c: SEL 32 floating point instructions processing.
|
/* 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
|
Portions provided by Richard Cornwell, Geert Rolf and other SIMH contributers
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* sel32_hsdp.c: SEL-32 8064 High Speed Disk Processor
|
/* 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
|
Portions provided by Richard Cornwell and other SIMH contributers
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
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
|
#define UNIT_HSDP UNIT_ATTABLE | UNIT_IDLE | UNIT_DISABLE
|
||||||
|
|
||||||
|
extern uint32 SPAD[]; /* cpu SPAD memory */
|
||||||
|
|
||||||
/* useful conversions */
|
/* useful conversions */
|
||||||
/* Fill STAR value from cyl, trk, sec data */
|
/* Fill STAR value from cyl, trk, sec data */
|
||||||
#define CHS2STAR(c,h,s) (((c<<16) & LMASK)|((h<<8) & 0xff00)|(s & 0xff))
|
#define CHS2STAR(c,h,s) (((c<<16) & LMASK)|((h<<8) & 0xff00)|(s & 0xff))
|
||||||
|
@ -1226,19 +1228,19 @@ t_stat hsdp_rsctl(UNIT *uptr) {
|
||||||
int cmd = uptr->CMD & DSK_CMDMSK;
|
int cmd = uptr->CMD & DSK_CMDMSK;
|
||||||
CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */
|
CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */
|
||||||
|
|
||||||
if ((uptr->CMD & DSK_CMDMSK) != 0) { /* is unit busy */
|
if ((uptr->CMD & DSK_CMDMSK) != 0) { /* is unit busy */
|
||||||
sim_debug(DEBUG_CMD, dptr,
|
sim_debug(DEBUG_CMD, dptr,
|
||||||
"hsdp_rsctl RSCTL chsa %04x cmd %02x ccw_count %02x\n", chsa, cmd, chp->ccw_count);
|
"hsdp_rsctl RSCTL chsa %04x cmd %02x ccw_count %02x\n", chsa, cmd, chp->ccw_count);
|
||||||
sim_cancel(uptr); /* clear the input timer */
|
sim_cancel(uptr); /* clear the input timer */
|
||||||
chp->ccw_count = 0; /* zero the count */
|
chp->ccw_count = 0; /* zero the count */
|
||||||
chp->chan_caw = 0; /* zero iocd address for diags */
|
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->CMD &= LMASK; /* make non-busy */
|
||||||
uptr->SNS2 |= (SNS_ONC|SNS_UNR); /* on cylinder & ready */
|
uptr->SNS2 |= (SNS_ONC|SNS_UNR); /* on cylinder & ready */
|
||||||
sim_debug(DEBUG_CMD, dptr,
|
sim_debug(DEBUG_CMD, dptr,
|
||||||
"hsdp_rsctl RSCTL I/O not busy chsa %04x cmd %02x\n", chsa, cmd);
|
"hsdp_rsctl RSCTL I/O not busy chsa %04x cmd %02x\n", chsa, cmd);
|
||||||
return SCPE_OK; /* not busy */
|
return SCPE_OK; /* not busy */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle processing of hsdp requests. */
|
/* Handle processing of hsdp requests. */
|
||||||
|
@ -1247,13 +1249,15 @@ t_stat hsdp_srv(UNIT *uptr)
|
||||||
uint16 chsa = GET_UADDR(uptr->CMD);
|
uint16 chsa = GET_UADDR(uptr->CMD);
|
||||||
DEVICE *dptr = get_dev(uptr);
|
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 cmd = uptr->CMD & DSK_CMDMSK;
|
||||||
int type = GET_TYPE(uptr->flags);
|
int type = GET_TYPE(uptr->flags);
|
||||||
uint32 tcyl=0, trk=0, cyl=0, sec=0, tempt=0;
|
uint32 tcyl=0, trk=0, cyl=0, sec=0, tempt=0;
|
||||||
int unit = (uptr - dptr->units);
|
int unit = (uptr - dptr->units);
|
||||||
int len = chp->ccw_count;
|
int len = chp->ccw_count;
|
||||||
int i,j,k;
|
int i,j,k;
|
||||||
uint32 mema, ecc, cecc, tstar; /* memory address */
|
uint32 mema, ecc, cecc, tstar; /* memory address */
|
||||||
uint8 ch;
|
uint8 ch;
|
||||||
uint16 ssize = hsdp_type[type].ssiz * 4; /* disk sector size in bytes */
|
uint16 ssize = hsdp_type[type].ssiz * 4; /* disk sector size in bytes */
|
||||||
uint32 tstart;
|
uint32 tstart;
|
||||||
|
@ -1298,7 +1302,7 @@ t_stat hsdp_srv(UNIT *uptr)
|
||||||
mema = chp->ccw_addr; /* get inch or buffer addr */
|
mema = chp->ccw_addr; /* get inch or buffer addr */
|
||||||
sim_debug(DEBUG_CMD, dptr,
|
sim_debug(DEBUG_CMD, dptr,
|
||||||
"hsdp_srv cmd CONT INC %06x chsa %04x addr %06x count %04x completed\n",
|
"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 */
|
/* to use this inch method, byte count must be 0x20 */
|
||||||
if (len != 0x20) {
|
if (len != 0x20) {
|
||||||
/* we have invalid count, error, bail out */
|
/* 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 */
|
mema = chp->ccw_addr; /* get inch or buffer addr */
|
||||||
sim_debug(DEBUG_CMD, dptr,
|
sim_debug(DEBUG_CMD, dptr,
|
||||||
"hsdp_srv starting INCH %06x cmd, chsa %04x MemBuf %06x cnt %04x\n",
|
"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 */
|
/* 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 */
|
/* 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 */
|
uptr->CMD &= LMASK; /* remove old cmd */
|
||||||
sim_debug(DEBUG_CMD, dptr,
|
sim_debug(DEBUG_CMD, dptr,
|
||||||
"hsdp_srv cmd INCH %06x chsa %04x addr %06x count %04x mode %08x completed\n",
|
"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 */
|
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -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].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].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 */
|
uptr->u3 |= IOP_INCH2; /* save INCH command as 0xf0 */
|
||||||
sim_activate(uptr, 40); /* go on */
|
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 */
|
/* now call set_inch() function to write and test inch buffer addresses */
|
||||||
/* the chp->ccw_addr location contains the inch address */
|
/* the chp->ccw_addr location contains the inch address */
|
||||||
/* 1-256 wd buffer is provided for 128 status dbl words */
|
/* 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 */
|
if ((tstart == SCPE_MEM) || (tstart == SCPE_ARG)) { /* any error */
|
||||||
/* we have error, bail out */
|
/* we have error, bail out */
|
||||||
uptr->u5 |= SNS_CMDREJ;
|
uptr->u5 |= SNS_CMDREJ;
|
||||||
|
|
7214
SEL32/sel32_ipu.c
Normal file
7214
SEL32/sel32_ipu.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
||||||
/* sel32_lpr.c: SEL32 922x & 924x High Speed Line Printer
|
/* 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
|
Portions provided by Richard Cornwell and other SIMH contributers
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* sel32_mfp.c: SEL-32 Model 8002 MFP processor controller
|
/* 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
|
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"),
|
||||||
|
@ -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].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].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 */
|
uptr->u3 |= MFP_INCH2; /* save INCH command as 0xf0 */
|
||||||
sim_activate(uptr, 40); /* go on */
|
sim_activate(uptr, 40); /* go on */
|
||||||
return 0; /* no status change */
|
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 */
|
/* now call set_inch() function to write and test inch buffer addresses */
|
||||||
/* the chp->ccw_addr location contains the inch address */
|
/* the chp->ccw_addr location contains the inch address */
|
||||||
/* 1-256 wd buffer is provided for 128 status dbl words */
|
/* 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 */
|
if ((tstart == SCPE_MEM) || (tstart == SCPE_ARG)) { /* any error */
|
||||||
/* we have error, bail out */
|
/* we have error, bail out */
|
||||||
uptr->u5 |= SNS_CMDREJ;
|
uptr->u5 |= SNS_CMDREJ;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* sel32_mt.c: SEL-32 8051 Buffered Tape Processor
|
/* 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
|
Portions provided by Richard Cornwell and other SIMH contributers
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
@ -41,6 +41,8 @@
|
||||||
|
|
||||||
#if NUM_DEVS_MT > 0
|
#if NUM_DEVS_MT > 0
|
||||||
|
|
||||||
|
extern uint32 SPAD[]; /* cpu SPAD memory */
|
||||||
|
|
||||||
#define BUFFSIZE (64 * 1024)
|
#define BUFFSIZE (64 * 1024)
|
||||||
#define UNIT_MT UNIT_ATTABLE | UNIT_DISABLE | UNIT_ROABLE
|
#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 chsa = chp->chan_dev;
|
||||||
uint16 devstat = 0;
|
uint16 devstat = 0;
|
||||||
DEVICE *dptr = get_dev(uptr);
|
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 */
|
/* check for valid iocd address if 1st iocd */
|
||||||
if (chp->chan_info & INFO_SIOCD) { /* see if 1st IOCD in channel prog */
|
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_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:
|
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 */
|
/* 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 */
|
chp->chan_status |= STATUS_PCHK; /* program check for invalid cmd */
|
||||||
uptr->SNS |= SNS_CMDREJ; /* cmd rejected */
|
uptr->SNS |= SNS_CMDREJ; /* cmd rejected */
|
||||||
sim_debug(DEBUG_EXP, dptr,
|
sim_debug(DEBUG_EXP, dptr,
|
||||||
|
@ -628,11 +632,12 @@ t_stat mt_preio(UNIT *uptr, uint16 chan) {
|
||||||
DEVICE *dptr = get_dev(uptr);
|
DEVICE *dptr = get_dev(uptr);
|
||||||
int unit = (uptr - dptr->units);
|
int unit = (uptr - dptr->units);
|
||||||
uint16 chsa = GET_UADDR(uptr->CMD);
|
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",
|
sim_debug(DEBUG_CMD, dptr, "mt_preio CMD %08x unit %02x chsa %04x incha %08x\n",
|
||||||
uptr->CMD, unit, chsa, chp->chan_inch_addr);
|
uptr->CMD, unit, chsa, pchp->chan_inch_addr);
|
||||||
if ((!loading) && (chp->chan_inch_addr == 0)) {
|
if ((!loading) && (pchp->chan_inch_addr == 0)) {
|
||||||
sim_debug(DEBUG_CMD, dptr,
|
sim_debug(DEBUG_CMD, dptr,
|
||||||
"mt_preio unit %02x chsa %04x NO INCH\n", unit, chsa);
|
"mt_preio unit %02x chsa %04x NO INCH\n", unit, chsa);
|
||||||
/* no INCH yet, so do nothing */
|
/* no INCH yet, so do nothing */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* sel32_scfi.c: SEL-32 SCFI SCSI Disk Controller
|
/* 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
|
Portions provided by Richard Cornwell and other SIMH contributers
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
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
|
#define UNIT_SCFI UNIT_ATTABLE | UNIT_IDLE | UNIT_DISABLE
|
||||||
|
|
||||||
|
extern uint32 SPAD[]; /* cpu SPAD memory */
|
||||||
|
|
||||||
/* useful conversions */
|
/* useful conversions */
|
||||||
/* Fill STAR value from cyl, trk, sec data */
|
/* Fill STAR value from cyl, trk, sec data */
|
||||||
#define CHS2STAR(c,h,s) (((c<<16) & LMASK)|((h<<8) & 0xff00)|(s & 0xff))
|
#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);
|
DEVICE *dptr = get_dev(uptr);
|
||||||
int32 unit = (uptr - dptr->units);
|
int32 unit = (uptr - dptr->units);
|
||||||
CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */
|
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,
|
sim_debug(DEBUG_CMD, dptr,
|
||||||
"scfi_startcmd chsa %04x unit %02x cmd %02x CMD %08x\n",
|
"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 */
|
case DSK_INCH: /* INCH cmd 0x0 */
|
||||||
sim_debug(DEBUG_CMD, dptr,
|
sim_debug(DEBUG_CMD, dptr,
|
||||||
"scfi_startcmd starting INCH %06x cmd, chsa %04x MemBuf %06x cnt %04x\n",
|
"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->SNS &= ~SNS_CMDREJ; /* not rejected yet */
|
||||||
uptr->CMD |= DSK_INCH2; /* use 0xF0 for inch, just need int */
|
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);
|
uint16 chsa = GET_UADDR(uptr->CMD);
|
||||||
DEVICE *dptr = get_dev(uptr);
|
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 cmd = uptr->CMD & DSK_CMDMSK;
|
||||||
int type = GET_TYPE(uptr->flags);
|
int type = GET_TYPE(uptr->flags);
|
||||||
uint32 tcyl=0, trk=0, cyl=0, sec=0;
|
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 */
|
mema = chp->ccw_addr; /* get inch or buffer addr */
|
||||||
sim_debug(DEBUG_CMD, dptr,
|
sim_debug(DEBUG_CMD, dptr,
|
||||||
"scfi_srv cmd CONT ICH %06x chsa %04x addr %06x count %04x completed\n",
|
"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) {
|
if (len == 0x14) {
|
||||||
/* read all 20 bytes, stopping every 4 bytes to make words */
|
/* read all 20 bytes, stopping every 4 bytes to make words */
|
||||||
/* the first word has the inch buffer address */
|
/* 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]);
|
mema = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | (buf[3]);
|
||||||
sim_debug(DEBUG_CMD, dptr,
|
sim_debug(DEBUG_CMD, dptr,
|
||||||
"scfi_srv cmd CONT ICH %06x chsa %04x mema %06x completed\n",
|
"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 {
|
} else {
|
||||||
/* drive attribute registers */
|
/* drive attribute registers */
|
||||||
/* may want to use this later */
|
/* 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]);
|
tstart = (buf[i-3]<<24) | (buf[i-2]<<16) | (buf[i-1]<<8) | (buf[i]);
|
||||||
sim_debug(DEBUG_CMD, dptr,
|
sim_debug(DEBUG_CMD, dptr,
|
||||||
"scfi_srv cmd CONT ICH %06x chsa %04x data %06x completed\n",
|
"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 */
|
mema = chp->ccw_addr; /* get inch or buffer addr */
|
||||||
sim_debug(DEBUG_CMD, dptr,
|
sim_debug(DEBUG_CMD, dptr,
|
||||||
"scfi_srv starting INCH %06x cmd, chsa %04x MemBuf %06x cnt %04x\n",
|
"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 */
|
/* 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 */
|
/* 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 */
|
uptr->CMD &= LMASK; /* remove old status bits & cmd */
|
||||||
sim_debug(DEBUG_CMD, dptr,
|
sim_debug(DEBUG_CMD, dptr,
|
||||||
"scfi_srv cmd INCH %06x chsa %04x addr %06x count %04x completed\n",
|
"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 */
|
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* sel32_scsi.c: SEL-32 MFP SCSI Disk controller
|
/* 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
|
Portions provided by Richard Cornwell and other SIMH contributers
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
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
|
#define UNIT_SCSI UNIT_ATTABLE | UNIT_IDLE | UNIT_DISABLE
|
||||||
|
|
||||||
|
extern uint32 SPAD[]; /* cpu SPAD memory */
|
||||||
|
|
||||||
/* useful conversions */
|
/* useful conversions */
|
||||||
/* Fill STAR value from cyl, trk, sec data */
|
/* Fill STAR value from cyl, trk, sec data */
|
||||||
#define CHS2STAR(c,h,s) (((c<<16) & LMASK)|((h<<8) & 0xff00)|(s & 0xff))
|
#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 */
|
/* now call set_inch() function to write and test inch buffer addresses */
|
||||||
/* 1-256 wd buffer is provided for 128 status dbl words */
|
/* 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 */
|
if ((i == SCPE_MEM) || (i == SCPE_ARG)) { /* any error */
|
||||||
/* we have error, bail out */
|
/* we have error, bail out */
|
||||||
uptr->CMD &= LMASK; /* remove old status bits & cmd */
|
uptr->CMD &= LMASK; /* remove old status bits & cmd */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* sel32_sys.c: SEL-32 Gould Concept/32 (orignal SEL-32) Simulator system interface.
|
/* 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
|
Portions provided by Richard Cornwell, Geert Rolf and other SIMH contributers
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
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.
|
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 "sel32_defs.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
extern REG cpu_reg[];
|
extern REG cpu_reg[];
|
||||||
extern uint32 M[MAXMEMSIZE];
|
|
||||||
extern uint32 SPAD[];
|
extern uint32 SPAD[];
|
||||||
extern uint32 PSD[];
|
extern uint32 PSD[];
|
||||||
char *dump_mem(uint32 mp, int cnt);
|
char *dump_mem(uint32 mp, int cnt);
|
||||||
|
@ -59,6 +223,9 @@ int32 sim_emax = 4; /* maximum number of instructions/wo
|
||||||
|
|
||||||
DEVICE *sim_devices[] = {
|
DEVICE *sim_devices[] = {
|
||||||
&cpu_dev,
|
&cpu_dev,
|
||||||
|
#ifdef USE_IPU_THREAD
|
||||||
|
&ipu_dev,
|
||||||
|
#endif
|
||||||
#ifdef NUM_DEVS_IOP
|
#ifdef NUM_DEVS_IOP
|
||||||
&iop_dev, /* IOP channel controller */
|
&iop_dev, /* IOP channel controller */
|
||||||
#endif
|
#endif
|
||||||
|
@ -231,8 +398,6 @@ char *dump_buf(uint8 *mp, int32 off, int cnt)
|
||||||
return (line); /* return pointer to caller */
|
return (line); /* return pointer to caller */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get_word - function to load a 32 bit word from the input file
|
* get_word - function to load a 32 bit word from the input file
|
||||||
* return 1 - OK
|
* return 1 - OK
|
||||||
|
|
|
@ -242,6 +242,10 @@
|
||||||
RelativePath="..\SEL32\sel32_iop.c"
|
RelativePath="..\SEL32\sel32_iop.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\SEL32\sel32_ipu.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\SEL32\sel32_lpr.c"
|
RelativePath="..\SEL32\sel32_lpr.c"
|
||||||
>
|
>
|
||||||
|
|
2
makefile
2
makefile
|
@ -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_clk.c ${SEL32D}/sel32_mt.c ${SEL32D}/sel32_lpr.c \
|
||||||
${SEL32D}/sel32_scfi.c ${SEL32D}/sel32_fltpt.c ${SEL32D}/sel32_disk.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_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}
|
SEL32_OPT = -I $(SEL32D) -DUSE_INT32 -DSEL32 ${NETWORK_OPT}
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|
Loading…
Add table
Reference in a new issue