Notes For V3.7

1. New Features

1.1 3.7-0

1.1.1 SCP

- Added SET THROTTLE and SET NOTHROTTLE commands to regulate simulator
  execution rate and host resource utilization.
- Added idle support (based on work by Mark Pizzolato).
- Added -e to control error processing in nested DO commands (from
  Dave Bryan).

1.1.2 HP2100

- Added Double Integer instructions, 1000-F CPU, and Floating Point
  Processor (from Dave Bryan).
- Added 2114 and 2115 CPUs, 12607B and 12578A DMA controllers, and
  21xx binary loader protection (from Dave Bryan).

1.1.3 Interdata

- Added SET IDLE and SET NOIDLE commands to idle the simulator in wait
  state.

1.1.4 PDP-11

- Added SET IDLE and SET NOIDLE commands to idle the simulator in wait
  state (WAIT instruction executed).
- Added TA11/TU60 cassette support.

1.1.5 PDP-8

- Added SET IDLE and SET NOIDLE commands to idle the simulator in wait
  state (keyboard poll loop or jump-to-self).
- Added TA8E/TU60 cassette support.

1.1.6 PDP-1

- Added support for 16-channel sequence break system.
- Added support for PDP-1D extended features and timesharing clock.
- Added support for Type 630 data communications subsystem.

1.1.6 PDP-4/7/9/15

- Added SET IDLE and SET NOIDLE commands to idle the simulator in wait
  state (keyboard poll loop or jump-to-self).

1.1.7 VAX, VAX780

- Added SET IDLE and SET NOIDLE commands to idle the simulator in wait
  state (more than 200 cycles at IPL's 0, 1, or 3 in kernel mode).

1.1.8 PDP-10

- Added SET IDLE and SET NOIDLE commands to idle the simulator in wait
  state (operating system dependent).
- Added CD20 (CD11) support.

2. Bugs Fixed

Please see the revision history on http://simh.trailing-edge.com or
in the source module sim_rev.h.
This commit is contained in:
Bob Supnik 2007-05-12 17:39:00 -07:00 committed by Mark Pizzolato
parent 53d02f7fa7
commit 6149cc7e06
57 changed files with 10269 additions and 9632 deletions

View file

@ -1,4 +1,4 @@
Notes For V3.7-0 Notes For V3.7
1. New Features 1. New Features

File diff suppressed because it is too large Load diff

View file

@ -14,7 +14,7 @@
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
PETER SCHORN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER PETER SCHORN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -14,7 +14,7 @@
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
PETER SCHORN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER PETER SCHORN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@ -22,27 +22,28 @@
Except as contained in this notice, the name of Peter Schorn shall not Except as contained in this notice, the name of Peter Schorn shall not
be used in advertising or otherwise to promote the sale, use or other dealings be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Peter Schorn. in this Software without prior written authorization from Peter Schorn.
Contains code from Howard M. Harte for defining and changing disk geometry. Contains code from Howard M. Harte for defining and changing disk geometry.
*/ */
#include "altairz80_defs.h" #include "altairz80_defs.h"
#include <assert.h>
/* the following routines provided courtesy of Howard M. Harte */ /* The following routines are based on work from Howard M. Harte */
t_stat set_geom (UNIT *uptr, int32 val, char *cptr, void *desc); t_stat set_geom(UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat show_geom (FILE *st, UNIT *uptr, int32 val, void *desc); t_stat show_geom(FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat set_format (UNIT *uptr, int32 val, char *cptr, void *desc); t_stat set_format(UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat show_format (FILE *st, UNIT *uptr, int32 val, void *desc); t_stat show_format(FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat hdsk_attach (UNIT *uptr, char *cptr); t_stat hdsk_attach(UNIT *uptr, char *cptr);
#define UNIT_V_HDSKWLK (UNIT_V_UF + 0) /* write locked */ #define UNIT_V_HDSK_WLK (UNIT_V_UF + 0) /* write locked */
#define UNIT_HDSKWLK (1 << UNIT_V_HDSKWLK) #define UNIT_HDSK_WLK (1 << UNIT_V_HDSK_WLK)
#define UNIT_V_HDSK_VERBOSE (UNIT_V_UF + 1) /* verbose mode, i.e. show error messages */ #define UNIT_V_HDSK_VERBOSE (UNIT_V_UF + 1) /* verbose mode, i.e. show error messages */
#define UNIT_HDSK_VERBOSE (1 << UNIT_V_HDSK_VERBOSE) #define UNIT_HDSK_VERBOSE (1 << UNIT_V_HDSK_VERBOSE)
#define HDSK_MAX_SECTOR_SIZE 1024 /* size of sector */ #define HDSK_MAX_SECTOR_SIZE 1024 /* maximum size of a sector */
#define HDSK_SECTOR_SIZE u5 /* size of sector */ #define HDSK_SECTOR_SIZE u5 /* size of sector */
#define HDSK_SECTORS_PER_TRACK u4 /* sectors per track */ #define HDSK_SECTORS_PER_TRACK u4 /* sectors per track */
#define HDSK_MAX_TRACKS u3 /* number of tracks */ #define HDSK_NUMBER_OF_TRACKS u3 /* number of tracks */
#define HDSK_FORMAT_TYPE u6 /* Disk Format Type */ #define HDSK_FORMAT_TYPE u6 /* Disk Format Type */
#define HDSK_CAPACITY (2048*32*128) /* Default Altair HDSK Capacity */ #define HDSK_CAPACITY (2048*32*128) /* Default Altair HDSK Capacity */
#define HDSK_NUMBER 8 /* number of hard disks */ #define HDSK_NUMBER 8 /* number of hard disks */
@ -55,11 +56,11 @@ t_stat hdsk_attach (UNIT *uptr, char *cptr);
#define HDSK_WRITE 3 #define HDSK_WRITE 3
#define HDSK_PARAM 4 #define HDSK_PARAM 4
#define HDSK_BOOT_ADDRESS 0x5c00 #define HDSK_BOOT_ADDRESS 0x5c00
#define DPB_NAME_LENGTH 15
extern char messageBuffer[]; extern char messageBuffer[];
extern int32 PCX; extern int32 PCX;
extern UNIT cpu_unit; extern UNIT cpu_unit;
extern uint8 M[MAXMEMSIZE][MAXBANKS];
extern int32 saved_PC; extern int32 saved_PC;
extern int32 install_bootrom(void); extern int32 install_bootrom(void);
@ -71,14 +72,7 @@ extern uint8 GetBYTEWrapper(const uint32 Addr);
extern int32 bootrom[BOOTROM_SIZE]; extern int32 bootrom[BOOTROM_SIZE];
static t_stat hdsk_boot(int32 unitno, DEVICE *dptr); static t_stat hdsk_boot(int32 unitno, DEVICE *dptr);
static int32 hdsk_hasVerbose(void);
int32 hdsk_io(const int32 port, const int32 io, const int32 data); int32 hdsk_io(const int32 port, const int32 io, const int32 data);
static int32 hdsk_in(const int32 port);
static int32 hdsk_out(const int32 data);
static int32 checkParameters(void);
static int32 doSeek(void);
static int32 doRead(void);
static int32 doWrite(void);
static int32 hdskLastCommand = HDSK_NONE; static int32 hdskLastCommand = HDSK_NONE;
static int32 hdskCommandPosition = 0; static int32 hdskCommandPosition = 0;
@ -87,31 +81,33 @@ static int32 selectedDisk;
static int32 selectedSector; static int32 selectedSector;
static int32 selectedTrack; static int32 selectedTrack;
static int32 selectedDMA; static int32 selectedDMA;
static int32 hdskTrace; static int32 hdskTrace = FALSE;
typedef struct { typedef struct {
char name[16]; char name[DPB_NAME_LENGTH + 1]; /* name of CP/M disk parameter block */
t_addr capac; t_addr capac; /* capacity */
uint16 spt; uint16 spt; /* sectors per track */
uint8 bsh; uint8 bsh; /* data allocation block shift factor */
uint8 blm; uint8 blm; /* data allocation block mask */
uint8 exm; uint8 exm; /* extent mask */
uint16 dsm; uint16 dsm; /* maximum data block number */
uint16 drm; uint16 drm; /* total number of directory entries */
uint8 al0; uint8 al0; /* determine reserved directory blocks */
uint8 al1; uint8 al1; /* determine reserved directory blocks */
uint16 cks; uint16 cks; /* size of directory check vector */
uint16 off; uint16 off; /* number of reserved tracks */
uint8 psh; uint8 psh; /* physical record shift factor, CP/M 3 */
uint8 phm; uint8 phm; /* physical record mask, CP/M 3 */
} DPB; } DPB;
/* Note in the following CKS = 0 for fixed media which are not supposed to be changed while CP/M is executing */
static DPB dpb[] = { static DPB dpb[] = {
/* NAME CAPAC SPT BSH BLM EXM DSM DRM AL0 AL1 CKS OFF PSH PHM */ /* name capac spt bsh blm exm dsm drm al0 al1 cks off psh phm */
{ "HDSK", HDSK_CAPACITY, 32, 0x05, 0x1F, 0x01, 0x07f9, 0x03FF, 0xFF, 0x00, 0x8000, 0x0006, 0x00, 0x00 }, /* AZ80 HDSK */ { "HDSK", HDSK_CAPACITY, 32, 0x05, 0x1F, 0x01, 0x07f9, 0x03FF, 0xFF, 0x00, 0x0000, 0x0006, 0x00, 0x00 }, /* AZ80 HDSK */
{ "EZ80FL", 131072, 32, 0x03, 0x07, 0x00, 127, 0x003E, 0xC0, 0x00, 0x0000, 0x0000, 0x02, 0x03 }, /* 128K FLASH */ { "EZ80FL", 131072, 32, 0x03, 0x07, 0x00, 127, 0x003E, 0xC0, 0x00, 0x0000, 0x0000, 0x02, 0x03 }, /* 128K FLASH */
{ "P112", 1474560, 72, 0x04, 0x0F, 0x00, 710, 0x00FE, 0xF0, 0x00, 0x0000, 0x0002, 0x02, 0x03 }, /* 1.44M P112 */ { "P112", 1474560, 72, 0x04, 0x0F, 0x00, 710, 0x00FE, 0xF0, 0x00, 0x0000, 0x0002, 0x02, 0x03 }, /* 1.44M P112 */
{ "SU720", 737280, 36, 0x04, 0x0F, 0x00, 354, 0x007E, 0xC0, 0x00, 0x0020, 0x0002, 0x02, 0x03 }, /* 720K Super I/O */ { "SU720", 737280, 36, 0x04, 0x0F, 0x00, 354, 0x007E, 0xC0, 0x00, 0x0020, 0x0002, 0x02, 0x03 }, /* 720K Super I/O */
{ "SSSD8", 256256, 26, 0x03, 0x07, 0x00, 242, 0x003F, 0xC0, 0x00, 0x0000, 0x0002, 0x00, 0x00 }, /* Standard 8" SS SD */
{ "", 0 } { "", 0 }
}; };
@ -139,12 +135,12 @@ static REG hdsk_reg[] = {
static MTAB hdsk_mod[] = { static MTAB hdsk_mod[] = {
{ MTAB_XTD|MTAB_VUN|MTAB_VAL, 0, "FORMAT", "FORMAT", &set_format, &show_format, NULL }, { MTAB_XTD|MTAB_VUN|MTAB_VAL, 0, "FORMAT", "FORMAT", &set_format, &show_format, NULL },
{ UNIT_HDSKWLK, 0, "WRTENB", "WRTENB", NULL }, { UNIT_HDSK_WLK, 0, "WRTENB", "WRTENB", NULL },
{ UNIT_HDSKWLK, UNIT_HDSKWLK, "WRTLCK", "WRTLCK", NULL }, { UNIT_HDSK_WLK, UNIT_HDSK_WLK, "WRTLCK", "WRTLCK", NULL },
/* quiet, no warning messages */ /* quiet, no warning messages */
{ UNIT_HDSK_VERBOSE, 0, "QUIET", "QUIET", NULL }, { UNIT_HDSK_VERBOSE, 0, "QUIET", "QUIET", NULL },
/* verbose, show warning messages */ /* verbose, show warning messages */
{ UNIT_HDSK_VERBOSE, UNIT_HDSK_VERBOSE, "VERBOSE", "VERBOSE", NULL }, { UNIT_HDSK_VERBOSE, UNIT_HDSK_VERBOSE, "VERBOSE", "VERBOSE", NULL },
{ MTAB_XTD|MTAB_VUN|MTAB_VAL, 0, "GEOM", "GEOM", &set_geom, &show_geom, NULL }, { MTAB_XTD|MTAB_VUN|MTAB_VAL, 0, "GEOM", "GEOM", &set_geom, &show_geom, NULL },
{ 0 } { 0 }
}; };
@ -159,102 +155,117 @@ DEVICE hdsk_dev = {
}; };
/* Attach routine */ /* Attach routine */
t_stat hdsk_attach (UNIT *uptr, char *cptr) { t_stat hdsk_attach(UNIT *uptr, char *cptr) {
uint32 flen;
t_stat r; t_stat r;
int32 i; int32 i;
char unitChar;
r = attach_unit (uptr, cptr); /* attach unit */ r = attach_unit(uptr, cptr); /* attach unit */
if (r != SCPE_OK) return r; /* error? */ if ( r != SCPE_OK) /* error? */
if ((flen = sim_fsize (uptr->fileref)) == 0) { /* new disk image? */ return r;
if (uptr->flags & UNIT_RO) return SCPE_OK; /* if ro, done */
return SCPE_OK;
}
if(flen>0) { /* Step 1: Determine capacity of this disk */
uptr->capac = flen; uptr -> capac = sim_fsize(uptr -> fileref); /* the file length is a good candidate */
if (uptr -> capac == 0) { /* file does not exist or has length 0 */
uptr -> capac = uptr -> HDSK_NUMBER_OF_TRACKS *
uptr -> HDSK_SECTORS_PER_TRACK * uptr -> HDSK_SECTOR_SIZE;
if (uptr -> capac == 0)
uptr -> capac = HDSK_CAPACITY;
} /* post condition: uptr -> capac > 0 */
assert(uptr -> capac);
uptr->HDSK_FORMAT_TYPE = -1; /* Default to unknown format type */ /* Step 2: Determine format based on disk capacity */
uptr -> HDSK_FORMAT_TYPE = -1; /* default to unknown format type */
for(i=0; dpb[i].spt != 0; i++) { for (i = 0; dpb[i].capac != 0; i++) { /* find disk parameter block */
if(dpb[i].capac == uptr->capac) { if (dpb[i].capac == uptr -> capac) { /* found if correct capacity */
uptr->HDSK_FORMAT_TYPE = i; uptr -> HDSK_FORMAT_TYPE = i;
break; break;
}
} }
} }
if(uptr->HDSK_FORMAT_TYPE == -1) { /* Step 3: Set number of sectors per track and sector size */
uptr->HDSK_FORMAT_TYPE = 0; if (uptr -> HDSK_FORMAT_TYPE == -1) { /* Case 1: no disk parameter block found*/
uptr->capac = dpb[uptr->HDSK_FORMAT_TYPE].capac; for (i = 0; i < hdsk_dev.numunits; i++) /* find affected unit number */
printf("HDSK: WARNING: Unsupported disk capacity, assuming HDSK type.\n"); if (&hdsk_unit[i] == uptr)
uptr->flags |= UNIT_HDSKWLK; break; /* found */
printf("HDSK: WARNING: Forcing WRTLCK.\n"); unitChar = '0' + i;
if(uptr->capac != (uptr->HDSK_MAX_TRACKS * uptr->HDSK_SECTORS_PER_TRACK * uptr->HDSK_SECTOR_SIZE)) { uptr -> HDSK_FORMAT_TYPE = 0;
printf("HDSK: WARNING: Geometry may be incorrect.\n"); printf("HDSK%c: WARNING: Unsupported disk capacity, assuming HDSK type with capacity %iKB.\n",
unitChar, uptr -> capac / 1000);
uptr -> flags |= UNIT_HDSK_WLK;
printf("HDSK%c: WARNING: Forcing WRTLCK.\n", unitChar);
/* check whether capacity corresponds to setting of tracks, sectors per track and sector size */
if (uptr -> capac != (uptr -> HDSK_NUMBER_OF_TRACKS *
uptr -> HDSK_SECTORS_PER_TRACK * uptr -> HDSK_SECTOR_SIZE)) {
printf("HDSK%c: WARNING: Fixing geometry.\n", unitChar);
if (uptr -> HDSK_SECTORS_PER_TRACK == 0) uptr -> HDSK_SECTORS_PER_TRACK = 32;
if (uptr -> HDSK_SECTOR_SIZE == 0) uptr -> HDSK_SECTOR_SIZE = 128;
} }
} }
else { /* Case 2: disk parameter block found */
uptr -> HDSK_SECTORS_PER_TRACK = dpb[uptr -> HDSK_FORMAT_TYPE].spt >> dpb[uptr -> HDSK_FORMAT_TYPE].psh;
uptr -> HDSK_SECTOR_SIZE = (128 << dpb[uptr -> HDSK_FORMAT_TYPE].psh);
}
assert(uptr -> HDSK_SECTORS_PER_TRACK && uptr -> HDSK_SECTOR_SIZE);
uptr->HDSK_SECTOR_SIZE = (128 << dpb[uptr->HDSK_FORMAT_TYPE].psh); /* Step 4: Number of tracks is smallest number to accomodate capacity */
uptr->HDSK_SECTORS_PER_TRACK = dpb[uptr->HDSK_FORMAT_TYPE].spt >> dpb[uptr->HDSK_FORMAT_TYPE].psh; uptr -> HDSK_NUMBER_OF_TRACKS = (uptr -> capac + uptr -> HDSK_SECTORS_PER_TRACK *
uptr->HDSK_MAX_TRACKS = uptr->capac / (uptr->HDSK_SECTORS_PER_TRACK * uptr->HDSK_SECTOR_SIZE); uptr -> HDSK_SECTOR_SIZE - 1) / (uptr -> HDSK_SECTORS_PER_TRACK * uptr -> HDSK_SECTOR_SIZE);
assert( ((uptr -> HDSK_NUMBER_OF_TRACKS - 1) * uptr -> HDSK_SECTORS_PER_TRACK *
uptr -> HDSK_SECTOR_SIZE < uptr -> capac) &&
(uptr -> capac <= uptr -> HDSK_NUMBER_OF_TRACKS *
uptr -> HDSK_SECTORS_PER_TRACK * uptr -> HDSK_SECTOR_SIZE ) );
return SCPE_OK; return SCPE_OK;
} }
/* Set disk geometry routine */ /* Set disk geometry routine */
t_stat set_geom (UNIT *uptr, int32 val, char *cptr, void *desc) { t_stat set_geom(UNIT *uptr, int32 val, char *cptr, void *desc) {
DEVICE *dptr; uint32 numberOfTracks, numberOfSectors, sectorSize;
int result, n;
uint32 ncyl, nsect, ssize;
if (cptr == NULL) return SCPE_ARG; if (cptr == NULL) return SCPE_ARG;
if (uptr == NULL) return SCPE_IERR; if (uptr == NULL) return SCPE_IERR;
dptr = find_dev_from_unit (uptr); result = sscanf(cptr, "%d/%d/%d%n", &numberOfTracks, &numberOfSectors, &sectorSize, &n);
if (dptr == NULL) return SCPE_IERR; if ((result != 3) || (result == EOF) || (cptr[n] != 0)) {
result = sscanf(cptr, "T:%d/N:%d/S:%d%n", &numberOfTracks, &numberOfSectors, &sectorSize, &n);
sscanf(cptr, "%d/%d/%d", &ncyl, &nsect, &ssize); if ((result != 3) || (result == EOF) || (cptr[n] != 0)) return SCPE_ARG;
uptr->HDSK_MAX_TRACKS = ncyl; }
uptr->HDSK_SECTORS_PER_TRACK = nsect; uptr -> HDSK_NUMBER_OF_TRACKS = numberOfTracks;
uptr->HDSK_SECTOR_SIZE = ssize; uptr -> HDSK_SECTORS_PER_TRACK = numberOfSectors;
uptr -> HDSK_SECTOR_SIZE = sectorSize;
uptr -> capac = numberOfTracks * numberOfSectors * sectorSize;
return SCPE_OK; return SCPE_OK;
} }
/* Show disk geometry routine */ /* Show disk geometry routine */
t_stat show_geom (FILE *st, UNIT *uptr, int32 val, void *desc) { t_stat show_geom(FILE *st, UNIT *uptr, int32 val, void *desc) {
DEVICE *dptr;
if (uptr == NULL) return SCPE_IERR; if (uptr == NULL) return SCPE_IERR;
dptr = find_dev_from_unit (uptr); fprintf(st, "T:%d/N:%d/S:%d", uptr -> HDSK_NUMBER_OF_TRACKS,
if (dptr == NULL) return SCPE_IERR; uptr -> HDSK_SECTORS_PER_TRACK, uptr -> HDSK_SECTOR_SIZE);
fprintf (st, "T:%d/N:%d/S:%d", uptr->HDSK_MAX_TRACKS, uptr->HDSK_SECTORS_PER_TRACK, uptr->u5);
return SCPE_OK; return SCPE_OK;
} }
#define QUOTE1(text) #text
#define QUOTE2(text) QUOTE1(text)
/* Set disk format routine */ /* Set disk format routine */
t_stat set_format (UNIT *uptr, int32 val, char *cptr, void *desc) { t_stat set_format(UNIT *uptr, int32 val, char *cptr, void *desc) {
DEVICE *dptr; char fmtname[DPB_NAME_LENGTH + 1];
char fmtname[16];
int32 i; int32 i;
if (cptr == NULL) return SCPE_ARG; if (cptr == NULL) return SCPE_ARG;
if (uptr == NULL) return SCPE_IERR; if (uptr == NULL) return SCPE_IERR;
dptr = find_dev_from_unit (uptr); if (sscanf(cptr, "%" QUOTE2(DPB_NAME_LENGTH) "s", fmtname) == 0) return SCPE_ARG;
if (dptr == NULL) return SCPE_IERR; for (i = 0; dpb[i].capac != 0; i++) {
if (strncmp(fmtname, dpb[i].name, strlen(fmtname)) == 0) {
sscanf(cptr, "%s", fmtname); uptr -> HDSK_FORMAT_TYPE = i;
uptr -> capac = dpb[i].capac; /* Set capacity */
for(i=0;dpb[i].spt != 0;i++) {
if(!strncmp(fmtname, dpb[i].name, strlen(fmtname))) {
uptr->HDSK_FORMAT_TYPE = i;
uptr->capac = dpb[i].capac; /* Set capacity */
/* Configure physical disk geometry */ /* Configure physical disk geometry */
uptr->HDSK_SECTOR_SIZE = (128 << dpb[uptr->HDSK_FORMAT_TYPE].psh); uptr -> HDSK_SECTOR_SIZE = (128 << dpb[uptr -> HDSK_FORMAT_TYPE].psh);
uptr->HDSK_SECTORS_PER_TRACK = dpb[uptr->HDSK_FORMAT_TYPE].spt >> dpb[uptr->HDSK_FORMAT_TYPE].psh; uptr -> HDSK_SECTORS_PER_TRACK = dpb[uptr -> HDSK_FORMAT_TYPE].spt >> dpb[uptr -> HDSK_FORMAT_TYPE].psh;
uptr->HDSK_MAX_TRACKS = uptr->capac / (uptr->HDSK_SECTORS_PER_TRACK * uptr->HDSK_SECTOR_SIZE); uptr -> HDSK_NUMBER_OF_TRACKS = (uptr -> capac +
uptr -> HDSK_SECTORS_PER_TRACK * uptr -> HDSK_SECTOR_SIZE - 1) /
(uptr -> HDSK_SECTORS_PER_TRACK * uptr -> HDSK_SECTOR_SIZE);
return SCPE_OK; return SCPE_OK;
} }
@ -263,13 +274,9 @@ t_stat set_format (UNIT *uptr, int32 val, char *cptr, void *desc) {
} }
/* Show disk format routine */ /* Show disk format routine */
t_stat show_format (FILE *st, UNIT *uptr, int32 val, void *desc) { t_stat show_format(FILE *st, UNIT *uptr, int32 val, void *desc) {
DEVICE *dptr;
if (uptr == NULL) return SCPE_IERR; if (uptr == NULL) return SCPE_IERR;
dptr = find_dev_from_unit (uptr); fprintf(st, "%s", dpb[uptr -> HDSK_FORMAT_TYPE].name);
if (dptr == NULL) return SCPE_IERR;
fprintf (st, "%s", dpb[uptr->HDSK_FORMAT_TYPE].name);
return SCPE_OK; return SCPE_OK;
} }
@ -315,9 +322,6 @@ static t_stat hdsk_boot(int32 unitno, DEVICE *dptr) {
return SCPE_ARG; return SCPE_ARG;
} }
if (cpu_unit.flags & (UNIT_ALTAIRROM | UNIT_BANKED)) { if (cpu_unit.flags & (UNIT_ALTAIRROM | UNIT_BANKED)) {
if (install_bootrom()) {
printf("ALTAIR boot ROM installed.\n");
}
/* check whether we are really modifying an LD A,<> instruction */ /* check whether we are really modifying an LD A,<> instruction */
if (bootrom[UNIT_NO_OFFSET_1 - 1] == LDA_INSTRUCTION) { if (bootrom[UNIT_NO_OFFSET_1 - 1] == LDA_INSTRUCTION) {
bootrom[UNIT_NO_OFFSET_1] = (unitno + NUM_OF_DSK) & 0xff; /* LD A,<unitno> */ bootrom[UNIT_NO_OFFSET_1] = (unitno + NUM_OF_DSK) & 0xff; /* LD A,<unitno> */
@ -326,6 +330,7 @@ static t_stat hdsk_boot(int32 unitno, DEVICE *dptr) {
printf("Incorrect boot ROM offset detected.\n"); printf("Incorrect boot ROM offset detected.\n");
return SCPE_IERR; return SCPE_IERR;
} }
install_bootrom(); /* install modified ROM */
} }
for (i = 0; i < BOOTROM_SIZE; i++) { for (i = 0; i < BOOTROM_SIZE; i++) {
PutBYTEBasic(i + HDSK_BOOT_ADDRESS, 0, hdskBoot[i] & 0xff); PutBYTEBasic(i + HDSK_BOOT_ADDRESS, 0, hdskBoot[i] & 0xff);
@ -339,7 +344,7 @@ static t_stat hdsk_boot(int32 unitno, DEVICE *dptr) {
static int32 hdsk_hasVerbose(void) { static int32 hdsk_hasVerbose(void) {
int32 i; int32 i;
for (i = 0; i < HDSK_NUMBER; i++) { for (i = 0; i < HDSK_NUMBER; i++) {
if (((hdsk_dev.units + i) -> flags) & UNIT_HDSK_VERBOSE) { if (hdsk_dev.units[i].flags & UNIT_HDSK_VERBOSE) {
return TRUE; return TRUE;
} }
} }
@ -398,7 +403,7 @@ static int32 hdsk_hasVerbose(void) {
/* check the parameters and return TRUE iff parameters are correct or have been repaired */ /* check the parameters and return TRUE iff parameters are correct or have been repaired */
static int32 checkParameters(void) { static int32 checkParameters(void) {
UNIT *uptr = hdsk_dev.units + selectedDisk; UNIT *uptr = &hdsk_dev.units[selectedDisk];
int32 currentFlag; int32 currentFlag;
if ((selectedDisk < 0) || (selectedDisk >= HDSK_NUMBER)) { if ((selectedDisk < 0) || (selectedDisk >= HDSK_NUMBER)) {
if (hdsk_hasVerbose()) { if (hdsk_hasVerbose()) {
@ -406,24 +411,24 @@ static int32 checkParameters(void) {
} }
selectedDisk = 0; selectedDisk = 0;
} }
currentFlag = (hdsk_dev.units + selectedDisk) -> flags; currentFlag = hdsk_dev.units[selectedDisk].flags;
if ((currentFlag & UNIT_ATT) == 0) { if ((currentFlag & UNIT_ATT) == 0) {
if (currentFlag & UNIT_HDSK_VERBOSE) { if (currentFlag & UNIT_HDSK_VERBOSE) {
MESSAGE_2("HDSK%d is not attached.", selectedDisk); MESSAGE_2("HDSK%d is not attached.", selectedDisk);
} }
return FALSE; /* cannot read or write */ return FALSE; /* cannot read or write */
} }
if ((selectedSector < 0) || (selectedSector >= uptr->HDSK_SECTORS_PER_TRACK)) { if ((selectedSector < 0) || (selectedSector >= uptr -> HDSK_SECTORS_PER_TRACK)) {
if (currentFlag & UNIT_HDSK_VERBOSE) { if (currentFlag & UNIT_HDSK_VERBOSE) {
MESSAGE_4("HDSK%d: 0 <= Sector=%02d < %d violated, will use 0 instead.", MESSAGE_4("HDSK%d: 0 <= Sector=%02d < %d violated, will use 0 instead.",
selectedDisk, selectedSector, uptr->HDSK_SECTORS_PER_TRACK); selectedDisk, selectedSector, uptr -> HDSK_SECTORS_PER_TRACK);
} }
selectedSector = 0; selectedSector = 0;
} }
if ((selectedTrack < 0) || (selectedTrack >= uptr->HDSK_MAX_TRACKS)) { if ((selectedTrack < 0) || (selectedTrack >= uptr -> HDSK_NUMBER_OF_TRACKS)) {
if (currentFlag & UNIT_HDSK_VERBOSE) { if (currentFlag & UNIT_HDSK_VERBOSE) {
MESSAGE_4("HDSK%d: 0 <= Track=%04d < %04d violated, will use 0 instead.", MESSAGE_4("HDSK%d: 0 <= Track=%04d < %04d violated, will use 0 instead.",
selectedDisk, selectedTrack, uptr->HDSK_MAX_TRACKS); selectedDisk, selectedTrack, uptr -> HDSK_NUMBER_OF_TRACKS);
} }
selectedTrack = 0; selectedTrack = 0;
} }
@ -431,15 +436,16 @@ static int32 checkParameters(void) {
if (hdskTrace) { if (hdskTrace) {
MESSAGE_7("%s HDSK%d Track=%04d Sector=%02d Len=%04d DMA=%04x\n", MESSAGE_7("%s HDSK%d Track=%04d Sector=%02d Len=%04d DMA=%04x\n",
(hdskLastCommand == HDSK_READ) ? "Read" : "Write", (hdskLastCommand == HDSK_READ) ? "Read" : "Write",
selectedDisk, selectedTrack, selectedSector, uptr->HDSK_SECTOR_SIZE, selectedDMA); selectedDisk, selectedTrack, selectedSector, uptr -> HDSK_SECTOR_SIZE, selectedDMA);
} }
return TRUE; return TRUE;
} }
static int32 doSeek(void) { static int32 doSeek(void) {
UNIT *uptr = hdsk_dev.units + selectedDisk; UNIT *uptr = &hdsk_dev.units[selectedDisk];
if (fseek(uptr -> fileref, if (fseek(uptr -> fileref,
(uptr->HDSK_SECTORS_PER_TRACK * uptr->HDSK_SECTOR_SIZE) * selectedTrack + (uptr->HDSK_SECTOR_SIZE * selectedSector), SEEK_SET)) { (uptr -> HDSK_SECTORS_PER_TRACK * uptr -> HDSK_SECTOR_SIZE) * selectedTrack +
(uptr -> HDSK_SECTOR_SIZE * selectedSector), SEEK_SET)) {
if ((uptr -> flags) & UNIT_HDSK_VERBOSE) { if ((uptr -> flags) & UNIT_HDSK_VERBOSE) {
MESSAGE_4("Could not access HDSK%d Sector=%02d Track=%04d.", MESSAGE_4("Could not access HDSK%d Sector=%02d Track=%04d.",
selectedDisk, selectedSector, selectedTrack); selectedDisk, selectedSector, selectedTrack);
@ -451,17 +457,17 @@ static int32 doSeek(void) {
} }
} }
uint8 hdskbuf[HDSK_MAX_SECTOR_SIZE]; /* data buffer */ uint8 hdskbuf[HDSK_MAX_SECTOR_SIZE] = {}; /* data buffer */
static int32 doRead(void) { static int32 doRead(void) {
int32 i; int32 i;
UNIT *uptr = hdsk_dev.units + selectedDisk; UNIT *uptr = &hdsk_dev.units[selectedDisk];
if (doSeek()) { if (doSeek()) {
return CPM_ERROR; return CPM_ERROR;
} }
if (fread(hdskbuf, uptr->HDSK_SECTOR_SIZE, 1, uptr -> fileref) != 1) { if (fread(hdskbuf, uptr -> HDSK_SECTOR_SIZE, 1, uptr -> fileref) != 1) {
for (i = 0; i < uptr->HDSK_SECTOR_SIZE; i++) { for (i = 0; i < uptr -> HDSK_SECTOR_SIZE; i++) {
hdskbuf[i] = CPM_EMPTY; hdskbuf[i] = CPM_EMPTY;
} }
if ((uptr -> flags) & UNIT_HDSK_VERBOSE) { if ((uptr -> flags) & UNIT_HDSK_VERBOSE) {
@ -470,7 +476,7 @@ static int32 doRead(void) {
} }
return CPM_OK; /* allows the creation of empty hard disks */ return CPM_OK; /* allows the creation of empty hard disks */
} }
for (i = 0; i < uptr->HDSK_SECTOR_SIZE; i++) { for (i = 0; i < uptr -> HDSK_SECTOR_SIZE; i++) {
PutBYTEWrapper(selectedDMA + i, hdskbuf[i]); PutBYTEWrapper(selectedDMA + i, hdskbuf[i]);
} }
return CPM_OK; return CPM_OK;
@ -479,15 +485,15 @@ static int32 doRead(void) {
static int32 doWrite(void) { static int32 doWrite(void) {
int32 i; int32 i;
UNIT *uptr = hdsk_dev.units + selectedDisk; UNIT *uptr = &hdsk_dev.units[selectedDisk];
if (((uptr -> flags) & UNIT_HDSKWLK) == 0) { /* write enabled */ if (((uptr -> flags) & UNIT_HDSK_WLK) == 0) { /* write enabled */
if (doSeek()) { if (doSeek()) {
return CPM_ERROR; return CPM_ERROR;
} }
for (i = 0; i < uptr->HDSK_SECTOR_SIZE; i++) { for (i = 0; i < uptr -> HDSK_SECTOR_SIZE; i++) {
hdskbuf[i] = GetBYTEWrapper(selectedDMA + i); hdskbuf[i] = GetBYTEWrapper(selectedDMA + i);
} }
if (fwrite(hdskbuf, uptr->HDSK_SECTOR_SIZE, 1, uptr -> fileref) != 1) { if (fwrite(hdskbuf, uptr -> HDSK_SECTOR_SIZE, 1, uptr -> fileref) != 1) {
if ((uptr -> flags) & UNIT_HDSK_VERBOSE) { if ((uptr -> flags) & UNIT_HDSK_VERBOSE) {
MESSAGE_4("Could not write HDSK%d Sector=%02d Track=%04d.", MESSAGE_4("Could not write HDSK%d Sector=%02d Track=%04d.",
selectedDisk, selectedSector, selectedTrack); selectedDisk, selectedSector, selectedTrack);
@ -506,7 +512,7 @@ static int32 doWrite(void) {
} }
static int32 hdsk_in(const int32 port) { static int32 hdsk_in(const int32 port) {
UNIT *uptr = hdsk_dev.units + selectedDisk; UNIT *uptr = &hdsk_dev.units[selectedDisk];
int32 result; int32 result;
if ((hdskCommandPosition == 6) && ((hdskLastCommand == HDSK_READ) || (hdskLastCommand == HDSK_WRITE))) { if ((hdskCommandPosition == 6) && ((hdskLastCommand == HDSK_READ) || (hdskLastCommand == HDSK_WRITE))) {
@ -515,7 +521,7 @@ static int32 hdsk_in(const int32 port) {
hdskCommandPosition = 0; hdskCommandPosition = 0;
return result; return result;
} else if (hdskLastCommand == HDSK_PARAM) { } else if (hdskLastCommand == HDSK_PARAM) {
DPB current = dpb[uptr->HDSK_FORMAT_TYPE]; DPB current = dpb[uptr -> HDSK_FORMAT_TYPE];
uint8 params[17]; uint8 params[17];
params[ 0] = current.spt & 0xff; params[ 1] = (current.spt >> 8) & 0xff; params[ 0] = current.spt & 0xff; params[ 1] = (current.spt >> 8) & 0xff;
params[ 2] = current.bsh; params[ 2] = current.bsh;
@ -535,9 +541,9 @@ static int32 hdsk_in(const int32 port) {
if (paramcount <= 17) if (paramcount <= 17)
return params[paramcount - 1]; return params[paramcount - 1];
else if (paramcount == 18) else if (paramcount == 18)
return (uptr->HDSK_SECTOR_SIZE & 0xff); return (uptr -> HDSK_SECTOR_SIZE & 0xff);
else if (paramcount == 19) else if (paramcount == 19)
return (uptr->HDSK_SECTOR_SIZE >> 8); return (uptr -> HDSK_SECTOR_SIZE >> 8);
else else
MESSAGE_2("HDSK%d Get parameter error.", selectedDisk); MESSAGE_2("HDSK%d Get parameter error.", selectedDisk);

View file

@ -1,292 +1,292 @@
/* altairz80_net.c: networking capability /* altairz80_net.c: networking capability
Copyright (c) 2002-2007, Peter Schorn Copyright (c) 2002-2007, Peter Schorn
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions: Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
PETER SCHORN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER PETER SCHORN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Peter Schorn shall not Except as contained in this notice, the name of Peter Schorn shall not
be used in advertising or otherwise to promote the sale, use or other dealings be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Peter Schorn. in this Software without prior written authorization from Peter Schorn.
*/ */
#include "altairz80_defs.h" #include "altairz80_defs.h"
#include "sim_sock.h" #include "sim_sock.h"
#define UNIT_V_SERVER (UNIT_V_UF + 0) /* define machine as a server */ #define UNIT_V_SERVER (UNIT_V_UF + 0) /* define machine as a server */
#define UNIT_SERVER (1 << UNIT_V_SERVER) #define UNIT_SERVER (1 << UNIT_V_SERVER)
#define NET_INIT_POLL_SERVER 16000 #define NET_INIT_POLL_SERVER 16000
#define NET_INIT_POLL_CLIENT 15000 #define NET_INIT_POLL_CLIENT 15000
/*#define DEBUG_NETWORK TRUE*/ /*#define DEBUG_NETWORK TRUE*/
static t_stat net_attach (UNIT *uptr, char *cptr); static t_stat net_attach (UNIT *uptr, char *cptr);
static t_stat net_detach (UNIT *uptr); static t_stat net_detach (UNIT *uptr);
static t_stat net_reset (DEVICE *dptr); static t_stat net_reset (DEVICE *dptr);
static t_stat net_svc (UNIT *uptr); static t_stat net_svc (UNIT *uptr);
static t_stat set_net (UNIT *uptr, int32 value, char *cptr, void *desc); static t_stat set_net (UNIT *uptr, int32 value, char *cptr, void *desc);
int32 netStatus (const int32 port, const int32 io, const int32 data); int32 netStatus (const int32 port, const int32 io, const int32 data);
int32 netData (const int32 port, const int32 io, const int32 data); int32 netData (const int32 port, const int32 io, const int32 data);
#define MAX_CONNECTIONS 2 /* maximal number of server connections */ #define MAX_CONNECTIONS 2 /* maximal number of server connections */
#define BUFFER_LENGTH 512 /* length of input and output buffer */ #define BUFFER_LENGTH 512 /* length of input and output buffer */
static struct { static struct {
int32 Z80StatusPort; /* Z80 status port associated with this ioSocket, read only */ int32 Z80StatusPort; /* Z80 status port associated with this ioSocket, read only */
int32 Z80DataPort; /* Z80 data port associated with this ioSocket, read only */ int32 Z80DataPort; /* Z80 data port associated with this ioSocket, read only */
SOCKET masterSocket; /* server master socket, only defined at [1] */ SOCKET masterSocket; /* server master socket, only defined at [1] */
SOCKET ioSocket; /* accepted server socket or connected client socket, 0 iff free */ SOCKET ioSocket; /* accepted server socket or connected client socket, 0 iff free */
char inputBuffer[BUFFER_LENGTH]; /* buffer for input characters read from ioSocket */ char inputBuffer[BUFFER_LENGTH]; /* buffer for input characters read from ioSocket */
int32 inputPosRead; /* position of next character to read from buffer */ int32 inputPosRead; /* position of next character to read from buffer */
int32 inputPosWrite; /* position of next character to append to input buffer from ioSocket */ int32 inputPosWrite; /* position of next character to append to input buffer from ioSocket */
int32 inputSize; /* number of characters in circular input buffer */ int32 inputSize; /* number of characters in circular input buffer */
char outputBuffer[BUFFER_LENGTH];/* buffer for output characters to be written to ioSocket */ char outputBuffer[BUFFER_LENGTH];/* buffer for output characters to be written to ioSocket */
int32 outputPosRead; /* position of next character to write to ioSocket */ int32 outputPosRead; /* position of next character to write to ioSocket */
int32 outputPosWrite; /* position of next character to append to output buffer */ int32 outputPosWrite; /* position of next character to append to output buffer */
int32 outputSize; /* number of characters in circular output buffer */ int32 outputSize; /* number of characters in circular output buffer */
} serviceDescriptor[MAX_CONNECTIONS+1] = { /* serviceDescriptor[0] holds the information for a client */ } serviceDescriptor[MAX_CONNECTIONS+1] = { /* serviceDescriptor[0] holds the information for a client */
/* stat dat ms ios in inPR inPW inS out outPR outPW outS */ /* stat dat ms ios in inPR inPW inS out outPR outPW outS */
{50, 51, 0, 0, {0}, 0, 0, 0, {0}, 0, 0, 0}, /* client Z80 port 50 and 51 */ {50, 51, 0, 0, {0}, 0, 0, 0, {0}, 0, 0, 0}, /* client Z80 port 50 and 51 */
{40, 41, 0, 0, {0}, 0, 0, 0, {0}, 0, 0, 0}, /* server Z80 port 40 and 41 */ {40, 41, 0, 0, {0}, 0, 0, 0, {0}, 0, 0, 0}, /* server Z80 port 40 and 41 */
{42, 43, 0, 0, {0}, 0, 0, 0, {0}, 0, 0, 0} /* server Z80 port 42 and 43 */ {42, 43, 0, 0, {0}, 0, 0, 0, {0}, 0, 0, 0} /* server Z80 port 42 and 43 */
}; };
static UNIT net_unit = { static UNIT net_unit = {
UDATA (&net_svc, UNIT_ATTABLE, 0), UDATA (&net_svc, UNIT_ATTABLE, 0),
0, /* wait, set in attach */ 0, /* wait, set in attach */
0, /* u3 = Port */ 0, /* u3 = Port */
0, /* u4 = IP of host */ 0, /* u4 = IP of host */
0, /* u5, unused */ 0, /* u5, unused */
0, /* u6, unused */ 0, /* u6, unused */
}; };
static REG net_reg[] = { static REG net_reg[] = {
{ DRDATA (POLL, net_unit.wait, 32) }, { DRDATA (POLL, net_unit.wait, 32) },
{ HRDATA (IPHOST, net_unit.u4, 32), REG_RO }, { HRDATA (IPHOST, net_unit.u4, 32), REG_RO },
{ DRDATA (PORT, net_unit.u3, 32), REG_RO }, { DRDATA (PORT, net_unit.u3, 32), REG_RO },
{ NULL } { NULL }
}; };
static MTAB net_mod[] = { static MTAB net_mod[] = {
{ UNIT_SERVER, 0, "CLIENT", "CLIENT", &set_net}, /* machine is a client */ { UNIT_SERVER, 0, "CLIENT", "CLIENT", &set_net}, /* machine is a client */
{ UNIT_SERVER, UNIT_SERVER, "SERVER", "SERVER", &set_net}, /* machine is a server */ { UNIT_SERVER, UNIT_SERVER, "SERVER", "SERVER", &set_net}, /* machine is a server */
{ 0 } { 0 }
}; };
DEVICE net_dev = { DEVICE net_dev = {
"NET", &net_unit, net_reg, net_mod, "NET", &net_unit, net_reg, net_mod,
1, 10, 31, 1, 8, 8, 1, 10, 31, 1, 8, 8,
NULL, NULL, &net_reset, NULL, NULL, &net_reset,
NULL, &net_attach, &net_detach, NULL, &net_attach, &net_detach,
NULL, 0, 0, NULL, 0, 0,
NULL, NULL, NULL NULL, NULL, NULL
}; };
static t_stat set_net(UNIT *uptr, int32 value, char *cptr, void *desc) { static t_stat set_net(UNIT *uptr, int32 value, char *cptr, void *desc) {
char temp[CBUFSIZE]; char temp[CBUFSIZE];
if ((net_unit.flags & UNIT_ATT) && ((net_unit.flags & UNIT_SERVER) != value)) { if ((net_unit.flags & UNIT_ATT) && ((net_unit.flags & UNIT_SERVER) != value)) {
strncpy(temp, net_unit.filename, CBUFSIZE); /* save name for later attach */ strncpy(temp, net_unit.filename, CBUFSIZE); /* save name for later attach */
net_detach(&net_unit); net_detach(&net_unit);
net_unit.flags ^= UNIT_SERVER; /* now switch from client to server and vice versa */ net_unit.flags ^= UNIT_SERVER; /* now switch from client to server and vice versa */
net_attach(uptr, temp); net_attach(uptr, temp);
return SCPE_OK; return SCPE_OK;
} }
return SCPE_OK; return SCPE_OK;
} }
static void serviceDescriptor_reset(const uint32 i) { static void serviceDescriptor_reset(const uint32 i) {
serviceDescriptor[i].inputPosRead = 0; serviceDescriptor[i].inputPosRead = 0;
serviceDescriptor[i].inputPosWrite = 0; serviceDescriptor[i].inputPosWrite = 0;
serviceDescriptor[i].inputSize = 0; serviceDescriptor[i].inputSize = 0;
serviceDescriptor[i].outputPosRead = 0; serviceDescriptor[i].outputPosRead = 0;
serviceDescriptor[i].outputPosWrite = 0; serviceDescriptor[i].outputPosWrite = 0;
serviceDescriptor[i].outputSize = 0; serviceDescriptor[i].outputSize = 0;
} }
static t_stat net_reset(DEVICE *dptr) { static t_stat net_reset(DEVICE *dptr) {
uint32 i; uint32 i;
if (net_unit.flags & UNIT_ATT) if (net_unit.flags & UNIT_ATT)
sim_activate(&net_unit, net_unit.wait); /* start poll */ sim_activate(&net_unit, net_unit.wait); /* start poll */
for (i = 0; i <= MAX_CONNECTIONS; i++) for (i = 0; i <= MAX_CONNECTIONS; i++)
serviceDescriptor_reset(i); serviceDescriptor_reset(i);
return SCPE_OK; return SCPE_OK;
} }
static t_stat net_attach(UNIT *uptr, char *cptr) { static t_stat net_attach(UNIT *uptr, char *cptr) {
uint32 i, ipa, ipp; uint32 i, ipa, ipp;
t_stat r = get_ipaddr(cptr, &ipa, &ipp); t_stat r = get_ipaddr(cptr, &ipa, &ipp);
if (r != SCPE_OK) return SCPE_ARG; if (r != SCPE_OK) return SCPE_ARG;
if (ipa == 0) ipa = 0x7F000001; /* localhost = 127.0.0.1 */ if (ipa == 0) ipa = 0x7F000001; /* localhost = 127.0.0.1 */
if (ipp == 0) ipp = 3000; if (ipp == 0) ipp = 3000;
net_unit.u3 = ipp; net_unit.u3 = ipp;
net_unit.u4 = ipa; net_unit.u4 = ipa;
net_reset(&net_dev); net_reset(&net_dev);
for (i = 0; i <= MAX_CONNECTIONS; i++) serviceDescriptor[i].ioSocket = 0; for (i = 0; i <= MAX_CONNECTIONS; i++) serviceDescriptor[i].ioSocket = 0;
if (net_unit.flags & UNIT_SERVER) { if (net_unit.flags & UNIT_SERVER) {
net_unit.wait = NET_INIT_POLL_SERVER; net_unit.wait = NET_INIT_POLL_SERVER;
serviceDescriptor[1].masterSocket = sim_master_sock(ipp); serviceDescriptor[1].masterSocket = sim_master_sock(ipp);
if (serviceDescriptor[1].masterSocket == INVALID_SOCKET) return SCPE_IOERR; if (serviceDescriptor[1].masterSocket == INVALID_SOCKET) return SCPE_IOERR;
} }
else { else {
net_unit.wait = NET_INIT_POLL_CLIENT; net_unit.wait = NET_INIT_POLL_CLIENT;
serviceDescriptor[0].ioSocket = sim_connect_sock(ipa, ipp); serviceDescriptor[0].ioSocket = sim_connect_sock(ipa, ipp);
if (serviceDescriptor[0].ioSocket == INVALID_SOCKET) return SCPE_IOERR; if (serviceDescriptor[0].ioSocket == INVALID_SOCKET) return SCPE_IOERR;
} }
net_unit.flags |= UNIT_ATT; net_unit.flags |= UNIT_ATT;
net_unit.filename = (char *) calloc(CBUFSIZE, sizeof (char)); /* alloc name buf */ net_unit.filename = (char *) calloc(CBUFSIZE, sizeof (char)); /* alloc name buf */
if (net_unit.filename == NULL) return SCPE_MEM; if (net_unit.filename == NULL) return SCPE_MEM;
strncpy(net_unit.filename, cptr, CBUFSIZE); /* save name */ strncpy(net_unit.filename, cptr, CBUFSIZE); /* save name */
return SCPE_OK; return SCPE_OK;
} }
static t_stat net_detach(UNIT *uptr) { static t_stat net_detach(UNIT *uptr) {
uint32 i; uint32 i;
if (!(net_unit.flags & UNIT_ATT)) return SCPE_OK; /* if not attached simply return */ if (!(net_unit.flags & UNIT_ATT)) return SCPE_OK; /* if not attached simply return */
if (net_unit.flags & UNIT_SERVER) if (net_unit.flags & UNIT_SERVER)
sim_close_sock(serviceDescriptor[1].masterSocket, TRUE); sim_close_sock(serviceDescriptor[1].masterSocket, TRUE);
for (i = 0; i <= MAX_CONNECTIONS; i++) for (i = 0; i <= MAX_CONNECTIONS; i++)
if (serviceDescriptor[i].ioSocket) if (serviceDescriptor[i].ioSocket)
sim_close_sock(serviceDescriptor[i].ioSocket, FALSE); sim_close_sock(serviceDescriptor[i].ioSocket, FALSE);
free(net_unit.filename); /* free port string */ free(net_unit.filename); /* free port string */
net_unit.filename = NULL; net_unit.filename = NULL;
net_unit.flags &= ~UNIT_ATT; /* not attached */ net_unit.flags &= ~UNIT_ATT; /* not attached */
return SCPE_OK; return SCPE_OK;
} }
/* cannot use sim_check_conn to check whether read will return an error */ /* cannot use sim_check_conn to check whether read will return an error */
static t_stat net_svc(UNIT *uptr) { static t_stat net_svc(UNIT *uptr) {
int32 i, j, k, r; int32 i, j, k, r;
SOCKET s; SOCKET s;
static char svcBuffer[BUFFER_LENGTH]; static char svcBuffer[BUFFER_LENGTH];
if (net_unit.flags & UNIT_ATT) { if (net_unit.flags & UNIT_ATT) {
sim_activate(&net_unit, net_unit.wait); /* continue poll */ sim_activate(&net_unit, net_unit.wait); /* continue poll */
if (net_unit.flags & UNIT_SERVER) { if (net_unit.flags & UNIT_SERVER) {
for (i = 1; i <= MAX_CONNECTIONS; i++) for (i = 1; i <= MAX_CONNECTIONS; i++)
if (serviceDescriptor[i].ioSocket == 0) { if (serviceDescriptor[i].ioSocket == 0) {
s = sim_accept_conn(serviceDescriptor[1].masterSocket, NULL); s = sim_accept_conn(serviceDescriptor[1].masterSocket, NULL);
if (s != INVALID_SOCKET) { if (s != INVALID_SOCKET) {
serviceDescriptor[i].ioSocket = s; serviceDescriptor[i].ioSocket = s;
#ifdef DEBUG_NETWORK #ifdef DEBUG_NETWORK
printf("Accepted connection %i with socket %i.\n\r", i, s); printf("Accepted connection %i with socket %i.\n\r", i, s);
#endif #endif
} }
} }
} }
else if (serviceDescriptor[0].ioSocket == 0) { else if (serviceDescriptor[0].ioSocket == 0) {
serviceDescriptor[0].ioSocket = sim_connect_sock(net_unit.u4, net_unit.u3); serviceDescriptor[0].ioSocket = sim_connect_sock(net_unit.u4, net_unit.u3);
if (serviceDescriptor[0].ioSocket == INVALID_SOCKET) return SCPE_IOERR; if (serviceDescriptor[0].ioSocket == INVALID_SOCKET) return SCPE_IOERR;
printf("\rWaiting for server ... Type g<return> (possibly twice) when ready\n\r"); printf("\rWaiting for server ... Type g<return> (possibly twice) when ready\n\r");
return SCPE_STOP; return SCPE_STOP;
} }
for (i = 0; i <= MAX_CONNECTIONS; i++) for (i = 0; i <= MAX_CONNECTIONS; i++)
if (serviceDescriptor[i].ioSocket) { if (serviceDescriptor[i].ioSocket) {
if (serviceDescriptor[i].inputSize < BUFFER_LENGTH) { /* there is space left in inputBuffer */ if (serviceDescriptor[i].inputSize < BUFFER_LENGTH) { /* there is space left in inputBuffer */
r = sim_read_sock(serviceDescriptor[i].ioSocket, svcBuffer, r = sim_read_sock(serviceDescriptor[i].ioSocket, svcBuffer,
BUFFER_LENGTH - serviceDescriptor[i].inputSize); BUFFER_LENGTH - serviceDescriptor[i].inputSize);
if (r == -1) { if (r == -1) {
#ifdef DEBUG_NETWORK #ifdef DEBUG_NETWORK
printf("Drop connection %i with socket %i.\n\r", i, serviceDescriptor[i].ioSocket); printf("Drop connection %i with socket %i.\n\r", i, serviceDescriptor[i].ioSocket);
#endif #endif
sim_close_sock(serviceDescriptor[i].ioSocket, FALSE); sim_close_sock(serviceDescriptor[i].ioSocket, FALSE);
serviceDescriptor[i].ioSocket = 0; serviceDescriptor[i].ioSocket = 0;
serviceDescriptor_reset(i); serviceDescriptor_reset(i);
continue; continue;
} }
else { else {
for (j = 0; j < r; j++) { for (j = 0; j < r; j++) {
serviceDescriptor[i].inputBuffer[serviceDescriptor[i].inputPosWrite++] = svcBuffer[j]; serviceDescriptor[i].inputBuffer[serviceDescriptor[i].inputPosWrite++] = svcBuffer[j];
if (serviceDescriptor[i].inputPosWrite == BUFFER_LENGTH) if (serviceDescriptor[i].inputPosWrite == BUFFER_LENGTH)
serviceDescriptor[i].inputPosWrite = 0; serviceDescriptor[i].inputPosWrite = 0;
} }
serviceDescriptor[i].inputSize += r; serviceDescriptor[i].inputSize += r;
} }
} }
if (serviceDescriptor[i].outputSize > 0) { /* there is something to write in outputBuffer */ if (serviceDescriptor[i].outputSize > 0) { /* there is something to write in outputBuffer */
k = serviceDescriptor[i].outputPosRead; k = serviceDescriptor[i].outputPosRead;
for (j = 0; j < serviceDescriptor[i].outputSize; j++) { for (j = 0; j < serviceDescriptor[i].outputSize; j++) {
svcBuffer[j] = serviceDescriptor[i].outputBuffer[k++]; svcBuffer[j] = serviceDescriptor[i].outputBuffer[k++];
if (k == BUFFER_LENGTH) k = 0; if (k == BUFFER_LENGTH) k = 0;
} }
r = sim_write_sock(serviceDescriptor[i].ioSocket, svcBuffer, serviceDescriptor[i].outputSize); r = sim_write_sock(serviceDescriptor[i].ioSocket, svcBuffer, serviceDescriptor[i].outputSize);
if (r >= 0) { if (r >= 0) {
serviceDescriptor[i].outputSize -= r; serviceDescriptor[i].outputSize -= r;
serviceDescriptor[i].outputPosRead += r; serviceDescriptor[i].outputPosRead += r;
if (serviceDescriptor[i].outputPosRead >= BUFFER_LENGTH) if (serviceDescriptor[i].outputPosRead >= BUFFER_LENGTH)
serviceDescriptor[i].outputPosRead -= BUFFER_LENGTH; serviceDescriptor[i].outputPosRead -= BUFFER_LENGTH;
} }
else printf("write %i\r\n", r); else printf("write %i\r\n", r);
} }
} }
} }
return SCPE_OK; return SCPE_OK;
} }
int32 netStatus(const int32 port, const int32 io, const int32 data) { int32 netStatus(const int32 port, const int32 io, const int32 data) {
uint32 i; uint32 i;
net_svc(&net_unit); net_svc(&net_unit);
if (io == 0) { /* IN */ if (io == 0) { /* IN */
for (i = 0; i <= MAX_CONNECTIONS; i++) for (i = 0; i <= MAX_CONNECTIONS; i++)
if (serviceDescriptor[i].Z80StatusPort == port) if (serviceDescriptor[i].Z80StatusPort == port)
return (serviceDescriptor[i].inputSize > 0 ? 1 : 0) | return (serviceDescriptor[i].inputSize > 0 ? 1 : 0) |
(serviceDescriptor[i].outputSize < BUFFER_LENGTH ? 2 : 0); (serviceDescriptor[i].outputSize < BUFFER_LENGTH ? 2 : 0);
} }
return 0; return 0;
} }
int32 netData(const int32 port, const int32 io, const int32 data) { int32 netData(const int32 port, const int32 io, const int32 data) {
uint32 i; uint32 i;
char result; char result;
net_svc(&net_unit); net_svc(&net_unit);
for (i = 0; i <= MAX_CONNECTIONS; i++) for (i = 0; i <= MAX_CONNECTIONS; i++)
if (serviceDescriptor[i].Z80DataPort == port) if (serviceDescriptor[i].Z80DataPort == port)
if (io == 0) { /* IN */ if (io == 0) { /* IN */
if (serviceDescriptor[i].inputSize == 0) { if (serviceDescriptor[i].inputSize == 0) {
printf("re-read from %i\r\n", port); printf("re-read from %i\r\n", port);
result = serviceDescriptor[i].inputBuffer[serviceDescriptor[i].inputPosRead > 0 ? result = serviceDescriptor[i].inputBuffer[serviceDescriptor[i].inputPosRead > 0 ?
serviceDescriptor[i].inputPosRead - 1 : BUFFER_LENGTH - 1]; serviceDescriptor[i].inputPosRead - 1 : BUFFER_LENGTH - 1];
} }
else { else {
result = serviceDescriptor[i].inputBuffer[serviceDescriptor[i].inputPosRead++]; result = serviceDescriptor[i].inputBuffer[serviceDescriptor[i].inputPosRead++];
if (serviceDescriptor[i].inputPosRead == BUFFER_LENGTH) if (serviceDescriptor[i].inputPosRead == BUFFER_LENGTH)
serviceDescriptor[i].inputPosRead = 0; serviceDescriptor[i].inputPosRead = 0;
serviceDescriptor[i].inputSize--; serviceDescriptor[i].inputSize--;
} }
#ifdef DEBUG_NETWORK #ifdef DEBUG_NETWORK
printf(" IN(%i)=%03xh (%c)\r\n", port, (result & 0xff), printf(" IN(%i)=%03xh (%c)\r\n", port, (result & 0xff),
(32 <= (result & 0xff)) && ((result & 0xff) <= 127) ? (result & 0xff) : '?'); (32 <= (result & 0xff)) && ((result & 0xff) <= 127) ? (result & 0xff) : '?');
#endif #endif
return result; return result;
} }
else { /* OUT */ else { /* OUT */
if (serviceDescriptor[i].outputSize == BUFFER_LENGTH) { if (serviceDescriptor[i].outputSize == BUFFER_LENGTH) {
printf("over-write %i to %i\r\n", data, port); printf("over-write %i to %i\r\n", data, port);
serviceDescriptor[i].outputBuffer[serviceDescriptor[i].outputPosWrite > 0 ? serviceDescriptor[i].outputBuffer[serviceDescriptor[i].outputPosWrite > 0 ?
serviceDescriptor[i].outputPosWrite - 1 : BUFFER_LENGTH - 1] = data; serviceDescriptor[i].outputPosWrite - 1 : BUFFER_LENGTH - 1] = data;
} }
else { else {
serviceDescriptor[i].outputBuffer[serviceDescriptor[i].outputPosWrite++] = data; serviceDescriptor[i].outputBuffer[serviceDescriptor[i].outputPosWrite++] = data;
if (serviceDescriptor[i].outputPosWrite== BUFFER_LENGTH) if (serviceDescriptor[i].outputPosWrite== BUFFER_LENGTH)
serviceDescriptor[i].outputPosWrite = 0; serviceDescriptor[i].outputPosWrite = 0;
serviceDescriptor[i].outputSize++; serviceDescriptor[i].outputSize++;
} }
#ifdef DEBUG_NETWORK #ifdef DEBUG_NETWORK
printf("OUT(%i)=%03xh (%c)\r\n", port, data, (32 <= data) && (data <= 127) ? data : '?'); printf("OUT(%i)=%03xh (%c)\r\n", port, data, (32 <= data) && (data <= 127) ? data : '?');
#endif #endif
return 0; return 0;
} }
return 0; return 0;
} }

View file

@ -1,6 +1,6 @@
/* gri_cpu.c: GRI-909 CPU simulator /* gri_cpu.c: GRI-909 CPU simulator
Copyright (c) 2001-2005, Robert M. Supnik Copyright (c) 2001-2007, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
cpu GRI-909 CPU cpu GRI-909 CPU
28-Apr-07 RMS Removed clock initialization
22-Sep-05 RMS Fixed declarations (from Sterling Garwood) 22-Sep-05 RMS Fixed declarations (from Sterling Garwood)
18-Jul-04 RMS Fixed missing ao_update calls in AX, AY write 18-Jul-04 RMS Fixed missing ao_update calls in AX, AY write
17-Jul-04 RMS Revised MSR, EAO based on additional documentation 17-Jul-04 RMS Revised MSR, EAO based on additional documentation
@ -380,14 +381,12 @@ t_stat sim_instr (void)
{ {
uint32 src, dst, op, t, jmp; uint32 src, dst, op, t, jmp;
t_stat reason; t_stat reason;
extern UNIT rtc_unit;
/* Restore register state */ /* Restore register state */
SC = SC & AMASK; /* load local PC */ SC = SC & AMASK; /* load local PC */
reason = 0; reason = 0;
ao_update (); /* update AO */ ao_update (); /* update AO */
sim_rtc_init (rtc_unit.wait); /* init calibration */
/* Main instruction fetch/decode loop */ /* Main instruction fetch/decode loop */

View file

@ -1,6 +1,6 @@
/* h316_cpu.c: Honeywell 316/516 CPU simulator /* h316_cpu.c: Honeywell 316/516 CPU simulator
Copyright (c) 1999-2006, Robert M. Supnik Copyright (c) 1999-2007, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
cpu H316/H516 CPU cpu H316/H516 CPU
28-Apr-07 RMS Removed clock initialization
03-Apr-06 RMS Fixed bugs in LLL, LRL (from Theo Engel) 03-Apr-06 RMS Fixed bugs in LLL, LRL (from Theo Engel)
22-Sep-05 RMS Fixed declarations (from Sterling Garwood) 22-Sep-05 RMS Fixed declarations (from Sterling Garwood)
16-Aug-05 RMS Fixed C++ declaration and cast problems 16-Aug-05 RMS Fixed C++ declaration and cast problems
@ -370,7 +371,6 @@ DEVICE cpu_dev = {
t_stat sim_instr (void) t_stat sim_instr (void)
{ {
extern UNIT clk_unit;
int32 AR, BR, MB, Y, t1, t2, t3, skip, dev; int32 AR, BR, MB, Y, t1, t2, t3, skip, dev;
uint32 ut; uint32 ut;
t_stat reason; t_stat reason;
@ -399,7 +399,6 @@ BR = saved_BR & DMASK;
XR = saved_XR & DMASK; XR = saved_XR & DMASK;
PC = PC & ((cpu_unit.flags & UNIT_EXT)? X_AMASK: NX_AMASK); /* mask PC */ PC = PC & ((cpu_unit.flags & UNIT_EXT)? X_AMASK: NX_AMASK); /* mask PC */
reason = 0; reason = 0;
sim_rtc_init (clk_unit.wait); /* init calibration */
/* Main instruction fetch/decode loop */ /* Main instruction fetch/decode loop */

View file

@ -1,6 +1,6 @@
/* h316_lp.c: Honeywell 316/516 line printer /* h316_lp.c: Honeywell 316/516 line printer
Copyright (c) 1999-2006, Robert M. Supnik Copyright (c) 1999-2007, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
lpt line printer lpt line printer
19-Jan-06 RMS Added UNIT_TEXT flag
03-Apr-06 RMS Fixed bug in blanks backscanning (from Theo Engel) 03-Apr-06 RMS Fixed bug in blanks backscanning (from Theo Engel)
01-Dec-04 RMS Fixed bug in DMA/DMC support 01-Dec-04 RMS Fixed bug in DMA/DMC support
24-Oct-03 RMS Added DMA/DMC support 24-Oct-03 RMS Added DMA/DMC support
@ -105,7 +106,7 @@ t_stat lpt_reset (DEVICE *dptr);
DIB lpt_dib = { LPT, IOBUS, 1, &lptio }; DIB lpt_dib = { LPT, IOBUS, 1, &lptio };
UNIT lpt_unit = { UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE, 0) }; UNIT lpt_unit = { UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0) };
REG lpt_reg[] = { REG lpt_reg[] = {
{ DRDATA (WDPOS, lpt_wdpos, 6) }, { DRDATA (WDPOS, lpt_wdpos, 6) },

View file

@ -28,6 +28,8 @@
DMA0,DMA1 12607B/12578A/12895A direct memory access controller DMA0,DMA1 12607B/12578A/12895A direct memory access controller
DCPC0,DCPC1 12897B dual channel port controller DCPC0,DCPC1 12897B dual channel port controller
28-Apr-07 RMS Removed clock initialization
02-Mar-07 JDB EDT passes input flag and DMA channel in dat parameter
11-Jan-07 JDB Added 12578A DMA byte packing 11-Jan-07 JDB Added 12578A DMA byte packing
28-Dec-06 JDB CLC 0 now sends CRS instead of CLC to devices 28-Dec-06 JDB CLC 0 now sends CRS instead of CLC to devices
26-Dec-06 JDB Fixed improper IRQ deferral for 21xx CPUs 26-Dec-06 JDB Fixed improper IRQ deferral for 21xx CPUs
@ -378,7 +380,6 @@
#define UNIT_MP_INT (1 << UNIT_V_MP_INT) #define UNIT_MP_INT (1 << UNIT_V_MP_INT)
#define UNIT_MP_SEL1 (1 << UNIT_V_MP_SEL1) #define UNIT_MP_SEL1 (1 << UNIT_V_MP_SEL1)
#define ABORT(val) longjmp (save_env, (val)) #define ABORT(val) longjmp (save_env, (val))
#define DMAR0 1 #define DMAR0 1
@ -521,8 +522,6 @@ void hp_post_cmd (t_bool from_scp);
extern t_stat cpu_eau (uint32 IR, uint32 intrq); extern t_stat cpu_eau (uint32 IR, uint32 intrq);
extern t_stat cpu_uig_0 (uint32 IR, uint32 intrq, uint32 iotrap); extern t_stat cpu_uig_0 (uint32 IR, uint32 intrq, uint32 iotrap);
extern t_stat cpu_uig_1 (uint32 IR, uint32 intrq, uint32 iotrap); extern t_stat cpu_uig_1 (uint32 IR, uint32 intrq, uint32 iotrap);
extern int32 clk_delay (int32 flg);
extern void (*sim_vm_post) (t_bool from_scp); extern void (*sim_vm_post) (t_bool from_scp);
/* CPU data structures /* CPU data structures
@ -841,7 +840,6 @@ for (i = 0; dptr = sim_devices[i]; i++) { /* loop thru dev */
dtab[dev] = dibp->iot; /* set I/O dispatch */ dtab[dev] = dibp->iot; /* set I/O dispatch */
} }
} }
sim_rtc_init (clk_delay (0)); /* recalibrate clock */
/* Configure interrupt deferral table */ /* Configure interrupt deferral table */
@ -2023,7 +2021,7 @@ return dat;
- STC requested but not CLC: issue STC,C - STC requested but not CLC: issue STC,C
- CLC requested but not STC: issue CLC,C - CLC requested but not STC: issue CLC,C
- STC and CLC both requested: issue STC,C and CLC,C, in that order - STC and CLC both requested: issue STC,C and CLC,C, in that order
Either: issue EDT Either: issue EDT (pass DMA channel number and I/O flag)
*/ */
void dma_cycle (uint32 ch, uint32 map) void dma_cycle (uint32 ch, uint32 map)
@ -2101,7 +2099,7 @@ else {
} /* end output */ } /* end output */
setFLG (DMA0 + ch); /* set DMA flg */ setFLG (DMA0 + ch); /* set DMA flg */
clrCMD (DMA0 + ch); /* clr DMA cmd */ clrCMD (DMA0 + ch); /* clr DMA cmd */
devdisp (dev, ioEDT, dev, 0); /* do EDT */ devdisp (dev, ioEDT, dev, inp | ch); /* do EDT */
} }
return; return;
} }

View file

@ -1,6 +1,6 @@
SIMH/HP 21XX DIAGNOSTICS PERFORMANCE SIMH/HP 21XX DIAGNOSTICS PERFORMANCE
==================================== ====================================
Last update: 2007-01-12 Last update: 2007-03-05
The HP 24396 diagnostic suite has been run against the SIMH HP 21xx simulation. The HP 24396 diagnostic suite has been run against the SIMH HP 21xx simulation.
@ -62,8 +62,8 @@ The results of the diagnostic runs are summarized below:
103122 59310 Interface Bus Interface 1728 - No simulation 103122 59310 Interface Bus Interface 1728 - No simulation
103003 12587 Asynchronous Data Set Interface 1553 - No simulation 103003 12587 Asynchronous Data Set Interface 1553 - No simulation
103110 12920 Asynchronous Multiplexer (Data) 1805 - Not tested 103110 12920 Asynchronous Multiplexer (Data) 1805 3.7-1 Passed
103011 12920 Asynchronous Multiplexer (Cntl) 1444 - Not tested 103011 12920 Asynchronous Multiplexer (Cntl) 1444 3.7-1 Passed
103012 12621 Synchronous Data Set (Receive) 1532 - No simulation 103012 12621 Synchronous Data Set (Receive) 1532 - No simulation
103013 12621 Synchronous Data Set (Send) 1532 - No simulation 103013 12621 Synchronous Data Set (Send) 1532 - No simulation
103116 12967 Synchronous Interface 1438 - No simulation 103116 12967 Synchronous Interface 1438 - No simulation
@ -114,11 +114,11 @@ not supported by the 24396 suite:
Paper Tape Date SIMH Paper Tape Date SIMH
Part Number DSN Diagnostic Name Code Vers. Result Part Number DSN Diagnostic Name Code Vers. Result
----------- ------ --------------------------------------- ---- ----- ---------- ----------- ------ --------------------------------------- ---- ----- ----------
24203-60001 -- HP2100A Cartridge Disc Memory (2871) A 3.3-0 Partial
22682-16017 177777 HP 2100 Fixed Head Disc/Drum (277x) 1612 3.3-0 Passed
13207-16001 101217 2000/Access Comm Processor for 21MX 1728 3.2-3 Passed 13207-16001 101217 2000/Access Comm Processor for 21MX 1728 3.2-3 Passed
20433-????? -- HP 3030 Magnetic Tape Subsystem -- - Not tested 20433-????? -- HP 3030 Magnetic Tape Subsystem -- - Not tested
24197-60001 -- 12875 Processor Interconnect Cable B 3.7-1 Passed
24203-60001 -- HP2100A Cartridge Disc Memory (2871) A 3.3-0 Partial
22682-16017 177777 HP 2100 Fixed Head Disc/Drum (277x) 1612 3.3-0 Passed
The "SIMH Version" is the version number of the earliest SIMH system that was The "SIMH Version" is the version number of the earliest SIMH system that was
tested with the given diagnostic. Earlier versions may or may not work tested with the given diagnostic. Earlier versions may or may not work
@ -988,31 +988,71 @@ TEST RESULT: Passed.
-------------------------------------------------- ---------------------------------------------------
DSN 103110 - 12920 Asynchronous Multiplexer (Data) DSN 103110 - 12920A Asynchronous Multiplexer (Data)
-------------------------------------------------- ---------------------------------------------------
TESTED DEVICE: MUX, MUXL (hp2100_mux.c) TESTED DEVICE: MUX, MUXL (hp2100_mux.c)
CONFIGURATION: CONFIGURATION: sim> set MUX DIAG
sim> deposit S 004040
sim> reset
sim> go 100
TEST REPORT: HALT instruction 102074
TEST RESULT: Not tested. sim> deposit S 000000
sim> reset
sim> go
TEST REPORT: ASYNC MULTIPLEXER DATA BOARD DIAGNOSTIC DSN 103110
H024 PRESS PRESET (EXT&INT),RUN
HALT instruction 102024
sim> reset
sim> go
H025 BI-O COMP
PASS 000001
HALT instruction 102077
TEST RESULT: Passed.
-------------------------------------------------- ---------------------------------------------------
DSN 103011 - 12920 Asynchronous Multiplexer (Cntl) DSN 103011 - 12920A Asynchronous Multiplexer (Cntl)
-------------------------------------------------- ---------------------------------------------------
TESTED DEVICE: MUXM (hp2100_mux.c) TESTED DEVICE: MUXM (hp2100_mux.c)
CONFIGURATION: CONFIGURATION: sim> set MUX DIAG
sim> deposit S 004042
sim> reset
sim> go 100
TEST REPORT: HALT instruction 102074
TEST RESULT: Not tested. sim> deposit S 000000
sim> reset
sim> go
TEST REPORT: ASYNC MULTIPLEXER CONTROL BOARD DIAGNOSTIC
H024 PRESS PRESET (EXT&INT),RUN
HALT instruction 102024
sim> reset
sim> go
H025 BI-O COMP
PASS 000001
HALT instruction 102077
TEST RESULT: Passed.
@ -3117,6 +3157,41 @@ TEST RESULT: Passed.
-----------------------------------------------
DSN (none) - 12875 Processor Interconnect Cable
-----------------------------------------------
TESTED DEVICE: IPLI, IPLO (hp2100_ipl.c)
BINARY TAPE: 24197-60001 Rev. B
CONFIGURATION: sim> set IPLI DIAG
sim> set IPLO DIAG
sim> deposit S 003332
sim> reset
sim> go 2
HALT instruction 107076
sim> deposit S 010000
sim> reset
sim> go
HALT instruction 107077
sim> deposit S 000000
sim> reset
sim> go 100
TEST REPORT: H14. START 12875 CABLE DIAGNOSTIC
H77. END 12875 CABLE DIAGNOSTIC
HALT instruction 102077
TEST RESULT: Passed.
-------------------------------------------- --------------------------------------------
DSN (none) - HP 3030 Magnetic Tape Subsystem DSN (none) - HP 3030 Magnetic Tape Subsystem
-------------------------------------------- --------------------------------------------

View file

@ -1,6 +1,6 @@
/* hp2100_ipl.c: HP 2000 interprocessor link simulator /* hp2100_ipl.c: HP 2000 interprocessor link simulator
Copyright (c) 2002-2006, Robert M Supnik Copyright (c) 2002-2007, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -23,9 +23,11 @@
used in advertising or otherwise to promote the sale, use or other dealings used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik. in this Software without prior written authorization from Robert M Supnik.
ipli, iplo 12566B interprocessor link pair ipli, iplo 12875A interprocessor link
28-Dec-06 JDB Added ioCRS state to I/O decoders (action unverified) 01-Mar-07 JDB IPLI EDT delays DMA completion interrupt for TSB
Added debug printouts
28-Dec-06 JDB Added ioCRS state to I/O decoders
16-Aug-05 RMS Fixed C++ declaration and cast problems 16-Aug-05 RMS Fixed C++ declaration and cast problems
07-Oct-04 JDB Fixed enable/disable from either device 07-Oct-04 JDB Fixed enable/disable from either device
26-Apr-04 RMS Fixed SFS x,C and SFC x,C 26-Apr-04 RMS Fixed SFS x,C and SFC x,C
@ -33,6 +35,20 @@
21-Dec-03 RMS Adjusted ipl_ptime for TSB (from Mike Gemeny) 21-Dec-03 RMS Adjusted ipl_ptime for TSB (from Mike Gemeny)
09-May-03 RMS Added network device flag 09-May-03 RMS Added network device flag
31-Jan-03 RMS Links are full duplex (found by Mike Gemeny) 31-Jan-03 RMS Links are full duplex (found by Mike Gemeny)
The 12875A Processor Interconnect Kit consists four 12566A Microcircuit
Interface cards. Two are used in each processor. One card in each system is
used to initiate transmissions to the other, and the second card is used to
receive transmissions from the other. Each pair of cards forms a
bidirectional link, as the sixteen data lines are cross-connected, so that
data sent and status returned are supported. In each processor, data is sent
on the lower priority card and received on the higher priority card. Two
sets of cards are used to support simultaneous transmission in both
directions.
Reference:
- 12875A Processor Interconnect Kit Operating and Service Manual
(12875-90002, Jan-1974)
*/ */
#include "hp2100_defs.h" #include "hp2100_defs.h"
@ -52,9 +68,17 @@
#define DSOCKET u3 /* data socket */ #define DSOCKET u3 /* data socket */
#define LSOCKET u4 /* listening socket */ #define LSOCKET u4 /* listening socket */
/* Debug flags */
#define DEB_CMDS (1 << 0) /* Command initiation and completion */
#define DEB_CPU (1 << 1) /* CPU I/O */
#define DEB_XFER (1 << 2) /* Socket receive and transmit */
extern uint32 PC; extern uint32 PC;
extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2], dev_srq[2]; extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2], dev_srq[2];
extern FILE *sim_log; extern FILE *sim_log;
extern FILE *sim_deb;
int32 ipl_edtdelay = 1; /* EDT delay (msec) */
int32 ipl_ptime = 31; /* polling interval */ int32 ipl_ptime = 31; /* polling interval */
int32 ipl_stopioe = 0; /* stop on error */ int32 ipl_stopioe = 0; /* stop on error */
int32 ipl_hold[2] = { 0 }; /* holding character */ int32 ipl_hold[2] = { 0 }; /* holding character */
@ -72,6 +96,14 @@ t_stat ipl_dscln (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat ipl_setdiag (UNIT *uptr, int32 val, char *cptr, void *desc); t_stat ipl_setdiag (UNIT *uptr, int32 val, char *cptr, void *desc);
t_bool ipl_check_conn (UNIT *uptr); t_bool ipl_check_conn (UNIT *uptr);
/* Debug flags table */
DEBTAB ipl_deb[] = {
{ "CMDS", DEB_CMDS },
{ "CPU", DEB_CPU },
{ "XFER", DEB_XFER },
{ NULL, 0 } };
/* IPLI data structures /* IPLI data structures
ipli_dev IPLI device descriptor ipli_dev IPLI device descriptor
@ -125,7 +157,8 @@ DEVICE ipli_dev = {
1, 10, 31, 1, 16, 16, 1, 10, 31, 1, 16, 16,
&tmxr_ex, &tmxr_dep, &ipl_reset, &tmxr_ex, &tmxr_dep, &ipl_reset,
&ipl_boot, &ipl_attach, &ipl_detach, &ipl_boot, &ipl_attach, &ipl_detach,
&ipli_dib, DEV_NET | DEV_DISABLE | DEV_DIS &ipli_dib, DEV_NET | DEV_DISABLE | DEV_DIS | DEV_DEBUG,
0, ipl_deb, NULL, NULL
}; };
/* IPLO data structures /* IPLO data structures
@ -154,7 +187,8 @@ DEVICE iplo_dev = {
1, 10, 31, 1, 16, 16, 1, 10, 31, 1, 16, 16,
&tmxr_ex, &tmxr_dep, &ipl_reset, &tmxr_ex, &tmxr_dep, &ipl_reset,
&ipl_boot, &ipl_attach, &ipl_detach, &ipl_boot, &ipl_attach, &ipl_detach,
&iplo_dib, DEV_NET | DEV_DISABLE | DEV_DIS &iplo_dib, DEV_NET | DEV_DISABLE | DEV_DIS | DEV_DEBUG,
0, ipl_deb, NULL, NULL
}; };
/* I/O instructions */ /* I/O instructions */
@ -169,12 +203,61 @@ int32 iploio (int32 inst, int32 IR, int32 dat)
return iplio (&iplo_unit, inst, IR, dat); return iplio (&iplo_unit, inst, IR, dat);
} }
/* I/O handler for the IPLI and IPLO devices.
Implementation note: 2000 Access has a race condition that manifests itself
by an apparently normal boot and operational system console but no PLEASE LOG
IN response to terminals connected to the multiplexer. The frequency of
occurrence is higher on multiprocessor host systems, where the SP and IOP
instances may execute concurrently.
The cause is this code in the SP disc loader source (2883.asm, 7900.asm,
790X.asm, 79X3.asm, and 79XX.asm):
LDA SDVTR REQUEST
JSB IOPMA,I DEVICE TABLE
[...]
STC DMAHS,C TURN ON DMA
SFS DMAHS WAIT FOR
JMP *-1 DEVICE TABLE
STC CH2,C SET CORRECT
CLC CH2 FLAG DIRECTION
The STC/CLC normally would cause a second "request device table" command to
be recognized by the IOP, except that the IOP DMA setup routine "DMAXF" (in
D61.asm) has specified an end-of-block CLC that holds off the IPL interrupt,
and the completion interrupt routine "DMACP" ends with a STC,C that clears
the IPL flag.
In hardware, the two CPUs are essentially interlocked by the DMA transfer,
and DMA completion interrupts occur almost simultaneously. Therefore, the
STC/CLC in the SP is guaranteed to occur before the STC,C in the IOP. Under
simulation, and especially on multiprocessor hosts, that guarantee does not
hold. If the STC/CLC occurs after the STC,C, then the IOP starts a second
device table DMA transfer, which the SP is not expecting. The IOP never
processes the subsequent "start timesharing" command, and the muxtiplexer is
non-reponsive.
We employ a workaround that decreases the incidence of the problem: DMA
output completion interrupts are delayed to allow the other SIMH instance a
chance to process its own DMA completion. We do this by processing the EDT
(End Data Transfer) I/O backplane signal and "sleep"ing for a short time if
the transfer was an output transfer ("dat" contains the DMA channel number
and direction flag for EDT signals).
*/
int32 iplio (UNIT *uptr, int32 inst, int32 IR, int32 dat) int32 iplio (UNIT *uptr, int32 inst, int32 IR, int32 dat)
{ {
uint32 u, dev, odev; uint32 u, dev, odev;
int32 sta; int32 sta;
char msg[2]; char msg[2], uc;
DEVICE *dbdev; /* device ptr for debug */
static const char *iotype[] = { "Status", "Command" };
uc = (uptr == &ipli_unit) ? 'I' : 'O'; /* identify unit for debug */
dbdev = (uptr == &ipli_unit) ? &ipli_dev : &iplo_dev; /* identify device for debug */
u = (uptr - ipl_unit); /* get unit number */
dev = IR & I_DEVMASK; /* get device no */ dev = IR & I_DEVMASK; /* get device no */
switch (inst) { /* case on opcode */ switch (inst) { /* case on opcode */
@ -192,25 +275,42 @@ switch (inst) { /* case on opcode */
case ioOTX: /* output */ case ioOTX: /* output */
uptr->OBUF = dat; uptr->OBUF = dat;
if (DEBUG_PRJ (dbdev, DEB_CPU))
fprintf (sim_deb, ">>IPL%c OTx: %s = %06o\n", uc, iotype[u], dat);
break; break;
case ioLIX: /* load */ case ioLIX: /* load */
dat = uptr->IBUF; /* return val */ dat = 0;
break;
case ioMIX: /* merge */ case ioMIX: /* merge */
dat = dat | uptr->IBUF; /* get return data */ dat = dat | uptr->IBUF; /* get return data */
if (DEBUG_PRJ (dbdev, DEB_CPU))
fprintf (sim_deb, ">>IPL%c LIx: %s = %06o\n", uc, iotype[u ^ 1], dat);
break;
case ioCRS: /* control reset */
clrCMD (dev); /* clear ctl, cmd */
clrCTL (dev);
break; break;
case ioCRS: /* control reset (action unverif) */
case ioCTL: /* control clear/set */ case ioCTL: /* control clear/set */
if (IR & I_CTL) { /* CLC */ if (IR & I_CTL) { /* CLC */
clrCMD (dev); /* clear ctl, cmd */ clrCMD (dev); /* clear ctl, cmd */
clrCTL (dev); clrCTL (dev);
if (DEBUG_PRJ (dbdev, DEB_CMDS))
fprintf (sim_deb, ">>IPL%c CLC: Command cleared\n", uc);
} }
else { /* STC */ else { /* STC */
setCMD (dev); /* set ctl, cmd */ setCMD (dev); /* set ctl, cmd */
setCTL (dev); setCTL (dev);
if (DEBUG_PRJ (dbdev, DEB_CMDS))
fprintf (sim_deb, ">>IPL%c STC: Command set\n", uc);
if (uptr->flags & UNIT_ATT) { /* attached? */ if (uptr->flags & UNIT_ATT) { /* attached? */
if ((uptr->flags & UNIT_ESTB) == 0) { /* established? */ if ((uptr->flags & UNIT_ESTB) == 0) { /* established? */
if (!ipl_check_conn (uptr)) /* not established? */ if (!ipl_check_conn (uptr)) /* not established? */
@ -220,6 +320,12 @@ switch (inst) { /* case on opcode */
msg[0] = (uptr->OBUF >> 8) & 0377; msg[0] = (uptr->OBUF >> 8) & 0377;
msg[1] = uptr->OBUF & 0377; msg[1] = uptr->OBUF & 0377;
sta = sim_write_sock (uptr->DSOCKET, msg, 2); sta = sim_write_sock (uptr->DSOCKET, msg, 2);
if (DEBUG_PRJ (dbdev, DEB_XFER))
fprintf (sim_deb,
">>IPL%c STC: Socket write = %06o, status = %d\n",
uc, uptr->OBUF, sta);
if (sta == SOCKET_ERROR) { if (sta == SOCKET_ERROR) {
printf ("IPL: socket write error\n"); printf ("IPL: socket write error\n");
return SCPE_IOERR; return SCPE_IOERR;
@ -236,6 +342,16 @@ switch (inst) { /* case on opcode */
} }
break; break;
case ioEDT: /* End of DMA data transfer */
if ((dat & DMA2_OI) == 0) { /* output transfer? */
if (DEBUG_PRJ (dbdev, DEB_CMDS))
fprintf (sim_deb,
">>IPL%c EDT: Delaying DMA completion interrupt for %d msec\n",
uc, ipl_edtdelay);
sim_os_ms_sleep (ipl_edtdelay); /* delay completion */
}
break;
default: default:
break; break;
} }
@ -249,7 +365,8 @@ return dat;
t_stat ipl_svc (UNIT *uptr) t_stat ipl_svc (UNIT *uptr)
{ {
int32 u, nb, dev; int32 u, nb, dev;
char msg[2]; char msg[2], uc;
DEVICE *dbdev; /* device ptr for debug */
u = uptr - ipl_unit; /* get link number */ u = uptr - ipl_unit; /* get link number */
if ((uptr->flags & UNIT_ATT) == 0) return SCPE_OK; /* not attached? */ if ((uptr->flags & UNIT_ATT) == 0) return SCPE_OK; /* not attached? */
@ -277,6 +394,14 @@ else uptr->IBUF = ((((int32) msg[0]) & 0377) << 8) |
dev = ipl_dib[u].devno; /* get device number */ dev = ipl_dib[u].devno; /* get device number */
clrCMD (dev); /* clr cmd, set flag */ clrCMD (dev); /* clr cmd, set flag */
setFSR (dev); setFSR (dev);
uc = (uptr == &ipli_unit) ? 'I' : 'O'; /* identify unit for debug */
dbdev = (uptr == &ipli_unit) ? &ipli_dev : &iplo_dev; /* identify device for debug */
if (DEBUG_PRJ (dbdev, DEB_XFER))
fprintf (sim_deb, ">>IPL%c svc: Socket read = %06o, status = %d\n",
uc, uptr->IBUF, nb);
return SCPE_OK; return SCPE_OK;
} }
@ -524,4 +649,3 @@ M[PC + IPL_DEVA] = devi;
M[PC + PTR_DEVA] = devp; M[PC + PTR_DEVA] = devp;
return SCPE_OK; return SCPE_OK;
} }

View file

@ -26,6 +26,7 @@
lps 12653A 2767 line printer lps 12653A 2767 line printer
12566B microcircuit interface with loopback diagnostic connector 12566B microcircuit interface with loopback diagnostic connector
10-May-07 RMS Added UNIT_TEXT flag
11-Jan-07 JDB CLC cancels I/O event if DIAG (jumper W9 in "A" pos) 11-Jan-07 JDB CLC cancels I/O event if DIAG (jumper W9 in "A" pos)
Added ioCRS state to I/O decoders Added ioCRS state to I/O decoders
19-Nov-04 JDB Added restart when set online, etc. 19-Nov-04 JDB Added restart when set online, etc.
@ -207,7 +208,7 @@ t_stat lps_show_timing (FILE *st, UNIT *uptr, int32 val, void *desc);
DIB lps_dib = { LPS, 0, 0, 0, 0, 0, &lpsio }; DIB lps_dib = { LPS, 0, 0, 0, 0, 0, &lpsio };
UNIT lps_unit = { UNIT lps_unit = {
UDATA (&lps_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_DISABLE, 0) UDATA (&lps_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_DISABLE+UNIT_TEXT, 0)
}; };
REG lps_reg[] = { REG lps_reg[] = {

View file

@ -1,6 +1,6 @@
/* hp2100_lpt.c: HP 2100 12845B line printer simulator /* hp2100_lpt.c: HP 2100 12845B line printer simulator
Copyright (c) 1993-2006, Robert M. Supnik Copyright (c) 1993-2007, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
lpt 12845B 2607 line printer lpt 12845B 2607 line printer
22-Jan-07 RMS Added UNIT_TEXT flag
28-Dec-06 JDB Added ioCRS state to I/O decoders (action unverified) 28-Dec-06 JDB Added ioCRS state to I/O decoders (action unverified)
19-Nov-04 JDB Added restart when set online, etc. 19-Nov-04 JDB Added restart when set online, etc.
29-Sep-04 JDB Added SET OFFLINE/ONLINE, POWEROFF/POWERON 29-Sep-04 JDB Added SET OFFLINE/ONLINE, POWEROFF/POWERON
@ -113,7 +114,7 @@ t_stat lpt_attach (UNIT *uptr, char *cptr);
DIB lpt_dib = { LPT, 0, 0, 0, 0, 0, &lptio }; DIB lpt_dib = { LPT, 0, 0, 0, 0, 0, &lptio };
UNIT lpt_unit = { UNIT lpt_unit = {
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_DISABLE, 0) UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_DISABLE+UNIT_TEXT, 0)
}; };
REG lpt_reg[] = { REG lpt_reg[] = {

View file

@ -1,6 +1,6 @@
/* hp2100_mux.c: HP 2100 12920A terminal multiplexor simulator /* hp2100_mux.c: HP 2100 12920A terminal multiplexor simulator
Copyright (c) 2002-2006, Robert M Supnik Copyright (c) 2002-2007, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -25,7 +25,19 @@
mux,muxl,muxc 12920A terminal multiplexor mux,muxl,muxc 12920A terminal multiplexor
28-Dec-06 JDB Added ioCRS state to I/O decoders (action unverified) 06-Mar-07 JDB Corrected "mux_sta" size from 16 to 21 elements
Fixed "muxc_reset" to clear lines 16-20
26-Feb-07 JDB Added debug printouts
Fixed control card OTx to set current channel number
Fixed to set "muxl_ibuf" in response to a transmit interrupt
Changed "mux_xbuf", "mux_rbuf" declarations from 8 to 16 bits
Fixed to set "mux_rchp" when a line break is received
Fixed incorrect "odd_par" table values
Reversed test in "RCV_PAR" to return "LIL_PAR" on odd parity
Fixed mux reset (ioCRS) to clear port parameters
Fixed to use PUT_DCH instead of PUT_CCH for data channel status
10-Feb-07 JDB Added DIAG/TERM modifiers to implement diagnostic mode
28-Dec-06 JDB Added ioCRS state to I/O decoders
02-Jun-06 JDB Fixed compiler warning for mux_ldsc init 02-Jun-06 JDB Fixed compiler warning for mux_ldsc init
22-Nov-05 RMS Revised for new terminal processing routines 22-Nov-05 RMS Revised for new terminal processing routines
29-Jun-05 RMS Added SET MUXLn DISCONNECT 29-Jun-05 RMS Added SET MUXLn DISCONNECT
@ -60,7 +72,9 @@
#define MUX_LINES 16 /* user lines */ #define MUX_LINES 16 /* user lines */
#define MUX_ILINES 5 /* diag rcv only */ #define MUX_ILINES 5 /* diag rcv only */
#define UNIT_V_MDM (TTUF_V_UF + 0) /* modem control */ #define UNIT_V_MDM (TTUF_V_UF + 0) /* modem control */
#define UNIT_V_DIAG (TTUF_V_UF + 1) /* loopback diagnostic */
#define UNIT_MDM (1 << UNIT_V_MDM) #define UNIT_MDM (1 << UNIT_V_MDM)
#define UNIT_DIAG (1 << UNIT_V_DIAG)
#define MUXU_INIT_POLL 8000 #define MUXU_INIT_POLL 8000
#define MUXL_WAIT 500 #define MUXL_WAIT 500
@ -85,7 +99,8 @@
#define OTL_V_BAUD 0 /* baud rate */ #define OTL_V_BAUD 0 /* baud rate */
#define OTL_M_BAUD 0377 #define OTL_M_BAUD 0377
#define OTL_BAUD(x) (((x) >> OTL_V_BAUD) & OTL_M_BAUD) #define OTL_BAUD(x) (((x) >> OTL_V_BAUD) & OTL_M_BAUD)
#define OTL_CHAR 01777 /* char mask */ #define OTL_CHAR 03777 /* char mask */
#define OTL_PAR 0200 /* char parity */
/* LIA, lower = received data */ /* LIA, lower = received data */
@ -112,6 +127,7 @@
#define OTC_EC1 0000100 #define OTC_EC1 0000100
#define OTC_C2 0000040 /* Cn flops */ #define OTC_C2 0000040 /* Cn flops */
#define OTC_C1 0000020 #define OTC_C1 0000020
#define OTC_V_C 4 /* S1 to C1 */
#define OTC_ES2 0000010 /* enb comparison */ #define OTC_ES2 0000010 /* enb comparison */
#define OTC_ES1 0000004 #define OTC_ES1 0000004
#define OTC_V_ES 2 #define OTC_V_ES 2
@ -139,14 +155,21 @@
((muxc_ota[ch] & (OTC_ES2|OTC_ES1)) >> OTC_V_ES)) \ ((muxc_ota[ch] & (OTC_ES2|OTC_ES1)) >> OTC_V_ES)) \
<< LIC_V_I) << LIC_V_I)
/* Debug flags */
#define DEB_CMDS (1 << 0) /* Command initiation and completion */
#define DEB_CPU (1 << 1) /* CPU I/O */
#define DEB_XFER (1 << 2) /* Socket receive and transmit */
extern uint32 PC; extern uint32 PC;
extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2], dev_srq[2]; extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2], dev_srq[2];
extern FILE *sim_deb;
uint16 mux_sta[MUX_LINES]; /* line status */ uint16 mux_sta[MUX_LINES + MUX_ILINES]; /* line status */
uint16 mux_rpar[MUX_LINES + MUX_ILINES]; /* rcv param */ uint16 mux_rpar[MUX_LINES + MUX_ILINES]; /* rcv param */
uint16 mux_xpar[MUX_LINES]; /* xmt param */ uint16 mux_xpar[MUX_LINES]; /* xmt param */
uint8 mux_rbuf[MUX_LINES + MUX_ILINES]; /* rcv buf */ uint16 mux_rbuf[MUX_LINES + MUX_ILINES]; /* rcv buf */
uint8 mux_xbuf[MUX_LINES]; /* xmt buf */ uint16 mux_xbuf[MUX_LINES]; /* xmt buf */
uint8 mux_rchp[MUX_LINES + MUX_ILINES]; /* rcv chr pend */ uint8 mux_rchp[MUX_LINES + MUX_ILINES]; /* rcv chr pend */
uint8 mux_xdon[MUX_LINES]; /* xmt done */ uint8 mux_xdon[MUX_LINES]; /* xmt done */
uint8 muxc_ota[MUX_LINES]; /* ctrl: Cn,ESn,SSn */ uint8 muxc_ota[MUX_LINES]; /* ctrl: Cn,ESn,SSn */
@ -171,6 +194,7 @@ t_stat muxo_svc (UNIT *uptr);
t_stat muxc_reset (DEVICE *dptr); t_stat muxc_reset (DEVICE *dptr);
t_stat mux_attach (UNIT *uptr, char *cptr); t_stat mux_attach (UNIT *uptr, char *cptr);
t_stat mux_detach (UNIT *uptr); t_stat mux_detach (UNIT *uptr);
t_stat mux_setdiag (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat mux_summ (FILE *st, UNIT *uptr, int32 val, void *desc); t_stat mux_summ (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat mux_show (FILE *st, UNIT *uptr, int32 val, void *desc); t_stat mux_show (FILE *st, UNIT *uptr, int32 val, void *desc);
void mux_data_int (void); void mux_data_int (void);
@ -179,24 +203,33 @@ void mux_diag (int32 c);
static uint8 odd_par[256] = { static uint8 odd_par[256] = {
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 000-017 */ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 000-017 */
0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, /* 020-037 */ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, /* 020-037 */
0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, /* 040-067 */ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, /* 040-067 */
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 060-077 */ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 060-077 */
0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, /* 100-117 */ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, /* 100-117 */
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 120-137 */ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 120-137 */
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 140-157 */ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 140-157 */
0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, /* 160-177 */ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, /* 160-177 */
0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, /* 200-217 */ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, /* 200-217 */
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 220-237 */ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 220-237 */
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 240-257 */ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 240-267 */
0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, /* 260-277 */ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, /* 260-277 */
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 300-317 */ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 300-317 */
0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, /* 320-337 */ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, /* 320-337 */
0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, /* 340-367 */ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, /* 340-357 */
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1 /* 360-377 */ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1 /* 360-377 */
}; };
#define RCV_PAR(x) (odd_par[(x) & 0377]? LIL_PAR: 0) #define RCV_PAR(x) (odd_par[(x) & 0377] ? 0 : LIL_PAR)
#define XMT_PAR(x) (odd_par[(x) & 0377] ? 0 : OTL_PAR)
/* Debug flags table */
DEBTAB mux_deb[] = {
{ "CMDS", DEB_CMDS },
{ "CPU", DEB_CPU },
{ "XFER", DEB_XFER },
{ NULL, 0 } };
DIB mux_dib[] = { DIB mux_dib[] = {
{ MUXL, 0, 0, 0, 0, 0, &muxlio }, { MUXL, 0, 0, 0, 0, 0, &muxlio },
@ -229,6 +262,8 @@ REG muxu_reg[] = {
}; };
MTAB muxu_mod[] = { MTAB muxu_mod[] = {
{ UNIT_DIAG, UNIT_DIAG, "diagnostic mode", "DIAG", &mux_setdiag },
{ UNIT_DIAG, 0, "terminal mode", "TERM", &mux_setdiag },
{ UNIT_ATT, UNIT_ATT, "connections", NULL, NULL, &mux_summ }, { UNIT_ATT, UNIT_ATT, "connections", NULL, NULL, &mux_summ },
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 1, "CONNECTIONS", NULL, { MTAB_XTD | MTAB_VDV | MTAB_NMO, 1, "CONNECTIONS", NULL,
NULL, &mux_show, NULL }, NULL, &mux_show, NULL },
@ -246,7 +281,8 @@ DEVICE muxu_dev = {
1, 10, 31, 1, 8, 8, 1, 10, 31, 1, 8, 8,
&tmxr_ex, &tmxr_dep, &muxc_reset, &tmxr_ex, &tmxr_dep, &muxc_reset,
NULL, &mux_attach, &mux_detach, NULL, &mux_attach, &mux_detach,
&muxu_dib, DEV_NET | DEV_DISABLE &muxu_dib, DEV_NET | DEV_DISABLE | DEV_DEBUG,
0, mux_deb, NULL, NULL
}; };
/* MUXL data structures /* MUXL data structures
@ -301,11 +337,11 @@ REG muxl_reg[] = {
{ FLDATA (FLG, muxl_dib.flg, 0) }, { FLDATA (FLG, muxl_dib.flg, 0) },
{ FLDATA (FBF, muxl_dib.fbf, 0) }, { FLDATA (FBF, muxl_dib.fbf, 0) },
{ FLDATA (SRQ, muxl_dib.srq, 0) }, { FLDATA (SRQ, muxl_dib.srq, 0) },
{ BRDATA (STA, mux_sta, 8, 16, MUX_LINES) }, { BRDATA (STA, mux_sta, 8, 16, MUX_LINES + MUX_ILINES) },
{ BRDATA (RPAR, mux_rpar, 8, 16, MUX_LINES + MUX_ILINES) }, { BRDATA (RPAR, mux_rpar, 8, 16, MUX_LINES + MUX_ILINES) },
{ BRDATA (XPAR, mux_xpar, 8, 16, MUX_LINES) }, { BRDATA (XPAR, mux_xpar, 8, 16, MUX_LINES) },
{ BRDATA (RBUF, mux_rbuf, 8, 8, MUX_LINES + MUX_ILINES) }, { BRDATA (RBUF, mux_rbuf, 8, 16, MUX_LINES + MUX_ILINES) },
{ BRDATA (XBUF, mux_xbuf, 8, 8, MUX_LINES) }, { BRDATA (XBUF, mux_xbuf, 8, 16, MUX_LINES) },
{ BRDATA (RCHP, mux_rchp, 8, 1, MUX_LINES + MUX_ILINES) }, { BRDATA (RCHP, mux_rchp, 8, 1, MUX_LINES + MUX_ILINES) },
{ BRDATA (XDON, mux_xdon, 8, 1, MUX_LINES) }, { BRDATA (XDON, mux_xdon, 8, 1, MUX_LINES) },
{ URDATA (TIME, muxl_unit[0].wait, 10, 24, 0, { URDATA (TIME, muxl_unit[0].wait, 10, 24, 0,
@ -362,13 +398,25 @@ DEVICE muxc_dev = {
&muxc_dib, DEV_DISABLE &muxc_dib, DEV_DISABLE
}; };
/* IO instructions: data cards */ /* IO instructions: data cards
Implementation note: the operating manual says that "at least 100
milliseconds of CLC 0s must be programmed" by systems employing the
multiplexer to ensure that the multiplexer resets. In practice, such systems
issue 128K CLC 0 instructions. As we provide debug logging of multiplexer
resets, a CRS counter is used to ensure that only one debug line is printed
in response to these 128K CRS invocations.
*/
int32 muxlio (int32 inst, int32 IR, int32 dat) int32 muxlio (int32 inst, int32 IR, int32 dat)
{ {
int32 dev, ln; int32 dev, ln;
t_bool is_crs;
static uint32 crs_count = 0; /* cntr for crs repeat */
dev = IR & I_DEVMASK; /* get device no */ dev = IR & I_DEVMASK; /* get device no */
is_crs = FALSE;
switch (inst) { /* case on opcode */ switch (inst) { /* case on opcode */
case ioFLG: /* flag clear/set */ case ioFLG: /* flag clear/set */
@ -385,37 +433,107 @@ switch (inst) { /* case on opcode */
case ioOTX: /* output */ case ioOTX: /* output */
muxl_obuf = dat; /* store data */ muxl_obuf = dat; /* store data */
break;
case ioMIX: /* merge */ if (DEBUG_PRI (muxu_dev, DEB_CPU))
dat = dat | muxl_ibuf; if (dat & OTL_P)
fprintf (sim_deb, ">>MUXl OTx: Parameter = %06o\n", dat);
else
fprintf (sim_deb, ">>MUXl OTx: Data = %06o\n", dat);
break; break;
case ioLIX: /* load */ case ioLIX: /* load */
dat = muxl_ibuf; dat = 0;
case ioMIX: /* merge */
dat = dat | muxl_ibuf;
if (DEBUG_PRI (muxu_dev, DEB_CPU))
fprintf (sim_deb, ">>MUXl LIx: Data = %06o\n", dat);
break; break;
case ioCRS: /* control reset (action unverif) */ case ioCRS: /* control reset */
is_crs = TRUE;
if (crs_count) /* already reset? */
break; /* skip redundant clear */
for (ln = 0; ln < MUX_LINES; ln++) { /* clear transmit info */
mux_xbuf[ln] = mux_xpar[ln] = 0;
muxc_ota[ln] = muxc_lia[ln] = mux_xdon[ln] = 0;
}
for (ln = 0; ln < (MUX_LINES + MUX_ILINES); ln++) {
mux_rbuf[ln] = mux_rpar[ln] = 0; /* clear receive info */
mux_sta[ln] = mux_rchp[ln] = 0;
} /* fall into CLC SC */
case ioCTL: /* control clear/set */ case ioCTL: /* control clear/set */
if (IR & I_CTL) { clrCTL (dev); } /* CLC */ if (IR & I_CTL) { /* CLC */
clrCTL (dev);
if (DEBUG_PRI (muxu_dev, DEB_CMDS))
fprintf (sim_deb, ">>MUXl CLC: Data interrupt inhibited\n");
}
else { /* STC */ else { /* STC */
setCTL (dev); /* set ctl */ setCTL (dev); /* set ctl */
ln = MUX_CHAN (muxu_obuf); /* get chan # */ ln = MUX_CHAN (muxu_obuf); /* get chan # */
if (muxl_obuf & OTL_P) { /* parameter set? */
if (muxl_obuf & OTL_TX) { /* transmit? */ if (muxl_obuf & OTL_TX) { /* transmit? */
if (ln < MUX_LINES) /* to valid line? */ if (ln < MUX_LINES) { /* line valid? */
mux_xpar[ln] = muxl_obuf; if (muxl_obuf & OTL_P) { /* parameter? */
} mux_xpar[ln] = muxl_obuf; /* store param value */
else if (ln < (MUX_LINES + MUX_ILINES)) /* rcv, valid line? */ if (DEBUG_PRI (muxu_dev, DEB_CMDS))
mux_rpar[ln] = muxl_obuf; fprintf (sim_deb,
} ">>MUXl STC: Transmit channel %d parameter %06o stored\n",
else if ((muxl_obuf & OTL_TX) && /* xmit data? */ ln, muxl_obuf);
(ln < MUX_LINES)) { /* to valid line? */ }
if (sim_is_active (&muxl_unit[ln])) /* still working? */
mux_sta[ln] = mux_sta[ln] | LIU_LOST; else { /* data */
else sim_activate (&muxl_unit[ln], muxl_unit[ln].wait); if (mux_xpar[ln] & OTL_TPAR) /* parity requested? */
mux_xbuf[ln] = muxl_obuf & OTL_CHAR; /* load buffer */ muxl_obuf = /* add parity bit */
muxl_obuf & ~OTL_PAR |
XMT_PAR(muxl_obuf);
mux_xbuf[ln] = muxl_obuf; /* load buffer */
if (sim_is_active (&muxl_unit[ln])) { /* still working? */
mux_sta[ln] = mux_sta[ln] | LIU_LOST; /* char lost */
if (DEBUG_PRI (muxu_dev, DEB_CMDS))
fprintf (sim_deb,
">>MUXl STC: Transmit channel %d data overrun\n", ln);
}
else {
if (muxu_unit.flags & UNIT_DIAG) /* loopback? */
mux_ldsc[ln].conn = 1; /* connect this line */
sim_activate (&muxl_unit[ln], muxl_unit[ln].wait);
if (DEBUG_PRI (muxu_dev, DEB_CMDS))
fprintf (sim_deb,
">>MUXl STC: Transmit channel %d data %06o scheduled\n",
ln, muxl_obuf);
}
}
}
else if (DEBUG_PRI (muxu_dev, DEB_CMDS)) /* line invalid */
fprintf (sim_deb, ">>MUXl STC: Transmit channel %d invalid\n", ln);
} }
else /* receive */
if (ln < (MUX_LINES + MUX_ILINES)) { /* line valid? */
if (muxl_obuf & OTL_P) { /* parameter? */
mux_rpar[ln] = muxl_obuf; /* store param value */
if (DEBUG_PRI (muxu_dev, DEB_CMDS))
fprintf (sim_deb,
">>MUXl STC: Receive channel %d parameter %06o stored\n",
ln, muxl_obuf);
}
else if (DEBUG_PRI (muxu_dev, DEB_CMDS)) /* data (invalid action) */
fprintf (sim_deb,
">>MUXl STC: Receive channel %d parameter %06o invalid action\n",
ln, muxl_obuf);
}
else if (DEBUG_PRI (muxu_dev, DEB_CMDS)) /* line invalid */
fprintf (sim_deb, ">>MUXl STC: Receive channel %d invalid\n", ln);
} /* end STC */ } /* end STC */
break; break;
@ -423,6 +541,16 @@ switch (inst) { /* case on opcode */
break; break;
} }
if (is_crs) /* control reset? */
crs_count = crs_count + 1; /* increment count */
else if (crs_count) { /* something else */
if (DEBUG_PRI (muxu_dev, DEB_CMDS)) /* report reset count */
fprintf (sim_deb,
">>MUXl CRS: Multiplexer reset %d times\n", crs_count);
crs_count = 0; /* clear counter */
}
if (IR & I_HC) { /* H/C option */ if (IR & I_HC) { /* H/C option */
clrFSR (dev); /* clear flag */ clrFSR (dev); /* clear flag */
mux_data_int (); /* look for new int */ mux_data_int (); /* look for new int */
@ -436,14 +564,19 @@ switch (inst) { /* case on opcode */
case ioOTX: /* output */ case ioOTX: /* output */
muxu_obuf = dat; /* store data */ muxu_obuf = dat; /* store data */
break;
case ioMIX: /* merge */ if (DEBUG_PRI (muxu_dev, DEB_CPU))
dat = dat | muxu_ibuf; fprintf (sim_deb, ">>MUXu OTx: Data channel = %d\n", MUX_CHAN(dat));
break; break;
case ioLIX: /* load */ case ioLIX: /* load */
dat = muxu_ibuf; dat = 0;
case ioMIX: /* merge */
dat = dat | muxu_ibuf;
if (DEBUG_PRI (muxu_dev, DEB_CPU))
fprintf (sim_deb, ">>MUXu LIx: Status = %06o, channel = %d\n", dat, MUX_CHAN(dat));
break; break;
default: default:
@ -453,7 +586,12 @@ switch (inst) { /* case on opcode */
return dat; return dat;
} }
/* IO instructions: control card */ /* IO instructions: control card
In diagnostic mode, the control signals C1 and C2 are looped back to status
signals S1 and S2. Changing the control signals may cause an interrupt, so a
test is performed after OTx processing.
*/
int32 muxcio (int32 inst, int32 IR, int32 dat) int32 muxcio (int32 inst, int32 IR, int32 dat)
{ {
@ -475,38 +613,65 @@ switch (inst) { /* case on opcode */
break; break;
case ioOTX: /* output */ case ioOTX: /* output */
ln = muxc_chan = OTC_CHAN (dat); /* set channel */
if (dat & OTC_SCAN) muxc_scan = 1; /* set scan flag */ if (dat & OTC_SCAN) muxc_scan = 1; /* set scan flag */
else muxc_scan = 0; else muxc_scan = 0;
if (dat & OTC_UPD) { /* update? */ if (dat & OTC_UPD) { /* update? */
ln = OTC_CHAN (dat); /* get channel */
old = muxc_ota[ln]; /* save prior val */ old = muxc_ota[ln]; /* save prior val */
muxc_ota[ln] = (muxc_ota[ln] & ~OTC_RW) | /* save ESn,SSn */ muxc_ota[ln] = /* save ESn,SSn */
(dat & OTC_RW); (muxc_ota[ln] & ~OTC_RW) | (dat & OTC_RW);
if (dat & OTC_EC2) muxc_ota[ln] = /* if EC2, upd C2 */
(muxc_ota[ln] & ~OTC_C2) | (dat & OTC_C2); if (dat & OTC_EC2) /* if EC2, upd C2 */
if (dat & OTC_EC1) muxc_ota[ln] = /* if EC1, upd C1 */ muxc_ota[ln] =
(muxc_ota[ln] & ~OTC_C1) | (dat & OTC_C1); (muxc_ota[ln] & ~OTC_C2) | (dat & OTC_C2);
if ((muxl_unit[ln].flags & UNIT_MDM) && /* modem ctrl? */
(old & DTR) && !(muxc_ota[ln] & DTR)) { /* DTR drop? */ if (dat & OTC_EC1) /* if EC1, upd C1 */
muxc_ota[ln] =
(muxc_ota[ln] & ~OTC_C1) | (dat & OTC_C1);
if (muxu_unit.flags & UNIT_DIAG) /* loopback? */
muxc_lia[ln ^ 1] = /* set S1, S2 to C1, C2 */
(muxc_lia[ln ^ 1] & ~(LIC_S2 | LIC_S1)) |
(muxc_ota[ln] & (OTC_C1 | OTC_C2)) >> OTC_V_C;
else if ((muxl_unit[ln].flags & UNIT_MDM) && /* modem ctrl? */
(old & DTR) && /* DTR drop? */
!(muxc_ota[ln] & DTR)) {
tmxr_linemsg (&mux_ldsc[ln], "\r\nLine hangup\r\n"); tmxr_linemsg (&mux_ldsc[ln], "\r\nLine hangup\r\n");
tmxr_reset_ln (&mux_ldsc[ln]); /* reset line */ tmxr_reset_ln (&mux_ldsc[ln]); /* reset line */
muxc_lia[ln] = 0; /* dataset off */ muxc_lia[ln] = 0; /* dataset off */
} }
} /* end update */ } /* end update */
if (DEBUG_PRI (muxu_dev, DEB_CPU))
fprintf (sim_deb, ">>MUXc OTx: Parameter = %06o, channel = %d\n",
dat, ln);
if ((muxu_unit.flags & UNIT_DIAG) && /* loopback? */
(!FLG(muxc_dib.devno))) /* flag clear? */
mux_ctrl_int (); /* status chg may interrupt */
break; break;
case ioLIX: /* load */ case ioLIX: /* load */
dat = 0; dat = 0;
case ioMIX: /* merge */ case ioMIX: /* merge */
t = LIC_MBO | PUT_CCH (muxc_chan) | /* mbo, chan num */ t = LIC_MBO | PUT_CCH (muxc_chan) | /* mbo, chan num */
LIC_TSTI (muxc_chan) | /* I2, I1 */ LIC_TSTI (muxc_chan) | /* I2, I1 */
(muxc_ota[muxc_chan] & (OTC_ES2 | OTC_ES1)) | /* ES2, ES1 */ (muxc_ota[muxc_chan] & (OTC_ES2 | OTC_ES1)) | /* ES2, ES1 */
(muxc_lia[muxc_chan] & (LIC_S2 | LIC_S1)); /* S2, S1 */ (muxc_lia[muxc_chan] & (LIC_S2 | LIC_S1)); /* S2, S1 */
dat = dat | t; /* return status */ dat = dat | t; /* return status */
if (DEBUG_PRI (muxu_dev, DEB_CPU))
fprintf (sim_deb, ">>MUXc LIx: Status = %06o, channel = %d\n",
dat, muxc_chan);
muxc_chan = (muxc_chan + 1) & LIC_M_CHAN; /* incr channel */ muxc_chan = (muxc_chan + 1) & LIC_M_CHAN; /* incr channel */
break; break;
case ioCRS: /* control reset (action unverif) */ case ioCRS: /* control reset */
case ioCTL: /* ctrl clear/set */ case ioCTL: /* ctrl clear/set */
if (IR & I_CTL) { clrCTL (dev); } /* CLC */ if (IR & I_CTL) { clrCTL (dev); } /* CLC */
else { setCTL (dev); } /* STC */ else { setCTL (dev); } /* STC */
@ -532,41 +697,70 @@ return dat;
t_stat muxi_svc (UNIT *uptr) t_stat muxi_svc (UNIT *uptr)
{ {
int32 ln, c, t; int32 ln, c, t;
t_bool loopback;
loopback = ((muxu_unit.flags & UNIT_DIAG) != 0); /* diagnostic mode? */
if (!loopback) { /* terminal mode? */
if ((uptr->flags & UNIT_ATT) == 0) return SCPE_OK; /* attached? */
t = sim_rtcn_calb (mux_tps, TMR_MUX); /* calibrate */
sim_activate (uptr, t); /* continue poll */
ln = tmxr_poll_conn (&mux_desc); /* look for connect */
if (ln >= 0) { /* got one? */
if ((muxl_unit[ln].flags & UNIT_MDM) && /* modem ctrl? */
(muxc_ota[ln] & DTR)) /* DTR? */
muxc_lia[ln] = muxc_lia[ln] | CDET; /* set cdet */
muxc_lia[ln] = muxc_lia[ln] | DSR; /* set dsr */
mux_ldsc[ln].rcve = 1; /* rcv enabled */
}
tmxr_poll_rx (&mux_desc); /* poll for input */
}
if ((uptr->flags & UNIT_ATT) == 0) return SCPE_OK; /* attached? */
t = sim_rtcn_calb (mux_tps, TMR_MUX); /* calibrate */
sim_activate (uptr, t); /* continue poll */
ln = tmxr_poll_conn (&mux_desc); /* look for connect */
if (ln >= 0) { /* got one? */
if ((muxl_unit[ln].flags & UNIT_MDM) && /* modem ctrl? */
(muxc_ota[ln] & DTR)) /* DTR? */
muxc_lia[ln] = muxc_lia[ln] | CDET; /* set cdet */
muxc_lia[ln] = muxc_lia[ln] | DSR; /* set dsr */
mux_ldsc[ln].rcve = 1; /* rcv enabled */
}
tmxr_poll_rx (&mux_desc); /* poll for input */
for (ln = 0; ln < MUX_LINES; ln++) { /* loop thru lines */ for (ln = 0; ln < MUX_LINES; ln++) { /* loop thru lines */
if (mux_ldsc[ln].conn) { /* connected? */ if (mux_ldsc[ln].conn) { /* connected? */
if (c = tmxr_getc_ln (&mux_ldsc[ln])) { /* get char */ if (loopback) { /* diagnostic mode? */
c = mux_xbuf[ln ^ 1] & OTL_CHAR; /* get char from xmit line */
if (c == 0) /* all char bits = 0? */
c = c | SCPE_BREAK; /* set break flag */
mux_ldsc[ln].conn = 0; /* clear connection */
}
else
c = tmxr_getc_ln (&mux_ldsc[ln]); /* get char from Telnet */
if (c) { /* valid char? */
if (c & SCPE_BREAK) { /* break? */ if (c & SCPE_BREAK) { /* break? */
mux_sta[ln] = mux_sta[ln] | LIU_BRK; mux_sta[ln] = mux_sta[ln] | LIU_BRK;
mux_rbuf[ln] = 0; /* no char */ mux_rbuf[ln] = 0; /* no char */
} }
else { /* normal */ else { /* normal */
if (mux_rchp[ln]) mux_sta[ln] = mux_sta[ln] | LIU_LOST; if (mux_rchp[ln]) /* char already pending? */
c = sim_tt_inpcvt (c, TT_GET_MODE (muxl_unit[ln].flags)); mux_sta[ln] = mux_sta[ln] | LIU_LOST;
if (mux_rpar[ln] & OTL_ECHO) { /* echo? */
TMLN *lp = &mux_ldsc[ln]; /* get line */ if (!loopback) { /* terminal mode? */
tmxr_putc_ln (lp, c); /* output char */ c = sim_tt_inpcvt (c, TT_GET_MODE (muxl_unit[ln].flags));
tmxr_poll_tx (&mux_desc); /* poll xmt */ if (mux_rpar[ln] & OTL_ECHO) { /* echo? */
TMLN *lp = &mux_ldsc[ln]; /* get line */
tmxr_putc_ln (lp, c); /* output char */
tmxr_poll_tx (&mux_desc); /* poll xmt */
}
} }
mux_rbuf[ln] = c; /* save char */ mux_rbuf[ln] = c; /* save char */
mux_rchp[ln] = 1; /* char pending */
} }
mux_rchp[ln] = 1; /* char pending */
if (DEBUG_PRI (muxu_dev, DEB_XFER))
fprintf (sim_deb, ">>MUXi svc: Line %d character %06o received\n",
ln, c);
if (mux_rpar[ln] & OTL_DIAG) mux_diag (c); /* rcv diag? */ if (mux_rpar[ln] & OTL_DIAG) mux_diag (c); /* rcv diag? */
} /* end if char */ } /* end if char */
} /* end if connected */ } /* end if connected */
else muxc_lia[ln] = 0; /* disconnected */
else /* not connected */
if (!loopback) /* terminal mode? */
muxc_lia[ln] = 0; /* line disconnected */
} /* end for */ } /* end for */
if (!FLG (muxl_dib.devno)) mux_data_int (); /* scan for data int */ if (!FLG (muxl_dib.devno)) mux_data_int (); /* scan for data int */
if (!FLG (muxc_dib.devno)) mux_ctrl_int (); /* scan modem */ if (!FLG (muxc_dib.devno)) mux_ctrl_int (); /* scan modem */
@ -577,33 +771,55 @@ return SCPE_OK;
t_stat muxo_svc (UNIT *uptr) t_stat muxo_svc (UNIT *uptr)
{ {
int32 c, ln = uptr - muxl_unit; /* line # */ int32 c, fc, ln, altln;
t_bool loopback;
ln = uptr - muxl_unit; /* line # */
altln = ln ^ 1; /* alt. line for diag mode */
fc = mux_xbuf[ln] & OTL_CHAR; /* full character data */
c = fc & 0377; /* Telnet character data */
loopback = ((muxu_unit.flags & UNIT_DIAG) != 0); /* diagnostic mode? */
if (mux_ldsc[ln].conn) { /* connected? */ if (mux_ldsc[ln].conn) { /* connected? */
if (mux_ldsc[ln].xmte) { /* xmt enabled? */ if (mux_ldsc[ln].xmte) { /* xmt enabled? */
if (loopback) /* diagnostic mode? */
mux_ldsc[ln].conn = 0; /* clear connection */
if ((mux_xbuf[ln] & OTL_SYNC) == 0) { /* start bit 0? */ if ((mux_xbuf[ln] & OTL_SYNC) == 0) { /* start bit 0? */
TMLN *lp = &mux_ldsc[ln]; /* get line */ TMLN *lp = &mux_ldsc[ln]; /* get line */
c = mux_xbuf[ln]; /* get char */
c = sim_tt_outcvt (c, TT_GET_MODE (muxl_unit[ln].flags)); c = sim_tt_outcvt (c, TT_GET_MODE (muxl_unit[ln].flags));
if (mux_xpar[ln] & OTL_DIAG) /* xmt diag? */
mux_diag (mux_xbuf[ln]); /* before munge */
mux_xdon[ln] = 1; /* set done */
/* In (default) UC or (new) 7P, all these chars are suppressed automatically */ if (mux_xpar[ln] & OTL_DIAG) /* xmt diagnose? */
/* if ((TT_GET_MODE (muxl_unit[ln].flags) != TT_MODE_8B) && mux_diag (fc); /* before munge */
/* (c != 0x7f) && (c != 0x13) && /* not del, ^S? */
/* (c != 0x11) && (c != 0x5)) /* not ^Q, ^E? */ if (loopback) { /* diagnostic mode? */
if (c >= 0) /* valid? */ mux_ldsc[altln].conn = 1; /* set recv connection */
tmxr_putc_ln (lp, c); /* output char */ sim_activate (&muxu_unit, 1); /* schedule receive */
tmxr_poll_tx (&mux_desc); /* poll xmt */ }
else { /* no loopback */
if (c >= 0) /* valid? */
tmxr_putc_ln (lp, c); /* output char */
tmxr_poll_tx (&mux_desc); /* poll xmt */
}
} }
mux_xdon[ln] = 1; /* set for xmit irq */
if (DEBUG_PRI (muxu_dev, DEB_XFER) && (loopback | (c >= 0)))
fprintf (sim_deb, ">>MUXo svc: Line %d character %06o sent\n",
ln, (loopback ? fc : c));
} }
else { /* buf full */ else { /* buf full */
tmxr_poll_tx (&mux_desc); /* poll xmt */ tmxr_poll_tx (&mux_desc); /* poll xmt */
sim_activate (uptr, muxl_unit[ln].wait); /* wait */ sim_activate (uptr, muxl_unit[ln].wait); /* wait */
return SCPE_OK; return SCPE_OK;
} }
} }
if (!FLG (muxl_dib.devno)) mux_data_int (); /* scan for int */ if (!FLG (muxl_dib.devno)) mux_data_int (); /* scan for int */
return SCPE_OK; return SCPE_OK;
} }
@ -616,31 +832,48 @@ int32 i;
for (i = 0; i < MUX_LINES; i++) { /* rcv lines */ for (i = 0; i < MUX_LINES; i++) { /* rcv lines */
if ((mux_rpar[i] & OTL_ENB) && mux_rchp[i]) { /* enabled, char? */ if ((mux_rpar[i] & OTL_ENB) && mux_rchp[i]) { /* enabled, char? */
muxl_ibuf = PUT_CCH (i) | mux_rbuf[i] | /* lo buf = char */ muxl_ibuf = PUT_DCH (i) | /* lo buf = char */
mux_rbuf[i] & LIL_CHAR |
RCV_PAR (mux_rbuf[i]); RCV_PAR (mux_rbuf[i]);
muxu_ibuf = PUT_CCH (i) | mux_sta[i]; /* hi buf = stat */ muxu_ibuf = PUT_DCH (i) | mux_sta[i]; /* hi buf = stat */
mux_rchp[i] = 0; /* clr char, stat */ mux_rchp[i] = 0; /* clr char, stat */
mux_sta[i] = 0; mux_sta[i] = 0;
if (DEBUG_PRI (muxu_dev, DEB_CMDS))
fprintf (sim_deb, ">>MUXd irq: Receive channel %d interrupt requested\n", i);
setFSR (muxl_dib.devno); /* interrupt */ setFSR (muxl_dib.devno); /* interrupt */
return; return;
} }
} }
for (i = 0; i < MUX_LINES; i++) { /* xmt lines */ for (i = 0; i < MUX_LINES; i++) { /* xmt lines */
if ((mux_xpar[i] & OTL_ENB) && mux_xdon[i]) { /* enabled, done? */ if ((mux_xpar[i] & OTL_ENB) && mux_xdon[i]) { /* enabled, done? */
muxu_ibuf = PUT_CCH (i) | mux_sta[i] | LIU_TR; /* hi buf = stat */ muxl_ibuf = PUT_DCH (i) | /* lo buf = last rcv char */
mux_rbuf[i] & LIL_CHAR |
RCV_PAR (mux_rbuf[i]);
muxu_ibuf = PUT_DCH (i) | mux_sta[i] | LIU_TR; /* hi buf = stat */
mux_xdon[i] = 0; /* clr done, stat */ mux_xdon[i] = 0; /* clr done, stat */
mux_sta[i] = 0; mux_sta[i] = 0;
if (DEBUG_PRI (muxu_dev, DEB_CMDS))
fprintf (sim_deb, ">>MUXd irq: Transmit channel %d interrupt requested\n", i);
setFSR (muxl_dib.devno); /* interrupt */ setFSR (muxl_dib.devno); /* interrupt */
return; return;
} }
} }
for (i = MUX_LINES; i < (MUX_LINES + MUX_ILINES); i++) { /* diag lines */ for (i = MUX_LINES; i < (MUX_LINES + MUX_ILINES); i++) { /* diag lines */
if ((mux_rpar[i] & OTL_ENB) && mux_rchp[i]) { /* enabled, char? */ if ((mux_rpar[i] & OTL_ENB) && mux_rchp[i]) { /* enabled, char? */
muxl_ibuf = PUT_CCH (i) | mux_rbuf[i] | /* lo buf = char */ muxl_ibuf = PUT_DCH (i) | /* lo buf = char */
mux_rbuf[i] & LIL_CHAR |
RCV_PAR (mux_rbuf[i]); RCV_PAR (mux_rbuf[i]);
muxu_ibuf = PUT_CCH (i) | mux_sta[i] | LIU_DG; /* hi buf = stat */ muxu_ibuf = PUT_DCH (i) | mux_sta[i] | LIU_DG; /* hi buf = stat */
mux_rchp[i] = 0; /* clr char, stat */ mux_rchp[i] = 0; /* clr char, stat */
mux_sta[i] = 0; mux_sta[i] = 0;
if (DEBUG_PRI (muxu_dev, DEB_CMDS))
fprintf (sim_deb, ">>MUXd irq: Receive channel %d interrupt requested\n", i);
setFSR (muxl_dib.devno); setFSR (muxl_dib.devno);
return; return;
} }
@ -648,16 +881,31 @@ for (i = MUX_LINES; i < (MUX_LINES + MUX_ILINES); i++) { /* diag lines */
return; return;
} }
/* Look for control interrupt */ /* Look for control interrupt
If either of the incoming status bits does not match the stored status, and
the corresponding mismatch is enabled, a control interrupt request is
generated. Depending on the scan flag, we check either all 16 lines or just
the current line. If an interrupt is requested, the channel counter
indicates the interrupting channel.
*/
void mux_ctrl_int (void) void mux_ctrl_int (void)
{ {
int32 i; int32 i, line_count;
if (muxc_scan == 0) return; line_count = (muxc_scan ? MUX_LINES : 1); /* check one or all lines */
for (i = 0; i < MUX_LINES; i++) {
muxc_chan = (muxc_chan + 1) & LIC_M_CHAN; /* step channel */ for (i = 0; i < line_count; i++) {
if (muxc_scan) /* scanning? */
muxc_chan = (muxc_chan + 1) & LIC_M_CHAN; /* step channel */
if (LIC_TSTI (muxc_chan)) { /* status change? */ if (LIC_TSTI (muxc_chan)) { /* status change? */
if (DEBUG_PRI (muxu_dev, DEB_CMDS))
fprintf (sim_deb,
">>MUXc irq: Control channel %d interrupt requested (poll = %d)\n",
muxc_chan, i + 1);
setFSR (muxc_dib.devno); /* set flag */ setFSR (muxc_dib.devno); /* set flag */
break; break;
} }
@ -694,7 +942,8 @@ mux_rpar[i] = mux_xpar[i] = 0;
mux_rchp[i] = mux_xdon[i] = 0; mux_rchp[i] = mux_xdon[i] = 0;
mux_sta[i] = 0; mux_sta[i] = 0;
muxc_ota[i] = muxc_lia[i] = 0; /* clear modem */ muxc_ota[i] = muxc_lia[i] = 0; /* clear modem */
if (mux_ldsc[i].conn) /* connected? */ if (mux_ldsc[i].conn && /* connected? */
((muxu_unit.flags & UNIT_DIAG) == 0)) /* term mode? */
muxc_lia[i] = muxc_lia[i] | DSR | /* cdet, dsr */ muxc_lia[i] = muxc_lia[i] | DSR | /* cdet, dsr */
(muxl_unit[i].flags & UNIT_MDM? CDET: 0); (muxl_unit[i].flags & UNIT_MDM? CDET: 0);
sim_cancel (&muxl_unit[i]); sim_cancel (&muxl_unit[i]);
@ -733,7 +982,9 @@ if (muxu_unit.flags & UNIT_ATT) { /* master att? */
} }
} }
else sim_cancel (&muxu_unit); /* else stop */ else sim_cancel (&muxu_unit); /* else stop */
for (i = 0; i < MUX_LINES; i++) mux_reset_ln (i); for (i = 0; i < MUX_LINES; i++) mux_reset_ln (i); /* reset lines 0-15 */
for (i = MUX_LINES; i < (MUX_LINES + MUX_ILINES); i++) /* reset lines 16-20 */
mux_rbuf[i] = mux_rpar[i] = mux_sta[i] = mux_rchp[i] = 0;
return SCPE_OK; return SCPE_OK;
} }
@ -744,6 +995,9 @@ t_stat mux_attach (UNIT *uptr, char *cptr)
t_stat r; t_stat r;
int32 t; int32 t;
if (muxu_unit.flags & UNIT_DIAG) /* diag mode? */
return SCPE_NOFNC; /* command not allowed */
r = tmxr_attach (&mux_desc, uptr, cptr); /* attach */ r = tmxr_attach (&mux_desc, uptr, cptr); /* attach */
if (r != SCPE_OK) return r; /* error */ if (r != SCPE_OK) return r; /* error */
t = sim_rtcn_init (muxu_unit.wait, TMR_MUX); t = sim_rtcn_init (muxu_unit.wait, TMR_MUX);
@ -764,12 +1018,50 @@ sim_cancel (uptr); /* stop poll */
return r; return r;
} }
/* Diagnostic/normal mode routine
Diagnostic testing wants to exercise as much of the regular simulation code
as possible to ensure good test coverage. Normally, input polling and output
transmission only occurs on connected lines. In diagnostic mode, line
connection flags are set selectively to enable processing on the lines under
test. The alternative to this would require duplicating the send/receive
code; the diagnostic would then test the copy but not the actual code used
for normal character transfers, which is undesirable.
Therefore, to enable diagnostic mode, we must force a disconnect of the
master socket and any connected Telnet lines, which clears the connection
flags on all lines. Then we set the "transmission enabled" flags on all
lines to enable output character processing for the diagnostic. (Normally,
all of the flags are set when the multiplexer is first attached. Until then,
the enable flags default to "not enabled," so we enable them explicitly
here.)
*/
t_stat mux_setdiag (UNIT *uptr, int32 val, char *cptr, void *desc)
{
int32 ln;
if (val) { /* set diag? */
mux_detach (uptr); /* detach lines */
for (ln = 0; ln < MUX_LINES; ln++) /* enable transmission */
mux_ldsc[ln].xmte = 1; /* on all lines */
}
else { /* set term */
for (ln = 0; ln < MUX_LINES; ln++) /* clear connections */
mux_ldsc[ln].conn = 0; /* on all lines */
}
return SCPE_OK;
}
/* Show summary processor */ /* Show summary processor */
t_stat mux_summ (FILE *st, UNIT *uptr, int32 val, void *desc) t_stat mux_summ (FILE *st, UNIT *uptr, int32 val, void *desc)
{ {
int32 i, t; int32 i, t;
if (muxu_unit.flags & UNIT_DIAG) /* diag mode? */
return SCPE_NOFNC; /* command not allowed */
for (i = t = 0; i < MUX_LINES; i++) t = t + (mux_ldsc[i].conn != 0); for (i = t = 0; i < MUX_LINES; i++) t = t + (mux_ldsc[i].conn != 0);
if (t == 1) fprintf (st, "1 connection"); if (t == 1) fprintf (st, "1 connection");
else fprintf (st, "%d connections", t); else fprintf (st, "%d connections", t);
@ -782,6 +1074,9 @@ t_stat mux_show (FILE *st, UNIT *uptr, int32 val, void *desc)
{ {
int32 i, t; int32 i, t;
if (muxu_unit.flags & UNIT_DIAG) /* diag mode? */
return SCPE_NOFNC; /* command not allowed */
for (i = t = 0; i < MUX_LINES; i++) t = t + (mux_ldsc[i].conn != 0); for (i = t = 0; i < MUX_LINES; i++) t = t + (mux_ldsc[i].conn != 0);
if (t) { if (t) {
for (i = 0; i < MUX_LINES; i++) { for (i = 0; i < MUX_LINES; i++) {
@ -794,4 +1089,3 @@ if (t) {
else fprintf (st, "all disconnected\n"); else fprintf (st, "all disconnected\n");
return SCPE_OK; return SCPE_OK;
} }

View file

@ -1,6 +1,6 @@
/* i1401_cd.c: IBM 1402 card reader/punch /* i1401_cd.c: IBM 1402 card reader/punch
Copyright (c) 1993-2005, Robert M. Supnik Copyright (c) 1993-2007, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -35,6 +35,7 @@
Cards are represented as ASCII text streams terminated by newlines. Cards are represented as ASCII text streams terminated by newlines.
This allows cards to be created and edited as normal files. This allows cards to be created and edited as normal files.
19-Jan-07 RMS Added UNIT_TEXT flag
20-Sep-05 RMS Revised for new code tables, compatible colbinary treatment 20-Sep-05 RMS Revised for new code tables, compatible colbinary treatment
30-Aug-05 RMS Fixed read, punch to ignore modifier on 1,4 char inst 30-Aug-05 RMS Fixed read, punch to ignore modifier on 1,4 char inst
(reported by Van Snyder) (reported by Van Snyder)
@ -73,7 +74,7 @@ char colbin_to_bcd (uint32 cb);
*/ */
UNIT cdr_unit = { UNIT cdr_unit = {
UDATA (&cdr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0), 100 UDATA (&cdr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE+UNIT_TEXT, 0), 100
}; };
REG cdr_reg[] = { REG cdr_reg[] = {
@ -102,7 +103,7 @@ DEVICE cdr_dev = {
*/ */
UNIT cdp_unit = { UNIT cdp_unit = {
UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0)
}; };
REG cdp_reg[] = { REG cdp_reg[] = {
@ -134,11 +135,11 @@ DEVICE cdp_dev = {
*/ */
UNIT stack_unit[] = { UNIT stack_unit[] = {
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) }, { UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0) },
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) }, { UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0) },
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) }, { UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0) },
{ UDATA (NULL, UNIT_DIS, 0) }, /* unused */ { UDATA (NULL, UNIT_DIS, 0) }, /* unused */
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) } { UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0) }
}; };
REG stack_reg[] = { REG stack_reg[] = {
@ -179,10 +180,10 @@ fgets (rbuf, (cbn)? 2 * CBUFSIZE: CBUFSIZE, /* rd bin/char card */
cdr_unit.fileref); cdr_unit.fileref);
if (feof (cdr_unit.fileref)) return STOP_NOCD; /* eof? */ if (feof (cdr_unit.fileref)) return STOP_NOCD; /* eof? */
if (ferror (cdr_unit.fileref)) { /* error? */ if (ferror (cdr_unit.fileref)) { /* error? */
ind[IN_READ] = 1;
perror ("Card reader I/O error"); perror ("Card reader I/O error");
clearerr (cdr_unit.fileref); clearerr (cdr_unit.fileref);
if (iochk) return SCPE_IOERR; if (iochk) return SCPE_IOERR;
ind[IN_READ] = 1;
return SCPE_OK; return SCPE_OK;
} }
cdr_unit.pos = ftell (cdr_unit.fileref); /* update position */ cdr_unit.pos = ftell (cdr_unit.fileref); /* update position */
@ -236,12 +237,12 @@ for (i = CDR_WIDTH - 1; (i >= 0) && (rbuf[i] == ' '); i--) rbuf[i] = 0;
rbuf[CDR_WIDTH] = 0; /* null at end */ rbuf[CDR_WIDTH] = 0; /* null at end */
fputs (rbuf, uptr->fileref); /* write card */ fputs (rbuf, uptr->fileref); /* write card */
fputc ('\n', uptr->fileref); /* plus new line */ fputc ('\n', uptr->fileref); /* plus new line */
uptr->pos = ftell (uptr->fileref); /* update position */
if (ferror (uptr->fileref)) { /* error? */ if (ferror (uptr->fileref)) { /* error? */
perror ("Card stacker I/O error"); perror ("Card stacker I/O error");
clearerr (uptr->fileref); clearerr (uptr->fileref);
if (iochk) return SCPE_IOERR; if (iochk) return SCPE_IOERR;
} }
uptr->pos = ftell (uptr->fileref); /* update position */
return SCPE_OK; return SCPE_OK;
} }
@ -293,13 +294,13 @@ else { /* normal */
} }
fputs (pbuf, uptr->fileref); /* output card */ fputs (pbuf, uptr->fileref); /* output card */
fputc ('\n', uptr->fileref); /* plus new line */ fputc ('\n', uptr->fileref); /* plus new line */
uptr->pos = ftell (uptr->fileref); /* update position */
if (ferror (uptr->fileref)) { /* error? */ if (ferror (uptr->fileref)) { /* error? */
perror ("Card punch I/O error"); perror ("Card punch I/O error");
clearerr (uptr->fileref); clearerr (uptr->fileref);
if (iochk) return SCPE_IOERR; if (iochk) return SCPE_IOERR;
ind[IN_PNCH] = 1; ind[IN_PNCH] = 1;
} }
uptr->pos = ftell (uptr->fileref); /* update position */
return SCPE_OK; return SCPE_OK;
} }

View file

@ -1,6 +1,6 @@
/* i1401_lp.c: IBM 1403 line printer simulator /* i1401_lp.c: IBM 1403 line printer simulator
Copyright (c) 1993-2005, Robert M. Supnik Copyright (c) 1993-2007, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
lpt 1403 line printer lpt 1403 line printer
19-Jan-07 RMS Added UNIT_TEXT flag
07-Mar-05 RMS Fixed bug in write_line (reported by Van Snyder) 07-Mar-05 RMS Fixed bug in write_line (reported by Van Snyder)
25-Apr-03 RMS Revised for extended file support 25-Apr-03 RMS Revised for extended file support
30-May-02 RMS Widened POS to 32b 30-May-02 RMS Widened POS to 32b
@ -69,7 +70,7 @@ char *pch_table[4] = {
*/ */
UNIT lpt_unit = { UNIT lpt_unit = {
UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0)
}; };
REG lpt_reg[] = { REG lpt_reg[] = {
@ -136,10 +137,10 @@ else {
} }
lines = lflag = 0; /* clear cc action */ lines = lflag = 0; /* clear cc action */
if (ferror (lpt_unit.fileref)) { /* error? */ if (ferror (lpt_unit.fileref)) { /* error? */
ind[IN_LPT] = 1;
perror ("Line printer I/O error"); perror ("Line printer I/O error");
clearerr (lpt_unit.fileref); clearerr (lpt_unit.fileref);
if (iochk) return SCPE_IOERR; if (iochk) return SCPE_IOERR;
ind[IN_LPT] = 1;
} }
return SCPE_OK; return SCPE_OK;
} }

View file

@ -1,6 +1,6 @@
/* i1620_cd.c: IBM 1622 card reader/punch /* i1620_cd.c: IBM 1622 card reader/punch
Copyright (c) 2002-2006, Robert M. Supnik Copyright (c) 2002-2007, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -26,6 +26,7 @@
cdr 1622 card reader cdr 1622 card reader
cdp 1622 card punch cdp 1622 card punch
19-Jan-07 RMS Set UNIT_TEXT flag
13-Jul-06 RMS Fixed card reader fgets call (from Tom McBride) 13-Jul-06 RMS Fixed card reader fgets call (from Tom McBride)
Fixed card reader boot sequence (from Tom McBride) Fixed card reader boot sequence (from Tom McBride)
21-Sep-05 RMS Revised translation tables for 7094/1401 compatibility 21-Sep-05 RMS Revised translation tables for 7094/1401 compatibility
@ -63,7 +64,7 @@ t_stat cdp_num (uint32 pa, uint32 ndig, t_bool dump);
*/ */
UNIT cdr_unit = { UNIT cdr_unit = {
UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0) UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE+UNIT_TEXT, 0)
}; };
REG cdr_reg[] = { REG cdr_reg[] = {
@ -87,7 +88,7 @@ DEVICE cdr_dev = {
*/ */
UNIT cdp_unit = { UNIT cdp_unit = {
UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0)
}; };
REG cdp_reg[] = { REG cdp_reg[] = {
@ -421,13 +422,14 @@ while ((len > 0) && (cdp_buf[len - 1] == ' ')) --len; /* trim spaces */
cdp_buf[len] = '\n'; /* newline, null */ cdp_buf[len] = '\n'; /* newline, null */
cdp_buf[len + 1] = 0; cdp_buf[len + 1] = 0;
if (fputs (cdp_buf, cdp_unit.fileref) == EOF) { /* write card */ fputs (cdp_buf, cdp_unit.fileref); /* write card */
ind[IN_WRCHK] = 1; /* error? */ cdp_unit.pos = ftell (cdp_unit.fileref); /* count char */
if (ferror (cdp_unit.fileref)) { /* error? */
ind[IN_WRCHK] = 1;
perror ("CDP I/O error"); perror ("CDP I/O error");
clearerr (cdp_unit.fileref); clearerr (cdp_unit.fileref);
return SCPE_IOERR; return SCPE_IOERR;
} }
cdp_unit.pos = ftell (cdp_unit.fileref); /* count char */
return SCPE_OK; return SCPE_OK;
} }

View file

@ -1,6 +1,6 @@
/* i1620_lp.c: IBM 1443 line printer simulator /* i1620_lp.c: IBM 1443 line printer simulator
Copyright (c) 2002-2005, Robert M. Supnik Copyright (c) 2002-2007, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
lpt 1443 line printer lpt 1443 line printer
19-Jan-07 RMS Added UNIT_TEXT flag
21-Sep-05 RMS Revised translation tables for 7094/1401 compatibility 21-Sep-05 RMS Revised translation tables for 7094/1401 compatibility
29-Dec-03 RMS Fixed bug in scheduling 29-Dec-03 RMS Fixed bug in scheduling
25-Apr-03 RMS Revised for extended file support 25-Apr-03 RMS Revised for extended file support
@ -69,7 +70,7 @@ t_stat lpt_space (int32 lines, int32 lflag);
*/ */
UNIT lpt_unit = { UNIT lpt_unit = {
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE, 50) UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 50)
}; };
REG lpt_reg[] = { REG lpt_reg[] = {

View file

@ -1,6 +1,6 @@
/* i7094_cd.c: IBM 711/721 card reader/punch /* i7094_cd.c: IBM 711/721 card reader/punch
Copyright (c) 2003-2006, Robert M. Supnik Copyright (c) 2003-2007, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -26,6 +26,7 @@
cdr 711 card reader cdr 711 card reader
cdp 721 card punch cdp 721 card punch
19-Jan-07 RMS Added UNIT_TEXT
13-Jul-06 RMS Fixed problem with 80 column full cards 13-Jul-06 RMS Fixed problem with 80 column full cards
Cards are represented as ASCII text streams terminated by newlines. Cards are represented as ASCII text streams terminated by newlines.
@ -106,7 +107,7 @@ extern uint32 col_masks[12];
DIB cdr_dib = { &cdr_chsel, NULL }; DIB cdr_dib = { &cdr_chsel, NULL };
UNIT cdr_unit = { UNIT cdr_unit = {
UDATA (&cdr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0) UDATA (&cdr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE+UNIT_TEXT, 0)
}; };
REG cdr_reg[] = { REG cdr_reg[] = {
@ -144,7 +145,7 @@ DEVICE cdr_dev = {
DIB cdp_dib = { &cdp_chsel, &cdp_chwr }; DIB cdp_dib = { &cdp_chsel, &cdp_chwr };
UNIT cdp_unit = { UNIT cdp_unit = {
UDATA (&cdp_svc, UNIT_SEQ+UNIT_ATTABLE, 0) UDATA (&cdp_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0)
}; };
REG cdp_reg[] = { REG cdp_reg[] = {
@ -443,12 +444,12 @@ for (i = ((2 * CD_CHRLNT) + 1); (i > 0) &&
cdp_cbuf[i++] = '\n'; /* append nl */ cdp_cbuf[i++] = '\n'; /* append nl */
cdp_cbuf[i++] = 0; /* append nul */ cdp_cbuf[i++] = 0; /* append nul */
fputs (cdp_cbuf, uptr->fileref); /* write card */ fputs (cdp_cbuf, uptr->fileref); /* write card */
uptr->pos = ftell (uptr->fileref); /* update position */
if (ferror (uptr->fileref)) { /* error? */ if (ferror (uptr->fileref)) { /* error? */
perror ("CDP I/O error"); perror ("CDP I/O error");
clearerr (uptr->fileref); clearerr (uptr->fileref);
return SCPE_IOERR; return SCPE_IOERR;
} }
uptr->pos = ftell (uptr->fileref); /* update position */
cdp_sta = CDS_END; /* end state */ cdp_sta = CDS_END; /* end state */
sim_cancel (uptr); /* cancel current */ sim_cancel (uptr); /* cancel current */
sim_activate (uptr, cdp_tstop); /* long timer */ sim_activate (uptr, cdp_tstop); /* long timer */

View file

@ -1,6 +1,6 @@
/* i7094_cpu.c: IBM 7094 CPU simulator /* i7094_cpu.c: IBM 7094 CPU simulator
Copyright (c) 2003-2006, Robert M. Supnik Copyright (c) 2003-2007, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
cpu 7094 central processor cpu 7094 central processor
28-Apr-07 RMS Removed clock initialization
29-Oct-06 RMS Added additional expanded core instructions 29-Oct-06 RMS Added additional expanded core instructions
17-Oct-06 RMS Fixed the fix in halt IO wait loop 17-Oct-06 RMS Fixed the fix in halt IO wait loop
16-Jun-06 RMS Fixed bug in halt IO wait loop 16-Jun-06 RMS Fixed bug in halt IO wait loop
@ -198,7 +199,6 @@ extern uint32 ch_sta[NUM_CHAN];
extern uint32 ch_flags[NUM_CHAN]; extern uint32 ch_flags[NUM_CHAN];
extern DEVICE mt_dev[NUM_CHAN]; extern DEVICE mt_dev[NUM_CHAN];
extern DEVICE ch_dev[NUM_CHAN]; extern DEVICE ch_dev[NUM_CHAN];
extern UNIT clk_unit;
extern FILE *sim_deb; extern FILE *sim_deb;
extern int32 sim_int_char; extern int32 sim_int_char;
extern int32 sim_interval; extern int32 sim_interval;
@ -625,7 +625,6 @@ ind_reloc = ind_reloc & VA_BLK; /* canonical form */
ind_start = ind_start & VA_BLK; ind_start = ind_start & VA_BLK;
ind_limit = (ind_limit & VA_BLK) | VA_OFF; ind_limit = (ind_limit & VA_BLK) | VA_OFF;
chtr_pend = chtr_eval (NULL); /* eval chan traps */ chtr_pend = chtr_eval (NULL); /* eval chan traps */
sim_rtcn_init (clk_unit.wait, TMR_CLK); /* init clock */
tracing = ((hst_lnt != 0) || DEBUG_PRS (cpu_dev)); tracing = ((hst_lnt != 0) || DEBUG_PRS (cpu_dev));
if (ht_pend) { /* HTR pending? */ if (ht_pend) { /* HTR pending? */

View file

@ -1,6 +1,6 @@
/* i7094_lp.c: IBM 716 line printer simulator /* i7094_lp.c: IBM 716 line printer simulator
Copyright (c) 2003-2006, Robert M. Supnik Copyright (c) 2003-2007, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,8 @@
lpt 716 line printer lpt 716 line printer
19-Jan-07 RMS Added UNIT_TEXT flag
Internally, the 7094 works only with column binary and is limited to Internally, the 7094 works only with column binary and is limited to
72 columns of data. Each row of the printed line is represented by 72 columns of data. Each row of the printed line is represented by
72b of data (two 36b words). A complete print line consists of 12 rows 72b of data (two 36b words). A complete print line consists of 12 rows
@ -142,7 +144,7 @@ extern char colbin_to_bcd (uint32 colbin);
DIB lpt_dib = { &lpt_chsel, &lpt_chwr }; DIB lpt_dib = { &lpt_chsel, &lpt_chwr };
UNIT lpt_unit = { UNIT lpt_unit = {
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_CONS, 0) UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_CONS+UNIT_TEXT, 0)
}; };
REG lpt_reg[] = { REG lpt_reg[] = {
@ -306,7 +308,7 @@ return SCPE_OK;
t_stat lpt_end_line (UNIT *uptr) t_stat lpt_end_line (UNIT *uptr)
{ {
uint32 i, j, col, row, bufw, colbin; uint32 i, col, row, bufw, colbin;
char *pch, bcd, lpt_cbuf[LPT_CHRLNT + 1]; char *pch, bcd, lpt_cbuf[LPT_CHRLNT + 1];
t_uint64 dat; t_uint64 dat;
@ -325,22 +327,23 @@ for (col = 0; col < 72; col++) { /* proc 72 columns */
} }
for (i = LPT_CHRLNT; (i > 0) && for (i = LPT_CHRLNT; (i > 0) &&
(lpt_cbuf[i - 1] == ' '); --i) ; /* trim spaces */ (lpt_cbuf[i - 1] == ' '); --i) ; /* trim spaces */
lpt_cbuf[i++] = '\n'; /* append nl */ lpt_cbuf[i] = 0; /* append nul */
if (uptr->flags & UNIT_ATT) { /* file? */ if (uptr->flags & UNIT_ATT) { /* file? */
fxwrite (lpt_cbuf, 1, i, uptr->fileref); /* write line */ fputs (lpt_cbuf, uptr->fileref); /* write line */
fputc ('\n', uptr->fileref); /* append nl */
uptr->pos = ftell (uptr->fileref); /* update position */
if (ferror (uptr->fileref)) { /* error? */ if (ferror (uptr->fileref)) { /* error? */
perror ("LPT I/O error"); perror ("LPT I/O error");
clearerr (uptr->fileref); clearerr (uptr->fileref);
return SCPE_IOERR; return SCPE_IOERR;
} }
uptr->pos = ftell (uptr->fileref); /* update position */
} }
else if (uptr->flags & UNIT_CONS) { /* print to console? */ else if (uptr->flags & UNIT_CONS) { /* print to console? */
for (j = 0; j < i; j++) sim_putchar (lpt_cbuf[j]); for (i = 0; lpt_cbuf[i] != 0; i++) sim_putchar (lpt_cbuf[i]);
sim_putchar ('\r'); sim_putchar ('\r');
sim_putchar ('\n');
} }
else return SCPE_UNATT; /* otherwise error */ else return SCPE_UNATT; /* otherwise error */
uptr->pos = uptr->pos + strlen (lpt_cbuf); /* count char */
lpt_sta = LPS_END; /* end line state */ lpt_sta = LPS_END; /* end line state */
sim_cancel (uptr); /* cancel current */ sim_cancel (uptr); /* cancel current */
sim_activate (uptr, lpt_tstop); /* long timer */ sim_activate (uptr, lpt_tstop); /* long timer */

View file

@ -1,6 +1,6 @@
/* id16_cpu.c: Interdata 16b CPU simulator /* id16_cpu.c: Interdata 16b CPU simulator
Copyright (c) 2000-2006, Robert M. Supnik Copyright (c) 2000-2007, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
cpu Interdata 16b CPU cpu Interdata 16b CPU
28-Apr-07 RMS Removed clock initialization
27-Oct-06 RMS Added idle support 27-Oct-06 RMS Added idle support
Removed separate PASLA clock Removed separate PASLA clock
06-Feb-06 RMS Fixed bug in DH (found by Mark Hittinger) 06-Feb-06 RMS Fixed bug in DH (found by Mark Hittinger)
@ -222,7 +223,6 @@ extern int32 sim_interval;
extern int32 sim_int_char; extern int32 sim_int_char;
extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */ extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
extern t_bool sim_idle_enab; extern t_bool sim_idle_enab;
extern UNIT pic_unit, lfc_unit; /* timers */
uint32 ReadB (uint32 loc); uint32 ReadB (uint32 loc);
uint32 ReadH (uint32 loc); uint32 ReadH (uint32 loc);
@ -587,8 +587,6 @@ else {
} }
int_eval (); /* eval interrupts */ int_eval (); /* eval interrupts */
cc = newPSW (PSW & psw_mask); /* split PSW, eval wait */ cc = newPSW (PSW & psw_mask); /* split PSW, eval wait */
sim_rtcn_init (lfc_unit.wait, TMR_LFC); /* init clock */
sim_rtcn_init (pic_unit.wait, TMR_PIC); /* init timer */
reason = 0; reason = 0;
/* Process events */ /* Process events */

View file

@ -1,6 +1,6 @@
/* id32_cpu.c: Interdata 32b CPU simulator /* id32_cpu.c: Interdata 32b CPU simulator
Copyright (c) 2000-2006, Robert M. Supnik Copyright (c) 2000-2007, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
cpu Interdata 32b CPU cpu Interdata 32b CPU
28-Apr-07 RMS Removed clock initialization
27-Oct-06 RMS Added idle support 27-Oct-06 RMS Added idle support
Removed separate PASLA clock Removed separate PASLA clock
09-Mar-06 RMS Added 8 register bank support for 8/32 09-Mar-06 RMS Added 8 register bank support for 8/32
@ -252,7 +253,6 @@ extern int32 sim_interval;
extern int32 sim_int_char; extern int32 sim_int_char;
extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */ extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
extern t_bool sim_idle_enab; extern t_bool sim_idle_enab;
extern UNIT pic_unit, lfc_unit; /* timers */
extern FILE *sim_deb; extern FILE *sim_deb;
uint32 ReadB (uint32 loc, uint32 rel); uint32 ReadB (uint32 loc, uint32 rel);
@ -627,8 +627,6 @@ if (cpu_unit.flags & UNIT_8RS) psw_reg_mask = 7; /* 8 register sets */
else psw_reg_mask = 1; /* 2 register sets */ else psw_reg_mask = 1; /* 2 register sets */
int_eval (); /* eval interrupts */ int_eval (); /* eval interrupts */
cc = newPSW (PSW & PSW_MASK); /* split PSW, eval wait */ cc = newPSW (PSW & PSW_MASK); /* split PSW, eval wait */
sim_rtcn_init (lfc_unit.wait, TMR_LFC); /* init clock */
sim_rtcn_init (pic_unit.wait, TMR_PIC); /* init timer */
reason = 0; reason = 0;
/* Abort handling /* Abort handling

View file

@ -1,6 +1,6 @@
/* id_lp.c: Interdata line printer /* id_lp.c: Interdata line printer
Copyright (c) 2001-2005, Robert M. Supnik Copyright (c) 2001-2007, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
lpt M46-206 line printer lpt M46-206 line printer
19-Jan-07 RMS Added UNIT_TEXT flag
25-Apr-03 RMS Revised for extended file support 25-Apr-03 RMS Revised for extended file support
*/ */
@ -83,7 +84,7 @@ t_stat lpt_spc (UNIT *uptr, int32 cnt);
DIB lpt_dib = { d_LPT, -1, v_LPT, NULL, &lpt, NULL }; DIB lpt_dib = { d_LPT, -1, v_LPT, NULL, &lpt, NULL };
UNIT lpt_unit = { UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_UC, 0) }; UNIT lpt_unit = { UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_UC+UNIT_TEXT, 0) };
REG lpt_reg[] = { REG lpt_reg[] = {
{ HRDATA (STA, lpt_sta, 8) }, { HRDATA (STA, lpt_sta, 8) },

View file

@ -1,6 +1,6 @@
/* nova_cpu.c: NOVA CPU simulator /* nova_cpu.c: NOVA CPU simulator
Copyright (c) 1993-2006, Robert M. Supnik Copyright (c) 1993-2007, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
cpu Nova central processor cpu Nova central processor
28-Apr-07 RMS Removed clock initialization
06-Feb-06 RMS Fixed bug in DIVS (found by Mark Hittinger) 06-Feb-06 RMS Fixed bug in DIVS (found by Mark Hittinger)
22-Sep-05 RMS Fixed declarations (from Sterling Garwood) 22-Sep-05 RMS Fixed declarations (from Sterling Garwood)
25-Aug-05 RMS Fixed DIVS case 2^31 / - 1 25-Aug-05 RMS Fixed DIVS case 2^31 / - 1
@ -332,7 +333,6 @@ extern int32 sim_interval;
int32 PC, IR, i; int32 PC, IR, i;
t_stat reason; t_stat reason;
void mask_out (int32 mask); void mask_out (int32 mask);
extern int32 clk_sel, clk_time[4];
/* Restore register state */ /* Restore register state */
@ -341,7 +341,6 @@ PC = saved_PC & AMASK; /* load local PC */
C = C & CBIT; C = C & CBIT;
mask_out (pimask); /* reset int system */ mask_out (pimask); /* reset int system */
reason = 0; reason = 0;
sim_rtc_init (clk_time[clk_sel]); /* init calibration */
/* Main instruction fetch/decode loop */ /* Main instruction fetch/decode loop */

View file

@ -1,6 +1,6 @@
/* nova_lp.c: NOVA line printer simulator /* nova_lp.c: NOVA line printer simulator
Copyright (c) 1993-2005, Robert M. Supnik Copyright (c) 1993-2007, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
lpt line printer lpt line printer
19-Jan-07 RMS Added UNIT_TEXT
25-Apr-03 RMS Revised for extended file support 25-Apr-03 RMS Revised for extended file support
30-May-02 RMS Widened POS to 32b 30-May-02 RMS Widened POS to 32b
*/ */
@ -49,7 +50,7 @@ t_stat lpt_reset (DEVICE *dptr);
DIB lpt_dib = { DEV_LPT, INT_LPT, PI_LPT, &lpt }; DIB lpt_dib = { DEV_LPT, INT_LPT, PI_LPT, &lpt };
UNIT lpt_unit = { UNIT lpt_unit = {
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0), SERIAL_OUT_WAIT
}; };
REG lpt_reg[] = { REG lpt_reg[] = {
@ -110,12 +111,13 @@ dev_done = dev_done | INT_LPT; /* set done */
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable); int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable);
if ((lpt_unit.flags & UNIT_ATT) == 0) /* attached? */ if ((lpt_unit.flags & UNIT_ATT) == 0) /* attached? */
return IORETURN (lpt_stopioe, SCPE_UNATT); return IORETURN (lpt_stopioe, SCPE_UNATT);
if (putc (lpt_unit.buf, lpt_unit.fileref) == EOF) { fputc (uptr->buf, uptr->fileref);
uptr->pos = ftell (uptr->fileref);
if (ferror (uptr->fileref)) {
perror ("LPT I/O error"); perror ("LPT I/O error");
clearerr (lpt_unit.fileref); clearerr (uptr->fileref);
return SCPE_IOERR; return SCPE_IOERR;
} }
lpt_unit.pos = lpt_unit.pos + 1;
return SCPE_OK; return SCPE_OK;
} }

View file

@ -1,6 +1,6 @@
/* pdp1_lp.c: PDP-1 line printer simulator /* pdp1_lp.c: PDP-1 line printer simulator
Copyright (c) 1993-2006, Robert M. Supnik Copyright (c) 1993-2007, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
lpt Type 62 line printer for the PDP-1 lpt Type 62 line printer for the PDP-1
19-Jan-07 RMS Added UNIT_TEXT flag
21-Dec-06 RMS Added 16-channel SBS support 21-Dec-06 RMS Added 16-channel SBS support
07-Sep-03 RMS Changed ioc to ios 07-Sep-03 RMS Changed ioc to ios
23-Jul-03 RMS Fixed bugs in instruction decoding, overprinting 23-Jul-03 RMS Fixed bugs in instruction decoding, overprinting
@ -67,7 +68,7 @@ t_stat lpt_reset (DEVICE *dptr);
*/ */
UNIT lpt_unit = { UNIT lpt_unit = {
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0), SERIAL_OUT_WAIT
}; };
REG lpt_reg[] = { REG lpt_reg[] = {
@ -166,6 +167,7 @@ if (lpt_spc) { /* space? */
if ((uptr->flags & UNIT_ATT) == 0) /* attached? */ if ((uptr->flags & UNIT_ATT) == 0) /* attached? */
return IORETURN (lpt_stopioe, SCPE_UNATT); return IORETURN (lpt_stopioe, SCPE_UNATT);
fputs (lpt_cc[lpt_spc & 07], uptr->fileref); /* print cctl */ fputs (lpt_cc[lpt_spc & 07], uptr->fileref); /* print cctl */
uptr->pos = ftell (uptr->fileref); /* update position */
if (ferror (uptr->fileref)) { /* error? */ if (ferror (uptr->fileref)) { /* error? */
perror ("LPT I/O error"); perror ("LPT I/O error");
clearerr (uptr->fileref); clearerr (uptr->fileref);
@ -179,6 +181,7 @@ else {
return IORETURN (lpt_stopioe, SCPE_UNATT); return IORETURN (lpt_stopioe, SCPE_UNATT);
if (lpt_ovrpr) fputc ('\r', uptr->fileref); /* overprint? */ if (lpt_ovrpr) fputc ('\r', uptr->fileref); /* overprint? */
fputs (lpt_buf, uptr->fileref); /* print buffer */ fputs (lpt_buf, uptr->fileref); /* print buffer */
uptr->pos = ftell (uptr->fileref); /* update position */
if (ferror (uptr->fileref)) { /* test error */ if (ferror (uptr->fileref)) { /* test error */
perror ("LPT I/O error"); perror ("LPT I/O error");
clearerr (uptr->fileref); clearerr (uptr->fileref);
@ -188,7 +191,6 @@ else {
for (i = 0; i <= LPT_BSIZE; i++) lpt_buf[i] = 0; /* clear buffer */ for (i = 0; i <= LPT_BSIZE; i++) lpt_buf[i] = 0; /* clear buffer */
lpt_ovrpr = 1; /* set overprint */ lpt_ovrpr = 1; /* set overprint */
} }
lpt_unit.pos = ftell (uptr->fileref); /* update position */
return SCPE_OK; return SCPE_OK;
} }

View file

@ -1,6 +1,6 @@
/* pdp10_cpu.c: PDP-10 CPU simulator /* pdp10_cpu.c: PDP-10 CPU simulator
Copyright (c) 1993-2005, Robert M. Supnik Copyright (c) 1993-2007, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
cpu KS10 central processor cpu KS10 central processor
28-Apr-07 RMS Removed clock initialization
22-Sep-05 RMS Fixed declarations (from Sterling Garwood) 22-Sep-05 RMS Fixed declarations (from Sterling Garwood)
Fixed warning in MOVNI Fixed warning in MOVNI
16-Aug-05 RMS Fixed C++ declaration and cast problems 16-Aug-05 RMS Fixed C++ declaration and cast problems
@ -198,7 +199,6 @@ InstHistory *hst = NULL; /* instruction history *
extern int32 sim_int_char; extern int32 sim_int_char;
extern int32 sim_interval; extern int32 sim_interval;
extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */ extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
extern UNIT tim_unit;
/* Forward and external declarations */ /* Forward and external declarations */
@ -633,7 +633,6 @@ pager_tc = FALSE; /* not in trap cycle */
pager_pi = FALSE; /* not in pi sequence */ pager_pi = FALSE; /* not in pi sequence */
rlog = 0; /* not in extend */ rlog = 0; /* not in extend */
pi_eval (); /* eval pi system */ pi_eval (); /* eval pi system */
sim_rtc_init (tim_unit.wait); /* init calibration */
if (!Q_ITS) its_1pr = 0; /* ~ITS, clr 1-proc */ if (!Q_ITS) its_1pr = 0; /* ~ITS, clr 1-proc */
t20_idlelock = 0; /* clr T20 idle lock */ t20_idlelock = 0; /* clr T20 idle lock */

View file

@ -1,6 +1,6 @@
/* pdp10_lp20.c: PDP-10 LP20 line printer simulator /* pdp10_lp20.c: PDP-10 LP20 line printer simulator
Copyright (c) 1993-2005, Robert M Supnik Copyright (c) 1993-2007, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
lp20 line printer lp20 line printer
19-Jan-07 RMS Added UNIT_TEXT flag
04-Sep-05 RMS Fixed missing return (found by Peter Schorn) 04-Sep-05 RMS Fixed missing return (found by Peter Schorn)
07-Jul-05 RMS Removed extraneous externs 07-Jul-05 RMS Removed extraneous externs
18-Mar-05 RMS Added attached test to detach routine 18-Mar-05 RMS Added attached test to detach routine
@ -185,7 +186,7 @@ DIB lp20_dib = {
}; };
UNIT lp20_unit = { UNIT lp20_unit = {
UDATA (&lp20_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT UDATA (&lp20_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0), SERIAL_OUT_WAIT
}; };
REG lp20_reg[] = { REG lp20_reg[] = {
@ -527,8 +528,9 @@ else {
if (lpcolc >= LP_WIDTH) /* line full? */ if (lpcolc >= LP_WIDTH) /* line full? */
r = lp20_adv (1, TRUE); /* adv carriage */ r = lp20_adv (1, TRUE); /* adv carriage */
} }
for (i = 0; i < rpt; i++) putc (lppdat, lp20_unit.fileref); for (i = 0; i < rpt; i++)
lp20_unit.pos = lp20_unit.pos + rpt; fputc (lppdat, lp20_unit.fileref);
lp20_unit.pos = ftell (lp20_unit.fileref);
lpcolc = lpcolc + rpt; lpcolc = lpcolc + rpt;
return r; return r;
} }
@ -539,8 +541,9 @@ int32 i;
if (cnt == 0) return TRUE; if (cnt == 0) return TRUE;
lpcolc = 0; /* reset col cntr */ lpcolc = 0; /* reset col cntr */
for (i = 0; i < cnt; i++) putc ('\n', lp20_unit.fileref); for (i = 0; i < cnt; i++)
lp20_unit.pos = lp20_unit.pos + cnt; /* print 'n' newlines */ fputc ('\n', lp20_unit.fileref);
lp20_unit.pos = ftell (lp20_unit.fileref); /* print 'n' newlines */
if (dvuadv) dvptr = (dvptr + cnt) % dvlnt; /* update DAVFU ptr */ if (dvuadv) dvptr = (dvptr + cnt) % dvlnt; /* update DAVFU ptr */
if (davfu[dvptr] & (1 << DV_TOF)) { /* at top of form? */ if (davfu[dvptr] & (1 << DV_TOF)) { /* at top of form? */
if (lppagc = (lppagc - 1) & PAGC_MASK) { /* decr page cntr */ if (lppagc = (lppagc - 1) & PAGC_MASK) { /* decr page cntr */
@ -566,8 +569,8 @@ for (i = 0; i < dvlnt; i++) { /* search DAVFU */
if (davfu[dvptr] & (1 << cnt)) { /* channel stop set? */ if (davfu[dvptr] & (1 << cnt)) { /* channel stop set? */
if (cnt) return lp20_adv (i + 1, FALSE); /* ~TOF, adv */ if (cnt) return lp20_adv (i + 1, FALSE); /* ~TOF, adv */
if (lpcolc) lp20_adv (1, FALSE); /* TOF, need newline? */ if (lpcolc) lp20_adv (1, FALSE); /* TOF, need newline? */
putc ('\f', lp20_unit.fileref); /* print form feed */ fputc ('\f', lp20_unit.fileref); /* print form feed */
lp20_unit.pos = lp20_unit.pos + 1; lp20_unit.pos = ftell (lp20_unit.fileref);
if (lppagc = (lppagc - 1) & PAGC_MASK) { /* decr page cntr */ if (lppagc = (lppagc - 1) & PAGC_MASK) { /* decr page cntr */
lpcsa = lpcsa & ~CSA_PZRO; /* update status */ lpcsa = lpcsa & ~CSA_PZRO; /* update status */
return TRUE; return TRUE;

View file

@ -1,6 +1,6 @@
/* pdp10_tu.c - PDP-10 RH11/TM03/TU45 magnetic tape simulator /* pdp10_tu.c - PDP-10 RH11/TM03/TU45 magnetic tape simulator
Copyright (c) 1993-2006, Robert M Supnik Copyright (c) 1993-2007, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
tu RH11/TM03/TU45 magtape tu RH11/TM03/TU45 magtape
29-Apr-07 RMS Fixed bug in setting FCE on TMK (found by Naoki Hamada)
16-Feb-06 RMS Added tape capacity checking 16-Feb-06 RMS Added tape capacity checking
16-Aug-05 RMS Fixed C++ declaration and cast problems 16-Aug-05 RMS Fixed C++ declaration and cast problems
07-Jul-05 RMS Removed extraneous externs 07-Jul-05 RMS Removed extraneous externs
@ -871,6 +872,7 @@ switch (fnc) { /* case on function */
tufs = tufs | FS_ID; /* PE BOT? ID burst */ tufs = tufs | FS_ID; /* PE BOT? ID burst */
TXFR (ba, wc, 0); /* validate transfer */ TXFR (ba, wc, 0); /* validate transfer */
if (st = sim_tape_rdrecf (uptr, xbuf, &tbc, MT_MAXFR)) { /* read fwd */ if (st = sim_tape_rdrecf (uptr, xbuf, &tbc, MT_MAXFR)) { /* read fwd */
if (st == MTSE_TMK) set_tuer (ER_FCE); /* TMK also sets FCE */
r = tu_map_err (uptr, st, 1); /* map error */ r = tu_map_err (uptr, st, 1); /* map error */
break; /* done */ break; /* done */
} }
@ -924,6 +926,7 @@ switch (fnc) { /* case on function */
tufc = 0; /* clear frame count */ tufc = 0; /* clear frame count */
TXFR (ba, wc, 1); /* validate xfer rev */ TXFR (ba, wc, 1); /* validate xfer rev */
if (st = sim_tape_rdrecr (uptr, xbuf + 4, &tbc, MT_MAXFR)) { /* read rev */ if (st = sim_tape_rdrecr (uptr, xbuf + 4, &tbc, MT_MAXFR)) { /* read rev */
if (st == MTSE_TMK) set_tuer (ER_FCE); /* TMK also sets FCE */
r = tu_map_err (uptr, st, 1); /* map error */ r = tu_map_err (uptr, st, 1); /* map error */
break; /* done */ break; /* done */
} }
@ -1032,7 +1035,6 @@ switch (st) {
return SCPE_IERR; return SCPE_IERR;
case MTSE_TMK: /* end of file */ case MTSE_TMK: /* end of file */
set_tuer (ER_FCE); /* also sets FCE */
tufs = tufs | FS_TMK; tufs = tufs | FS_TMK;
break; break;

View file

@ -1,6 +1,6 @@
/* pdp11_cpu.c: PDP-11 CPU simulator /* pdp11_cpu.c: PDP-11 CPU simulator
Copyright (c) 1993-2006, Robert M Supnik Copyright (c) 1993-2007, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
cpu PDP-11 CPU cpu PDP-11 CPU
28-Apr-07 RMS Removed clock initialization
27-Oct-06 RMS Added idle support 27-Oct-06 RMS Added idle support
18-Oct-06 RMS Fixed bug in ASH -32 C value 18-Oct-06 RMS Fixed bug in ASH -32 C value
24-May-06 RMS Added instruction history 24-May-06 RMS Added instruction history
@ -298,7 +299,6 @@ int32 dsmask[4] = { MMR3_KDS, MMR3_SDS, 0, MMR3_UDS }; /* dspace enables */
extern int32 CPUERR, MAINT; extern int32 CPUERR, MAINT;
extern int32 sim_interval; extern int32 sim_interval;
extern UNIT clk_unit, pclk_unit;
extern int32 sim_int_char; extern int32 sim_int_char;
extern uint32 sim_switches; extern uint32 sim_switches;
extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */ extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
@ -661,8 +661,6 @@ MMR0 = MMR0 | MMR0_IC; /* usually on */
trap_req = calc_ints (ipl, trap_req); /* upd int req */ trap_req = calc_ints (ipl, trap_req); /* upd int req */
trapea = 0; trapea = 0;
reason = 0; reason = 0;
sim_rtcn_init (clk_unit.wait, TMR_CLK); /* init line clock */
sim_rtcn_init (pclk_unit.wait, TMR_PCLK); /* init prog clock */
/* Abort handling /* Abort handling

View file

@ -1,6 +1,6 @@
/* pdp11_cpumod.c: PDP-11 CPU model-specific features /* pdp11_cpumod.c: PDP-11 CPU model-specific features
Copyright (c) 2004-2005, Robert M Supnik Copyright (c) 2004-2007, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
system PDP-11 model-specific registers system PDP-11 model-specific registers
29-Apr-07 RMS Don't run bus setup routine during RESTORE
30-Aug-05 RMS Added additional 11/60 registers 30-Aug-05 RMS Added additional 11/60 registers
16-Aug-05 RMS Fixed C++ declaration and cast problems 16-Aug-05 RMS Fixed C++ declaration and cast problems
15-Feb-05 RMS Fixed bug in SHOW MODEL (from Sergey Okhapkin) 15-Feb-05 RMS Fixed bug in SHOW MODEL (from Sergey Okhapkin)
@ -83,6 +84,7 @@ extern FILE *sim_log;
extern int32 STKLIM, PIRQ; extern int32 STKLIM, PIRQ;
extern uint32 cpu_model, cpu_type, cpu_opt; extern uint32 cpu_model, cpu_type, cpu_opt;
extern int32 clk_fie, clk_fnxm, clk_tps, clk_default; extern int32 clk_fie, clk_fnxm, clk_tps, clk_default;
extern int32 sim_switches;
t_stat CPU24_rd (int32 *data, int32 addr, int32 access); t_stat CPU24_rd (int32 *data, int32 addr, int32 access);
t_stat CPU24_wr (int32 data, int32 addr, int32 access); t_stat CPU24_wr (int32 data, int32 addr, int32 access);
@ -1100,7 +1102,8 @@ for (i = 0; i < clim; i = i + 2) nM[i >> 1] = M[i >> 1];
free (M); free (M);
M = nM; M = nM;
MEMSIZE = val; MEMSIZE = val;
cpu_set_bus (cpu_opt); if (!(sim_switches & SIM_SW_REST)) /* unless restore, */
cpu_set_bus (cpu_opt); /* alter periph config */
return SCPE_OK; return SCPE_OK;
} }

View file

@ -1,6 +1,6 @@
/* pdp11_hk.c - RK611/RK06/RK07 disk controller /* pdp11_hk.c - RK611/RK06/RK07 disk controller
Copyright (c) 1993-2005, Robert M Supnik Copyright (c) 1993-2007, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,8 @@
hk RK611/RK06/RK07 disk hk RK611/RK06/RK07 disk
29-Apr-07 RMS NOP and DCLR (at least) do not check drive type
MR2 and MR3 only updated on NOP
17-Nov-05 RMS Removed unused variable 17-Nov-05 RMS Removed unused variable
13-Nov-05 RMS Fixed overlapped seek interaction with NOP, DCLR, PACK 13-Nov-05 RMS Fixed overlapped seek interaction with NOP, DCLR, PACK
16-Aug-05 RMS Fixed C++ declaration and cast problems 16-Aug-05 RMS Fixed C++ declaration and cast problems
@ -314,6 +316,12 @@ extern uint16 *M;
#define RDH2_V_DHA 5 /* decoded head */ #define RDH2_V_DHA 5 /* decoded head */
#define RDH2_GOOD 0140000 /* good sector flags */ #define RDH2_GOOD 0140000 /* good sector flags */
/* Debug detail levels */
#define HKDEB_OPS 001 /* transactions */
#define HKDEB_RRD 002 /* reg reads */
#define HKDEB_RWR 004 /* reg writes */
extern int32 int_req[IPL_HLVL]; extern int32 int_req[IPL_HLVL];
extern FILE *sim_deb; extern FILE *sim_deb;
@ -338,7 +346,7 @@ int32 hk_min2wait = 300; /* min time to 2nd int *
int16 hkdb[3] = { 0 }; /* data buffer silo */ int16 hkdb[3] = { 0 }; /* data buffer silo */
int16 hk_off[HK_NUMDR] = { 0 }; /* saved offset */ int16 hk_off[HK_NUMDR] = { 0 }; /* saved offset */
int16 hk_dif[HK_NUMDR] = { 0 }; /* cylinder diff */ int16 hk_dif[HK_NUMDR] = { 0 }; /* cylinder diff */
static int32 reg_in_drive[16] = { static uint8 reg_in_drive[16] = {
0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
DEVICE hk_dev; DEVICE hk_dev;
@ -453,12 +461,20 @@ MTAB hk_mod[] = {
{ 0 } { 0 }
}; };
DEBTAB hk_deb[] = {
{ "OPS", HKDEB_OPS },
{ "RRD", HKDEB_RRD },
{ "RWR", HKDEB_RWR },
{ NULL, 0 }
};
DEVICE hk_dev = { DEVICE hk_dev = {
"HK", hk_unit, hk_reg, hk_mod, "HK", hk_unit, hk_reg, hk_mod,
HK_NUMDR, DEV_RDX, 24, 1, DEV_RDX, 16, HK_NUMDR, DEV_RDX, 24, 1, DEV_RDX, 16,
NULL, NULL, &hk_reset, NULL, NULL, &hk_reset,
&hk_boot, &hk_attach, &hk_detach, &hk_boot, &hk_attach, &hk_detach,
&hk_dib, DEV_DISABLE | DEV_UBUS | DEV_Q18 | DEV_DEBUG &hk_dib, DEV_DISABLE | DEV_UBUS | DEV_Q18 | DEV_DEBUG, 0,
hk_deb, NULL, 0
}; };
/* I/O dispatch routines, I/O addresses 17777440 - 17777476 */ /* I/O dispatch routines, I/O addresses 17777440 - 17777476 */
@ -538,14 +554,16 @@ switch (j) { /* decode PA<4:1> */
break; break;
case 016: /* HKMR2 */ case 016: /* HKMR2 */
*data = hkmr2 = hk_rdmr2 (GET_MS (hkmr)); *data = hkmr2;
break; break;
case 017: /* HKMR3 */ case 017: /* HKMR3 */
*data = hkmr3 = hk_rdmr3 (GET_MS (hkmr)); *data = hkmr3;
break; break;
} }
if (DEBUG_PRI (hk_dev, HKDEB_RRD))
fprintf (sim_deb, ">>HK%d read: reg%d=%o\n", drv, j, *data);
return SCPE_OK; return SCPE_OK;
} }
@ -565,6 +583,8 @@ if ((hkcs1 & CS1_GO) && /* busy? */
return SCPE_OK; return SCPE_OK;
} }
if (DEBUG_PRI (hk_dev, HKDEB_RWR))
fprintf (sim_deb, ">>HK%d write: reg%d=%o\n", drv, j, data);
switch (j) { /* decode PA<4:1> */ switch (j) { /* decode PA<4:1> */
case 000: /* HKCS1 */ case 000: /* HKCS1 */
@ -648,23 +668,27 @@ void hk_go (int32 drv)
int32 fnc, t; int32 fnc, t;
UNIT *uptr; UNIT *uptr;
static int32 fnc_nxf[16] = { static uint8 fnc_cdt[16] = {
0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
};
static uint8 fnc_nxf[16] = {
0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0
}; };
static int32 fnc_att[16] = { static uint8 fnc_att[16] = {
0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0
}; };
static int32 fnc_rdy[16] = { static uint8 fnc_rdy[16] = {
0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0
}; };
static int32 fnc_cyl[16] = { static uint8 fnc_cyl[16] = {
0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0
}; };
fnc = GET_FNC (hkcs1); fnc = GET_FNC (hkcs1);
if (DEBUG_PRS (hk_dev)) fprintf (sim_deb, if (DEBUG_PRI (hk_dev, HKDEB_OPS)) fprintf (sim_deb,
">>HK%d go: fnc=%o, ds=%o, cyl=%o, da=%o, ba=%o, wc=%o\n", ">>HK%d strt: fnc=%o, cs1=%o, cs2=%o, ds=%o, er=%o, cyl=%o, da=%o, ba=%o, wc=%o\n",
drv, fnc, hkds[drv], hkdc, hkda, hkba, hkwc); drv, fnc, hkcs1, hkcs2, hkds[drv], hker[drv], hkdc, hkda, hkba, hkwc);
uptr = hk_dev.units + drv; /* get unit */ uptr = hk_dev.units + drv; /* get unit */
if (fnc != FNC_NOP) hkmr = hkmr & ~MR_MS; /* !nop, clr msg sel */ if (fnc != FNC_NOP) hkmr = hkmr & ~MR_MS; /* !nop, clr msg sel */
if (uptr->flags & UNIT_DIS) { /* nx unit? */ if (uptr->flags & UNIT_DIS) { /* nx unit? */
@ -672,11 +696,12 @@ if (uptr->flags & UNIT_DIS) { /* nx unit? */
update_hkcs (CS1_DONE, drv); /* done */ update_hkcs (CS1_DONE, drv); /* done */
return; return;
} }
if (((hkcs1 & CS1_DT) != 0) != /* dtype mismatch? */ if (fnc_cdt[fnc] &&
((uptr->flags & UNIT_DTYPE) != 0)) { (((hkcs1 & CS1_DT) != 0) != /* need dtype match? */
hk_cmderr (ER_DTY, drv); /* type error */ ((uptr->flags & UNIT_DTYPE) != 0))) {
return; hk_cmderr (ER_DTY, drv); /* type error */
} return;
}
if (fnc_nxf[fnc] && ((hkds[drv] & DS_VV) == 0)) { /* need vol valid? */ if (fnc_nxf[fnc] && ((hkds[drv] & DS_VV) == 0)) { /* need vol valid? */
hk_cmderr (ER_NXF, drv); /* non exec func */ hk_cmderr (ER_NXF, drv); /* non exec func */
return; return;
@ -699,10 +724,15 @@ switch (fnc) { /* case on function */
/* Instantaneous functions (unit may be busy, can't schedule thread) */ /* Instantaneous functions (unit may be busy, can't schedule thread) */
case FNC_NOP: /* no operation */
hkmr2 = hk_rdmr2 (GET_MS (hkmr)); /* get serial msgs */
hkmr3 = hk_rdmr3 (GET_MS (hkmr));
update_hkcs (CS1_DONE, drv); /* done */
break;
case FNC_DCLR: /* drive clear */ case FNC_DCLR: /* drive clear */
hkds[drv] &= ~DS_ATA; /* clr ATA */ hkds[drv] &= ~DS_ATA; /* clr ATA */
hker[drv] = 0; /* clear errors */ hker[drv] = 0; /* clear errors */
case FNC_NOP: /* no operation */
update_hkcs (CS1_DONE, drv); /* done */ update_hkcs (CS1_DONE, drv); /* done */
break; break;
@ -929,9 +959,6 @@ switch (fnc) { /* case on function */
break; break;
} /* end case func */ } /* end case func */
if (DEBUG_PRS (hk_dev)) fprintf (sim_deb,
">>HK%d done: fnc=%o, cs1 = %o, cs2 = %o, ds=%o, cyl=%o, da=%o, ba=%o, wc=%o\n",
drv, fnc, hkcs1, hkcs2, hkds[drv], hkdc, hkda, hkba, hkwc);
return SCPE_OK; return SCPE_OK;
} }
@ -961,6 +988,11 @@ for (i = 0; i < HK_NUMDR; i++) { /* if ATA, set DI */
} }
if (hker[drv] | (hkcs1 & (CS1_PAR | CS1_CTO)) | /* if err, set ERR */ if (hker[drv] | (hkcs1 & (CS1_PAR | CS1_CTO)) | /* if err, set ERR */
(hkcs2 & CS2_ERR)) hkcs1 = hkcs1 | CS1_ERR; (hkcs2 & CS2_ERR)) hkcs1 = hkcs1 | CS1_ERR;
if ((flag & CS1_DONE) && /* set done && debug? */
(DEBUG_PRI (hk_dev, HKDEB_OPS)))
fprintf (sim_deb,
">>HK%d done: fnc=%o, cs1=%o, cs2=%o, ds=%o, er=%o, cyl=%o, da=%o, ba=%o, wc=%o\n",
drv, GET_FNC (hkcs1), hkcs1, hkcs2, hkds[drv], hker[drv], hkdc, hkda, hkba, hkwc);
return; return;
} }

View file

@ -1,6 +1,6 @@
/* pdp11_lp.c: PDP-11 line printer simulator /* pdp11_lp.c: PDP-11 line printer simulator
Copyright (c) 1993-2005, Robert M Supnik Copyright (c) 1993-2007, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
lpt LP11 line printer lpt LP11 line printer
19-Jan-07 RMS Added UNIT_TEXT flag
07-Jul-05 RMS Removed extraneous externs 07-Jul-05 RMS Removed extraneous externs
19-May-03 RMS Revised for new conditional compilation scheme 19-May-03 RMS Revised for new conditional compilation scheme
25-Apr-03 RMS Revised for extended file support 25-Apr-03 RMS Revised for extended file support
@ -76,7 +77,7 @@ DIB lpt_dib = {
}; };
UNIT lpt_unit = { UNIT lpt_unit = {
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0), SERIAL_OUT_WAIT
}; };
REG lpt_reg[] = { REG lpt_reg[] = {
@ -151,15 +152,16 @@ t_stat lpt_svc (UNIT *uptr)
{ {
lpt_csr = lpt_csr | CSR_ERR | CSR_DONE; lpt_csr = lpt_csr | CSR_ERR | CSR_DONE;
if (lpt_csr & CSR_IE) SET_INT (LPT); if (lpt_csr & CSR_IE) SET_INT (LPT);
if ((lpt_unit.flags & UNIT_ATT) == 0) if ((uptr->flags & UNIT_ATT) == 0)
return IORETURN (lpt_stopioe, SCPE_UNATT); return IORETURN (lpt_stopioe, SCPE_UNATT);
if (putc (lpt_unit.buf & 0177, lpt_unit.fileref) == EOF) { fputc (uptr->buf & 0177, uptr->fileref);
uptr->pos = ftell (uptr->fileref);
if (ferror (uptr->fileref)) {
perror ("LPT I/O error"); perror ("LPT I/O error");
clearerr (lpt_unit.fileref); clearerr (uptr->fileref);
return SCPE_IOERR; return SCPE_IOERR;
} }
lpt_csr = lpt_csr & ~CSR_ERR; lpt_csr = lpt_csr & ~CSR_ERR;
lpt_unit.pos = lpt_unit.pos + 1;
return SCPE_OK; return SCPE_OK;
} }

View file

@ -25,6 +25,7 @@
tu TM02/TM03 magtape tu TM02/TM03 magtape
29-Apr-07 RMS Fixed bug in setting FCE on TMK (found by Naoki Hamada)
16-Feb-06 RMS Added tape capacity checking 16-Feb-06 RMS Added tape capacity checking
12-Nov-05 RMS Changed default formatter to TM03 (for VMS) 12-Nov-05 RMS Changed default formatter to TM03 (for VMS)
31-Oct-05 RMS Fixed address width for large files 31-Oct-05 RMS Fixed address width for large files
@ -671,6 +672,7 @@ switch (fnc) { /* case on function */
if ((uptr->UDENS == TC_1600) && sim_tape_bot (uptr)) if ((uptr->UDENS == TC_1600) && sim_tape_bot (uptr))
tufs = tufs | FS_ID; /* PE BOT? ID burst */ tufs = tufs | FS_ID; /* PE BOT? ID burst */
if (st = sim_tape_rdrecf (uptr, xbuf, &tbc, MT_MAXFR)) { /* read fwd */ if (st = sim_tape_rdrecf (uptr, xbuf, &tbc, MT_MAXFR)) { /* read fwd */
if (st == MTSE_TMK) tu_set_er (ER_FCE); /* tmk also sets FCE */
r = tu_map_err (drv, st, 1); /* map error */ r = tu_map_err (drv, st, 1); /* map error */
break; /* done */ break; /* done */
} }
@ -729,6 +731,7 @@ switch (fnc) { /* case on function */
case FNC_WCHKR: /* wcheck = read */ case FNC_WCHKR: /* wcheck = read */
tufc = 0; /* clear frame count */ tufc = 0; /* clear frame count */
if (st = sim_tape_rdrecr (uptr, xbuf + 4, &tbc, MT_MAXFR)) { /* read rev */ if (st = sim_tape_rdrecr (uptr, xbuf + 4, &tbc, MT_MAXFR)) { /* read rev */
if (st == MTSE_TMK) tu_set_er (ER_FCE); /* tmk also sets FCE */
r = tu_map_err (drv, st, 1); /* map error */ r = tu_map_err (drv, st, 1); /* map error */
break; /* done */ break; /* done */
} }
@ -826,7 +829,6 @@ switch (st) {
case MTSE_TMK: /* end of file */ case MTSE_TMK: /* end of file */
tufs = tufs | FS_TMK; tufs = tufs | FS_TMK;
tu_set_er (ER_FCE); /* also sets FCE */
break; break;
case MTSE_IOERR: /* IO error */ case MTSE_IOERR: /* IO error */

View file

@ -32,31 +32,37 @@
These manuals can be found online at: These manuals can be found online at:
http://www.spies.com/~aek/pdf/dec/unibus http://www.spies.com/~aek/pdf/dec/unibus
What this BETA version contains:
1) Basic Transmit/Receive packet functionality.
2) Promiscuous/All_Multicast/Multicast/MAC support
Testing performed: Testing performed:
1) Receives/Transmits single packet under custom RSX driver 1) Receives/Transmits single packet under custom RSX driver
2) Passes RSTS 10.1 controller diagnostics during boot 2) Passes RSTS 10.1 controller diagnostics during boot
3) VMS 7.2 on VAX780 summary: 3) VMS 7.2 on VAX780 summary:
LAT - Runs properly both in and out (May/2007: WinXP x64 host; MS VC++ 2005; SIMH v3.7-0 base; WinPcap 4.0)
DECNET - Starts without error, but will not do anything LAT - SET HOST/LAT in/out
TCP/IP - Starts with errors, will ping in/out but nothing else DECNET - SET HOST in/out, COPY in/out
Clustering - Not tested TCP/IP - PING in/out; SET HOST/TELNET out, COPY/FTP out
- can't seem to connect in
- possible TCPIP v5.0 misconfiguration?
- issues with host WinXP firewall or Domain policy?
Clustering - Successfully clustered with AlphaVMS 8.2
- no hangs or offlines, some odd delays and jerkiness
- out-of-order ring messages causing retransmits?
- caused by ping times (min/avg/max) of 2/7/16 ms?
4) Runs VAX EVDWA diagnostic tests 1-10; tests 11-19 (M68000/ROM/RAM) fail
Known issues: Known issues:
1) Transmit/Receive rings have not been thoroughly tested, 1) Transmit/Receive rings have not been thoroughly tested,
particularly when and where the ring pointers get reset. particularly when and where the ring pointers get reset.
2) Most auxiliary commands are not implemented yet. 2) Most auxiliary commands are not implemented yet.
3) System_ID broadcast is not implemented 3) System_ID broadcast is not implemented.
4) Error/Interrupt signalling is still iffy from merge of FvK and sim_ether 4) Error/Interrupt signalling is still iffy from merge of FvK and sim_ether.
5) There are residual Map_ReadB and Map_WriteB from the FvK version that
probably need to be converted to Map_ReadW and Map_WriteW calls.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
Modification history: Modification history:
03-May-07 DTH Added missing FC_RMAL command; cleared multicast on write
29-Oct-06 RMS Synced poll and clock 29-Oct-06 RMS Synced poll and clock
08-Dec-05 DTH Implemented ancilliary functions 022/023/024/025 08-Dec-05 DTH Implemented ancilliary functions 022/023/024/025
18-Nov-05 DTH Corrected time between system ID packets 18-Nov-05 DTH Corrected time between system ID packets
@ -598,7 +604,7 @@ t_stat xu_reset(DEVICE* dptr)
int32 xu_command(CTLR* xu) int32 xu_command(CTLR* xu)
{ {
uint32 udbb; uint32 udbb;
int fnc, mtlen; int fnc, mtlen, i, j;
uint16 value, pltlen; uint16 value, pltlen;
t_stat status, rstatus, wstatus, wstatus2, wstatus3; t_stat status, rstatus, wstatus, wstatus2, wstatus3;
struct xu_stats* stats = &xu->var->stats; struct xu_stats* stats = &xu->var->stats;
@ -666,12 +672,24 @@ int32 xu_command(CTLR* xu)
return PCSR0_PCEI; return PCSR0_PCEI;
break; break;
case FC_RMAL: /* read multicast address list */
mtlen = (xu->var->pcb[2] & 0xFF00) >> 8;
udbb = xu->var->pcb[1] | ((xu->var->pcb[2] & 03) << 16);
wstatus = Map_WriteB(udbb, mtlen * 3, (uint8*) &xu->var->setup.macs[1]);
break;
case FC_WMAL: /* write multicast address list */ case FC_WMAL: /* write multicast address list */
mtlen = (xu->var->pcb[2] & 0xFF00) >> 8; mtlen = (xu->var->pcb[2] & 0xFF00) >> 8;
sim_debug(DBG_TRC, xu->dev, "FC_WAL: mtlen=%d\n", mtlen); sim_debug(DBG_TRC, xu->dev, "FC_WAL: mtlen=%d\n", mtlen);
if (mtlen > 10) if (mtlen > 10)
return PCSR0_PCEI; return PCSR0_PCEI;
udbb = xu->var->pcb[1] | ((xu->var->pcb[2] & 03) << 16); udbb = xu->var->pcb[1] | ((xu->var->pcb[2] & 03) << 16);
/* clear existing multicast list */
for (i=1; i<XU_FILTER_MAX; i++) {
for (j=0; j<6; j++)
xu->var->setup.macs[i][j] = 0;
}
/* get multicast list from host */
rstatus = Map_ReadB(udbb, mtlen * 6, (uint8*) &xu->var->setup.macs[1]); rstatus = Map_ReadB(udbb, mtlen * 6, (uint8*) &xu->var->setup.macs[1]);
if (rstatus == 0) { if (rstatus == 0) {
xu->var->setup.mac_count = mtlen + 1; xu->var->setup.mac_count = mtlen + 1;

View file

@ -1,6 +1,6 @@
/* pdp18b_cpu.c: 18b PDP CPU simulator /* pdp18b_cpu.c: 18b PDP CPU simulator
Copyright (c) 1993-2006, Robert M Supnik Copyright (c) 1993-2007, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
cpu PDP-4/7/9/15 central processor cpu PDP-4/7/9/15 central processor
28-Apr-07 RMS Removed clock initialization
26-Dec-06 RMS Fixed boundary test in KT15/XVM (reported by Andrew Warkentin) 26-Dec-06 RMS Fixed boundary test in KT15/XVM (reported by Andrew Warkentin)
30-Oct-06 RMS Added idle and infinite loop detection 30-Oct-06 RMS Added idle and infinite loop detection
08-Oct-06 RMS Added RDCLK instruction 08-Oct-06 RMS Added RDCLK instruction
@ -581,7 +582,6 @@ int32 api_int, api_usmd, skp;
int32 iot_data, device, pulse; int32 iot_data, device, pulse;
int32 last_IR; int32 last_IR;
t_stat reason; t_stat reason;
extern UNIT clk_unit;
if (build_dev_tab ()) return SCPE_STOP; /* build, chk tables */ if (build_dev_tab ()) return SCPE_STOP; /* build, chk tables */
PC = PC & AMASK; /* clean variables */ PC = PC & AMASK; /* clean variables */
@ -589,8 +589,8 @@ LAC = LAC & LACMASK;
MQ = MQ & DMASK; MQ = MQ & DMASK;
reason = 0; reason = 0;
last_IR = -1; last_IR = -1;
sim_rtc_init (clk_unit.wait); /* init calibration */ if (cpu_unit.flags & UNIT_NOAPI) /* no API? */
if (cpu_unit.flags & UNIT_NOAPI) api_enb = api_req = api_act = 0; api_enb = api_req = api_act = 0;
api_int = api_eval (&int_pend); /* eval API */ api_int = api_eval (&int_pend); /* eval API */
api_usmd = 0; /* not API user cycle */ api_usmd = 0; /* not API user cycle */

View file

@ -1,6 +1,6 @@
/* pdp18b_lp.c: 18b PDP's line printer simulator /* pdp18b_lp.c: 18b PDP's line printer simulator
Copyright (c) 1993-2006, Robert M Supnik Copyright (c) 1993-2007, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -28,6 +28,7 @@
lp09 (PDP-9,15) LP09 line printer lp09 (PDP-9,15) LP09 line printer
lp15 (PDP-15) LP15 line printer lp15 (PDP-15) LP15 line printer
19-Jan-07 RMS Added UNIT_TEXT flag
11-Jun-06 RMS Made character translation table global scope 11-Jun-06 RMS Made character translation table global scope
14-Jan-04 RMS Revised IO device call interface 14-Jan-04 RMS Revised IO device call interface
23-Jul-03 RMS Fixed overprint bug in Type 62 23-Jul-03 RMS Fixed overprint bug in Type 62
@ -95,7 +96,7 @@ t_stat lp62_reset (DEVICE *dptr);
DIB lp62_dib = { DEV_LPT, 2, &lp62_iors, { &lp62_65, &lp62_66 } }; DIB lp62_dib = { DEV_LPT, 2, &lp62_iors, { &lp62_65, &lp62_66 } };
UNIT lp62_unit = { UNIT lp62_unit = {
UDATA (&lp62_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT UDATA (&lp62_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0), SERIAL_OUT_WAIT
}; };
REG lp62_reg[] = { REG lp62_reg[] = {
@ -179,6 +180,7 @@ if (lp62_spc) { /* space? */
if ((uptr->flags & UNIT_ATT) == 0) /* attached? */ if ((uptr->flags & UNIT_ATT) == 0) /* attached? */
return IORETURN (lp62_stopioe, SCPE_UNATT); return IORETURN (lp62_stopioe, SCPE_UNATT);
fputs (lp62_cc[lp62_spc & 07], uptr->fileref); /* print cctl */ fputs (lp62_cc[lp62_spc & 07], uptr->fileref); /* print cctl */
uptr->pos = ftell (uptr->fileref); /* update position */
if (ferror (uptr->fileref)) { /* error? */ if (ferror (uptr->fileref)) { /* error? */
perror ("LPT I/O error"); perror ("LPT I/O error");
clearerr (uptr->fileref); clearerr (uptr->fileref);
@ -192,6 +194,7 @@ else {
return IORETURN (lp62_stopioe, SCPE_UNATT); return IORETURN (lp62_stopioe, SCPE_UNATT);
if (lp62_ovrpr) fputc ('\r', uptr->fileref); /* overprint? */ if (lp62_ovrpr) fputc ('\r', uptr->fileref); /* overprint? */
fputs (lp62_buf, uptr->fileref); /* print buffer */ fputs (lp62_buf, uptr->fileref); /* print buffer */
uptr->pos = ftell (uptr->fileref); /* update position */
if (ferror (uptr->fileref)) { /* test error */ if (ferror (uptr->fileref)) { /* test error */
perror ("LPT I/O error"); perror ("LPT I/O error");
clearerr (uptr->fileref); clearerr (uptr->fileref);
@ -201,7 +204,6 @@ else {
for (i = 0; i <= LP62_BSIZE; i++) lp62_buf[i] = 0; /* clear buffer */ for (i = 0; i <= LP62_BSIZE; i++) lp62_buf[i] = 0; /* clear buffer */
lp62_ovrpr = 1; /* set overprint */ lp62_ovrpr = 1; /* set overprint */
} }
uptr->pos = ftell (uptr->fileref); /* update position */
return SCPE_OK; return SCPE_OK;
} }
@ -274,7 +276,7 @@ t_stat lp647_detach (UNIT *uptr);
DIB lp647_dib = { DEV_LPT, 2, &lp647_iors, { &lp647_65, &lp647_66 } }; DIB lp647_dib = { DEV_LPT, 2, &lp647_iors, { &lp647_65, &lp647_66 } };
UNIT lp647_unit = { UNIT lp647_unit = {
UDATA (&lp647_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT UDATA (&lp647_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0), SERIAL_OUT_WAIT
}; };
REG lp647_reg[] = { REG lp647_reg[] = {
@ -393,7 +395,7 @@ return dat;
t_stat lp647_svc (UNIT *uptr) t_stat lp647_svc (UNIT *uptr)
{ {
int32 i; int32 i;
char pbuf[LP647_BSIZE + 1]; char pbuf[LP647_BSIZE + 2];
lp647_don = 1; lp647_don = 1;
if (lp647_ie) SET_INT (LPT); /* set flag */ if (lp647_ie) SET_INT (LPT); /* set flag */
@ -405,8 +407,10 @@ if ((lp647_iot & 020) == 0) { /* print? */
for (i = 0; i < lp647_bp; i++) /* translate buffer */ for (i = 0; i < lp647_bp; i++) /* translate buffer */
pbuf[i] = lp647_buf[i] | ((lp647_buf[i] >= 040)? 0: 0100); pbuf[i] = lp647_buf[i] | ((lp647_buf[i] >= 040)? 0: 0100);
if ((lp647_iot & 060) == 0) pbuf[lp647_bp++] = '\r'; if ((lp647_iot & 060) == 0) pbuf[lp647_bp++] = '\r';
pbuf[lp647_bp++] = 0; /* append nul */
for (i = 0; i < LP647_BSIZE; i++) lp647_buf[i] = 0; /* clear buffer */ for (i = 0; i < LP647_BSIZE; i++) lp647_buf[i] = 0; /* clear buffer */
fwrite (pbuf, 1, lp647_bp, uptr->fileref); /* print buffer */ fputs (pbuf, uptr->fileref); /* print buffer */
uptr->pos = ftell (uptr->fileref); /* update position */
if (ferror (uptr->fileref)) { /* error? */ if (ferror (uptr->fileref)) { /* error? */
perror ("LPT I/O error"); perror ("LPT I/O error");
clearerr (uptr->fileref); clearerr (uptr->fileref);
@ -417,13 +421,13 @@ if ((lp647_iot & 020) == 0) { /* print? */
} }
if (lp647_iot & 060) { /* space? */ if (lp647_iot & 060) { /* space? */
fputs (lp647_cc[lp647_iot & 07], uptr->fileref); /* write cctl */ fputs (lp647_cc[lp647_iot & 07], uptr->fileref); /* write cctl */
uptr->pos = ftell (uptr->fileref); /* update position */
if (ferror (uptr->fileref)) { /* error? */ if (ferror (uptr->fileref)) { /* error? */
perror ("LPT I/O error"); perror ("LPT I/O error");
clearerr (uptr->fileref); clearerr (uptr->fileref);
return SCPE_IOERR; return SCPE_IOERR;
} }
} }
uptr->pos = ftell (uptr->fileref); /* update position */
return SCPE_OK; return SCPE_OK;
} }
@ -501,7 +505,7 @@ t_stat lp09_detach (UNIT *uptr);
DIB lp09_dib = { DEV_LPT, 2, &lp09_iors, { NULL, &lp09_66 } }; DIB lp09_dib = { DEV_LPT, 2, &lp09_iors, { NULL, &lp09_66 } };
UNIT lp09_unit = { UNIT lp09_unit = {
UDATA (&lp09_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT UDATA (&lp09_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0), SERIAL_OUT_WAIT
}; };
REG lp09_reg[] = { REG lp09_reg[] = {
@ -582,12 +586,13 @@ if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
} }
c = uptr->buf & 0177; /* get char */ c = uptr->buf & 0177; /* get char */
if ((c == 0) || (c == 0177)) return SCPE_OK; /* skip NULL, DEL */ if ((c == 0) || (c == 0177)) return SCPE_OK; /* skip NULL, DEL */
if (fputc (c, uptr->fileref) == EOF) { /* print char */ fputc (c, uptr->fileref); /* print char */
uptr->pos = ftell (uptr->fileref); /* update position */
if (ferror (uptr->fileref)) { /* error? */
perror ("LPT I/O error"); perror ("LPT I/O error");
clearerr (uptr->fileref); clearerr (uptr->fileref);
return SCPE_IOERR; return SCPE_IOERR;
} }
uptr->pos = uptr->pos + 1; /* update position */
return SCPE_OK; return SCPE_OK;
} }
@ -657,7 +662,7 @@ int32 lp15_stopioe = 0;
int32 lp15_mode = 0; int32 lp15_mode = 0;
int32 lp15_lc = 0; int32 lp15_lc = 0;
int32 lp15_bp = 0; int32 lp15_bp = 0;
char lp15_buf[LP15_BSIZE] = { 0 }; char lp15_buf[LP15_BSIZE + 1] = { 0 };
DEVICE lp15_dev; DEVICE lp15_dev;
int32 lp15_65 (int32 dev, int32 pulse, int32 dat); int32 lp15_65 (int32 dev, int32 pulse, int32 dat);
@ -678,7 +683,7 @@ int32 lp15_updsta (int32 new);
DIB lp15_dib = { DEV_LPT, 2, &lp15_iors, { &lp15_65, &lp15_66 } }; DIB lp15_dib = { DEV_LPT, 2, &lp15_iors, { &lp15_65, &lp15_66 } };
UNIT lp15_unit = { UNIT lp15_unit = {
UDATA (&lp15_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT UDATA (&lp15_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0), SERIAL_OUT_WAIT
}; };
REG lp15_reg[] = { REG lp15_reg[] = {
@ -786,8 +791,10 @@ for (more = 1; more != 0; ) { /* loop until ctrl */
} }
for (i = 0; i < ccnt; i++) { /* loop through */ for (i = 0; i < ccnt; i++) { /* loop through */
if ((c[i] <= 037) && ctrl[c[i]]) { /* control char? */ if ((c[i] <= 037) && ctrl[c[i]]) { /* control char? */
fwrite (lp15_buf, 1, lp15_bp, uptr->fileref); lp15_buf[lp15_bp] = 0; /* append nul */
fputs (ctrl[c[i]], uptr->fileref); fputs (lp15_buf, uptr->fileref); /* print line */
fputs (ctrl[c[i]], uptr->fileref); /* space */
uptr->pos = ftell (uptr->fileref);
if (ferror (uptr->fileref)) { /* error? */ if (ferror (uptr->fileref)) { /* error? */
perror ("LPT I/O error"); perror ("LPT I/O error");
clearerr (uptr->fileref); clearerr (uptr->fileref);
@ -795,7 +802,6 @@ for (more = 1; more != 0; ) { /* loop until ctrl */
lp15_updsta (STA_DON | STA_ALM); lp15_updsta (STA_DON | STA_ALM);
return SCPE_IOERR; return SCPE_IOERR;
} }
uptr->pos = ftell (uptr->fileref);
lp15_bp = more = 0; lp15_bp = more = 0;
} }
else { else {

View file

@ -1,6 +1,6 @@
/* pdp8_cpu.c: PDP-8 CPU simulator /* pdp8_cpu.c: PDP-8 CPU simulator
Copyright (c) 1993-2006, Robert M Supnik Copyright (c) 1993-2007, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
cpu central processor cpu central processor
28-Apr-07 RMS Removed clock initialization
30-Oct-06 RMS Added idle and infinite loop detection 30-Oct-06 RMS Added idle and infinite loop detection
30-Sep-06 RMS Fixed SC value after DVI overflow (found by Don North) 30-Sep-06 RMS Fixed SC value after DVI overflow (found by Don North)
22-Sep-05 RMS Fixed declarations (from Sterling Garwood) 22-Sep-05 RMS Fixed declarations (from Sterling Garwood)
@ -244,7 +245,6 @@ extern int32 sim_int_char;
extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */ extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
extern DEVICE *sim_devices[]; extern DEVICE *sim_devices[];
extern FILE *sim_log; extern FILE *sim_log;
extern UNIT clk_unit, ttix_unit;
extern t_bool sim_idle_enab; extern t_bool sim_idle_enab;
t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw); t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw);
@ -338,8 +338,6 @@ LAC = saved_LAC & 017777;
MQ = saved_MQ & 07777; MQ = saved_MQ & 07777;
int_req = INT_UPDATE; int_req = INT_UPDATE;
reason = 0; reason = 0;
sim_rtcn_init (clk_unit.wait, TMR_CLK); /* init clk calib */
sim_rtcn_init (ttix_unit.wait, TMR_TTX); /* init ttx calib */
/* Main instruction fetch/decode loop */ /* Main instruction fetch/decode loop */

View file

@ -1,6 +1,6 @@
/* pdp8_lp.c: PDP-8 line printer simulator /* pdp8_lp.c: PDP-8 line printer simulator
Copyright (c) 1993-2005, Robert M Supnik Copyright (c) 1993-2007, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
lpt LP8E line printer lpt LP8E line printer
19-Jan-07 RMS Added UNIT_TEXT
25-Apr-03 RMS Revised for extended file support 25-Apr-03 RMS Revised for extended file support
04-Oct-02 RMS Added DIB, enable/disable, device number support 04-Oct-02 RMS Added DIB, enable/disable, device number support
30-May-02 RMS Widened POS to 32b 30-May-02 RMS Widened POS to 32b
@ -54,7 +55,7 @@ t_stat lpt_detach (UNIT *uptr);
DIB lpt_dib = { DEV_LPT, 1, { &lpt } }; DIB lpt_dib = { DEV_LPT, 1, { &lpt } };
UNIT lpt_unit = { UNIT lpt_unit = {
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0), SERIAL_OUT_WAIT
}; };
REG lpt_reg[] = { REG lpt_reg[] = {
@ -135,16 +136,17 @@ t_stat lpt_svc (UNIT *uptr)
{ {
dev_done = dev_done | INT_LPT; /* set done */ dev_done = dev_done | INT_LPT; /* set done */
int_req = INT_UPDATE; /* update interrupts */ int_req = INT_UPDATE; /* update interrupts */
if ((lpt_unit.flags & UNIT_ATT) == 0) { if ((uptr->flags & UNIT_ATT) == 0) {
lpt_err = 1; lpt_err = 1;
return IORETURN (lpt_stopioe, SCPE_UNATT); return IORETURN (lpt_stopioe, SCPE_UNATT);
} }
if (putc (lpt_unit.buf, lpt_unit.fileref) == EOF) { fputc (uptr->buf, uptr->fileref); /* print char */
uptr->pos = ftell (uptr->fileref);
if (ferror (uptr->fileref)) { /* error? */
perror ("LPT I/O error"); perror ("LPT I/O error");
clearerr (lpt_unit.fileref); clearerr (uptr->fileref);
return SCPE_IOERR; return SCPE_IOERR;
} }
lpt_unit.pos = lpt_unit.pos + 1;
return SCPE_OK; return SCPE_OK;
} }

View file

@ -1,6 +1,6 @@
/* sds_cpu.c: SDS 940 CPU simulator /* sds_cpu.c: SDS 940 CPU simulator
Copyright (c) 2001-2006, Robert M. Supnik Copyright (c) 2001-2007, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -26,6 +26,7 @@
cpu central processor cpu central processor
rtc real time clock rtc real time clock
28-Apr-07 RMS Removed clock initialization
29-Dec-06 RMS Fixed breakpoint variable declarations 29-Dec-06 RMS Fixed breakpoint variable declarations
16-Aug-05 RMS Fixed C++ declaration and cast problems 16-Aug-05 RMS Fixed C++ declaration and cast problems
07-Nov-04 RMS Added instruction history 07-Nov-04 RMS Added instruction history
@ -195,7 +196,6 @@ int32 rtc_tps = 60; /* rtc ticks/sec */
extern int32 sim_int_char; extern int32 sim_int_char;
extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */ extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
extern UNIT mux_unit;
t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw); t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw);
t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw); t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw);
@ -373,8 +373,6 @@ api_lvl = api_lvl & ~1; /* <0> reserved */
set_dyn_map (); /* set up mapping */ set_dyn_map (); /* set up mapping */
int_reqhi = api_findreq (); /* recalc int req */ int_reqhi = api_findreq (); /* recalc int req */
chan_req = chan_testact (); /* recalc chan act */ chan_req = chan_testact (); /* recalc chan act */
sim_rtcn_init (rtc_unit.wait, TMR_RTC); /* init calibration */
sim_rtcn_init (mux_unit.wait, TMR_MUX); /* init calibration */
/* Main instruction fetch/decode loop */ /* Main instruction fetch/decode loop */

View file

@ -1,6 +1,6 @@
/* sds_lp.c: SDS 940 line printer simulator /* sds_lp.c: SDS 940 line printer simulator
Copyright (c) 2001-2005, Robert M. Supnik Copyright (c) 2001-2007, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
lpt line printer lpt line printer
19-Jan-07 RMS Added UNIT_TEXT flag
25-Apr-03 RMS Revised for extended file support 25-Apr-03 RMS Revised for extended file support
*/ */
@ -77,7 +78,7 @@ t_stat lpt (uint32 fnc, uint32 inst, uint32 *dat);
DIB lpt_dib = { CHAN_W, DEV_LPT, XFR_LPT, lpt_tplt, &lpt }; DIB lpt_dib = { CHAN_W, DEV_LPT, XFR_LPT, lpt_tplt, &lpt };
UNIT lpt_unit = { UNIT lpt_unit = {
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE, 0) UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0)
}; };
REG lpt_reg[] = { REG lpt_reg[] = {

View file

@ -51,6 +51,10 @@
50. LDPCTX: 11/780 implements mbz tests on PCB fields. 50. LDPCTX: 11/780 implements mbz tests on PCB fields.
51. LDPCTX/MTPR: 11/780 validity checks PCBB, SCBB, SBR, SLR, P0BR, P0LR, P1BR, P1LR. 51. LDPCTX/MTPR: 11/780 validity checks PCBB, SCBB, SBR, SLR, P0BR, P0LR, P1BR, P1LR.
52. TMR: tmr_inc not updated in standard (100Hz) mode. 52. TMR: tmr_inc not updated in standard (100Hz) mode.
53. MTPR SBR/PCBB/SCBB: 11/780 only checks that bits<1:0> == 0.
54. MTPR xLR: 11/780 excludes bits<31:24> from mbz test.
55. MTPR PxBR: 11/780 only checks bits<31,1:0> == 1,00.

View file

@ -1,6 +1,6 @@
/* vax780_defs.h: VAX 780 model-specific definitions file /* vax780_defs.h: VAX 780 model-specific definitions file
Copyright (c) 2004-2006, Robert M Supnik Copyright (c) 2004-2007, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -23,9 +23,11 @@
used in advertising or otherwise to promote the sale, use or other dealings used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik. in this Software without prior written authorization from Robert M Supnik.
29-Oct-2006 RMS Added clock coscheduler function 29-Apr-07 RMS Modified model-specific reserved operand check macros
17-May-2006 RMS Added CR11/CD11 support (from John Dundas) to reflect 780 microcode patches (found by Naoki Hamada)
10-May-2006 RMS Added model-specific reserved operand check macros 29-Oct-06 RMS Added clock coscheduler function
17-May-06 RMS Added CR11/CD11 support (from John Dundas)
10-May-06 RMS Added model-specific reserved operand check macros
This file covers the VAX 11/780, the first VAX. This file covers the VAX 11/780, the first VAX.
@ -119,10 +121,20 @@
/* Machine specific reserved operand tests */ /* Machine specific reserved operand tests */
#define ML_PA_TEST(r) if ((r) & 0xC0000003) RSVD_OPND_FAULT /* 780 microcode patch 37 - only test LR<23:0> for appropriate length */
#define ML_LR_TEST(r) if ((uint32)(r) > 0x200000) RSVD_OPND_FAULT
#define ML_BR_TEST(r) if ((((r) & 0xC0000000) != 0x80000000) || \ #define ML_LR_TEST(r) if ((uint32)((r) & 0xFFFFFF) > 0x200000) RSVD_OPND_FAULT
/* 780 microcode patch 38 - only test PxBR<31>=1 and xBR<1:0> = 0 */
#define ML_PXBR_TEST(r) if ((((r) & 0x80000000) == 0) || \
((r) & 0x00000003)) RSVD_OPND_FAULT ((r) & 0x00000003)) RSVD_OPND_FAULT
#define ML_SBR_TEST(r) if ((r) & 0x00000003) RSVD_OPND_FAULT
/* 780 microcode patch 78 - only test xCBB<1:0> = 0 */
#define ML_PA_TEST(r) if ((r) & 0x00000003) RSVD_OPND_FAULT
#define LP_AST_TEST(r) if ((r) > AST_MAX) RSVD_OPND_FAULT #define LP_AST_TEST(r) if ((r) > AST_MAX) RSVD_OPND_FAULT
#define LP_MBZ84_TEST(r) if ((r) & 0xF8C00000) RSVD_OPND_FAULT #define LP_MBZ84_TEST(r) if ((r) & 0xF8C00000) RSVD_OPND_FAULT
#define LP_MBZ92_TEST(r) if ((r) & 0x7FC00000) RSVD_OPND_FAULT #define LP_MBZ92_TEST(r) if ((r) & 0x7FC00000) RSVD_OPND_FAULT

View file

@ -1,6 +1,6 @@
/* vax_cpu.c: VAX CPU /* vax_cpu.c: VAX CPU
Copyright (c) 1998-2006, Robert M Supnik Copyright (c) 1998-2007, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
cpu VAX central processor cpu VAX central processor
28-Apr-07 RMS Removed clock initialization
29-Oct-06 RMS Added idle support 29-Oct-06 RMS Added idle support
22-May-06 RMS Fixed format error in CPU history (found by Peter Schorn) 22-May-06 RMS Fixed format error in CPU history (found by Peter Schorn)
10-May-06 RMS Added -kesu switches for virtual addressing modes 10-May-06 RMS Added -kesu switches for virtual addressing modes
@ -284,7 +285,6 @@ extern int32 sim_int_char;
extern int32 sim_switches; extern int32 sim_switches;
extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */ extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
extern t_bool sim_idle_enab; extern t_bool sim_idle_enab;
extern UNIT clk_unit;
extern t_stat build_dib_tab (void); extern t_stat build_dib_tab (void);
extern UNIT rom_unit, nvr_unit; extern UNIT rom_unit, nvr_unit;
@ -501,7 +501,6 @@ set_map_reg (); /* set map reg */
GET_CUR; /* set access mask */ GET_CUR; /* set access mask */
SET_IRQL; /* eval interrupts */ SET_IRQL; /* eval interrupts */
FLUSH_ISTR; /* clear prefetch */ FLUSH_ISTR; /* clear prefetch */
sim_rtcn_init (clk_unit.wait, TMR_CLK); /* init clock */
abortval = setjmp (save_env); /* set abort hdlr */ abortval = setjmp (save_env); /* set abort hdlr */
if (abortval > 0) { /* sim stop? */ if (abortval > 0) { /* sim stop? */

View file

@ -1,6 +1,6 @@
/* vax_cpu1.c: VAX complex instructions /* vax_cpu1.c: VAX complex instructions
Copyright (c) 1998-2006, Robert M Supnik Copyright (c) 1998-2007, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -23,6 +23,7 @@
used in advertising or otherwise to promote the sale, use or other dealings used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik. in this Software without prior written authorization from Robert M Supnik.
29-Apr-07 RMS Separated base register access checks for 11/780
10-May-06 RMS Added access check on system PTE for 11/780 10-May-06 RMS Added access check on system PTE for 11/780
Added mbz check in LDPCTX for 11/780 Added mbz check in LDPCTX for 11/780
22-Sep-06 RMS Fixed declarations (from Sterling Garwood) 22-Sep-06 RMS Fixed declarations (from Sterling Garwood)
@ -1230,7 +1231,7 @@ newpc = ReadLP (pcbpa + 72); /* get PC, PSL */
newpsl = ReadLP (pcbpa + 76); newpsl = ReadLP (pcbpa + 76);
t = ReadLP (pcbpa + 80); t = ReadLP (pcbpa + 80);
ML_BR_TEST (t); /* validate P0BR */ ML_PXBR_TEST (t); /* validate P0BR */
P0BR = t & BR_MASK; /* restore P0BR */ P0BR = t & BR_MASK; /* restore P0BR */
t = ReadLP (pcbpa + 84); t = ReadLP (pcbpa + 84);
LP_MBZ84_TEST (t); /* test mbz */ LP_MBZ84_TEST (t); /* test mbz */
@ -1240,7 +1241,7 @@ t = (t >> 24) & AST_MASK;
LP_AST_TEST (t); /* validate AST */ LP_AST_TEST (t); /* validate AST */
ASTLVL = t; /* restore AST */ ASTLVL = t; /* restore AST */
t = ReadLP (pcbpa + 88); t = ReadLP (pcbpa + 88);
ML_BR_TEST (t + 0x800000); /* validate P1BR */ ML_PXBR_TEST (t + 0x800000); /* validate P1BR */
P1BR = t & BR_MASK; /* restore P1BR */ P1BR = t & BR_MASK; /* restore P1BR */
t = ReadLP (pcbpa + 92); t = ReadLP (pcbpa + 92);
LP_MBZ92_TEST (t); /* test MBZ */ LP_MBZ92_TEST (t); /* test MBZ */
@ -1387,7 +1388,7 @@ switch (prn) { /* case on reg # */
break; break;
case MT_P0BR: /* P0BR */ case MT_P0BR: /* P0BR */
ML_BR_TEST (val); /* validate */ ML_PXBR_TEST (val); /* validate */
P0BR = val & BR_MASK; /* lw aligned */ P0BR = val & BR_MASK; /* lw aligned */
zap_tb (0); /* clr proc TLB */ zap_tb (0); /* clr proc TLB */
set_map_reg (); set_map_reg ();
@ -1401,7 +1402,7 @@ switch (prn) { /* case on reg # */
break; break;
case MT_P1BR: /* P1BR */ case MT_P1BR: /* P1BR */
ML_BR_TEST (val + 0x800000); /* validate */ ML_PXBR_TEST (val + 0x800000); /* validate */
P1BR = val & BR_MASK; /* lw aligned */ P1BR = val & BR_MASK; /* lw aligned */
zap_tb (0); /* clr proc TLB */ zap_tb (0); /* clr proc TLB */
set_map_reg (); set_map_reg ();
@ -1415,7 +1416,7 @@ switch (prn) { /* case on reg # */
break; break;
case MT_SBR: /* SBR */ case MT_SBR: /* SBR */
ML_PA_TEST (val); /* validate */ ML_SBR_TEST (val); /* validate */
SBR = val & BR_MASK; /* lw aligned */ SBR = val & BR_MASK; /* lw aligned */
zap_tb (1); /* clr entire TLB */ zap_tb (1); /* clr entire TLB */
set_map_reg (); set_map_reg ();

View file

@ -1,6 +1,6 @@
/* vax_mmu.c - VAX memory management /* vax_mmu.c - VAX memory management
Copyright (c) 1998-2005, Robert M Supnik Copyright (c) 1998-2007, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -23,6 +23,7 @@
used in advertising or otherwise to promote the sale, use or other dealings used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik. in this Software without prior written authorization from Robert M Supnik.
29-Apr-07 RMS Added address masking for system page table reads
22-Sep-05 RMS Fixed declarations (from Sterling Garwood) 22-Sep-05 RMS Fixed declarations (from Sterling Garwood)
30-Sep-04 RMS Comment and formating changes 30-Sep-04 RMS Comment and formating changes
19-Sep-03 RMS Fixed upper/lower case linkage problems on VMS 19-Sep-03 RMS Fixed upper/lower case linkage problems on VMS
@ -444,7 +445,7 @@ static TLBENT zero_pte = { 0, 0 };
if (va & VA_S0) { /* system space? */ if (va & VA_S0) { /* system space? */
if (ptidx >= d_slr) /* system */ if (ptidx >= d_slr) /* system */
MM_ERR (PR_LNV); MM_ERR (PR_LNV);
ptead = d_sbr + ptidx; ptead = (d_sbr + ptidx) & PAMASK;
} }
else { else {
if (va & VA_P1) { /* P1? */ if (va & VA_P1) { /* P1? */
@ -463,7 +464,7 @@ else {
ptidx = ((uint32) ptead) >> 7; /* xlate like sys */ ptidx = ((uint32) ptead) >> 7; /* xlate like sys */
if (ptidx >= d_slr) if (ptidx >= d_slr)
MM_ERR (PR_PLNV); MM_ERR (PR_PLNV);
pte = ReadLP (d_sbr + ptidx); /* get system pte */ pte = ReadLP ((d_sbr + ptidx) & PAMASK); /* get system pte */
#if defined (VAX_780) #if defined (VAX_780)
if ((pte & PTE_ACC) == 0) MM_ERR (PR_PACV); /* spte ACV? */ if ((pte & PTE_ACC) == 0) MM_ERR (PR_PACV); /* spte ACV? */
#endif #endif

View file

@ -1,6 +1,6 @@
/* vaxmod_defs.h: VAX model-specific definitions file /* vaxmod_defs.h: VAX model-specific definitions file
Copyright (c) 1998-2006, Robert M Supnik Copyright (c) 1998-2007, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -23,6 +23,7 @@
used in advertising or otherwise to promote the sale, use or other dealings used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik. in this Software without prior written authorization from Robert M Supnik.
29-Apr-07 RMS Separated checks for PxBR and SBR
17-May-06 RMS Added CR11/CD11 support 17-May-06 RMS Added CR11/CD11 support
10-May-06 RMS Added NOP'd reserved operand checking macros 10-May-06 RMS Added NOP'd reserved operand checking macros
05-Oct-05 RMS Added XU definitions for autoconfigure 05-Oct-05 RMS Added XU definitions for autoconfigure
@ -204,7 +205,8 @@
#define ML_PA_TEST(r) #define ML_PA_TEST(r)
#define ML_LR_TEST(r) #define ML_LR_TEST(r)
#define ML_BR_TEST(r) #define ML_SBR_TEST(r)
#define ML_PXBR_TEST(r)
#define LP_AST_TEST(r) #define LP_AST_TEST(r)
#define LP_MBZ84_TEST(r) #define LP_MBZ84_TEST(r)
#define LP_MBZ92_TEST(r) #define LP_MBZ92_TEST(r)

View file

@ -10,7 +10,11 @@ OS_CCDEFS = -lsocket -lnsl -lpthread -D_GNU_SOURCE
else else
OS_CCDEFS = -D_GNU_SOURCE OS_CCDEFS = -D_GNU_SOURCE
endif endif
ifeq ($(OSTYPE),macos)
CC = gcc -std=c99 -O2 -U__STRICT_ANSI__ -g -lm -lrt $(OS_CCDEFS) -I . CC = gcc -std=c99 -O2 -U__STRICT_ANSI__ -g -lm -lrt $(OS_CCDEFS) -I .
else
CC = gcc -std=c99 -O2 -U__STRICT_ANSI__ -g -lm $(OS_CCDEFS) -I .
endif
ifeq ($(USE_NETWORK),) ifeq ($(USE_NETWORK),)
else else
NETWORK_OPT = -DUSE_NETWORK -isystem /usr/local/include /usr/local/lib/libpcap.a NETWORK_OPT = -DUSE_NETWORK -isystem /usr/local/include /usr/local/lib/libpcap.a

26
scp.c
View file

@ -23,6 +23,10 @@
used in advertising or otherwise to promote the sale, use or other dealings used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik. in this Software without prior written authorization from Robert M Supnik.
28-Apr-07 RMS Modified sim_instr invocation to call sim_rtcn_init_all
Fixed bug in get_sim_opt
Fixed bug in restoration with changed memory size
08-Mar-07 JDB Fixed breakpoint actions in DO command file processing
30-Jan-07 RMS Fixed bugs in get_ipaddr 30-Jan-07 RMS Fixed bugs in get_ipaddr
17-Oct-06 RMS Added idle support 17-Oct-06 RMS Added idle support
04-Oct-06 JDB DO cmd failure now echoes cmd unless -q 04-Oct-06 JDB DO cmd failure now echoes cmd unless -q
@ -832,8 +836,10 @@ if ((fpin = fopen (do_arg[0], "r")) == NULL) { /* file failed to open?
if (flag < 1) flag = 1; /* start at level 1 */ if (flag < 1) flag = 1; /* start at level 1 */
do { do {
ocptr = cptr = read_line (cbuf, CBUFSIZE, fpin); /* get cmd line */ ocptr = cptr = sim_brk_getact (cbuf, CBUFSIZE); /* get bkpt action */
sub_args (cbuf, gbuf, CBUFSIZE, nargs, do_arg); if (!ocptr) /* no pending action? */
ocptr = cptr = read_line (cbuf, CBUFSIZE, fpin); /* get cmd line */
sub_args (cbuf, gbuf, CBUFSIZE, nargs, do_arg); /* substitute args */
if (cptr == NULL) { /* EOF? */ if (cptr == NULL) { /* EOF? */
stat = SCPE_OK; /* set good return */ stat = SCPE_OK; /* set good return */
break; break;
@ -2169,6 +2175,7 @@ if (v32) { /* [V3.2+] time as strin
else READ_I (sim_time); /* sim time */ else READ_I (sim_time); /* sim time */
READ_I (sim_rtime); /* [V2.6+] sim rel time */ READ_I (sim_rtime); /* [V2.6+] sim rel time */
sim_switches = SIM_SW_REST; /* flag restore */
for ( ;; ) { /* device loop */ for ( ;; ) { /* device loop */
READ_S (buf); /* read device name */ READ_S (buf); /* read device name */
if (buf[0] == 0) break; /* last? */ if (buf[0] == 0) break; /* last? */
@ -2214,7 +2221,6 @@ for ( ;; ) { /* device loop */
(!(dptr->flags & DEV_NET) || /* not net dev or */ (!(dptr->flags & DEV_NET) || /* not net dev or */
!(uptr->flags & UNIT_ATT) || /* not currently att */ !(uptr->flags & UNIT_ATT) || /* not currently att */
(buf[0] == 0))) { /* or will not be att */ (buf[0] == 0))) { /* or will not be att */
sim_switches = SIM_SW_REST; /* att-det/rest */
r = scp_detach_unit (dptr, uptr); /* detach old */ r = scp_detach_unit (dptr, uptr); /* detach old */
if (r != SCPE_OK) return r; if (r != SCPE_OK) return r;
if (buf[0] != 0) { /* any file? */ if (buf[0] != 0) { /* any file? */
@ -2232,16 +2238,16 @@ for ( ;; ) { /* device loop */
printf ("Can't restore memory: %s%d\n", sim_dname (dptr), unitno); printf ("Can't restore memory: %s%d\n", sim_dname (dptr), unitno);
return SCPE_INCOMP; return SCPE_INCOMP;
} }
if (high != old_capac) { if (high != old_capac) { /* size change? */
uptr->capac = old_capac; /* temp restore old */
if ((dptr->flags & DEV_DYNM) && if ((dptr->flags & DEV_DYNM) &&
((dptr->msize == NULL) || ((dptr->msize == NULL) ||
(dptr->msize (uptr, (int32) high, NULL, NULL) != SCPE_OK))) { (dptr->msize (uptr, (int32) high, NULL, NULL) != SCPE_OK))) {
printf ("Can't change memory size: %s%d\n", printf ("Can't change memory size: %s%d\n",
sim_dname (dptr), unitno); sim_dname (dptr), unitno);
uptr->capac = old_capac;
return SCPE_INCOMP; return SCPE_INCOMP;
} }
uptr->capac = high; uptr->capac = high; /* new memory size */
printf ("Memory size changed: %s%d = ", sim_dname (dptr), unitno); printf ("Memory size changed: %s%d = ", sim_dname (dptr), unitno);
fprint_capac (stdout, dptr, uptr); fprint_capac (stdout, dptr, uptr);
printf ("\n"); printf ("\n");
@ -2382,6 +2388,7 @@ if (sim_step) sim_activate (&sim_step_unit, sim_step); /* set step timer */
sim_throt_sched (); /* set throttle */ sim_throt_sched (); /* set throttle */
sim_is_running = 1; /* flag running */ sim_is_running = 1; /* flag running */
sim_brk_clract (); /* defang actions */ sim_brk_clract (); /* defang actions */
sim_rtcn_init_all (); /* re-init clocks */
r = sim_instr(); r = sim_instr();
sim_is_running = 0; /* flag idle */ sim_is_running = 0; /* flag idle */
@ -3495,6 +3502,7 @@ return cptr;
char *get_sim_opt (int32 opt, char *cptr, t_stat *st) char *get_sim_opt (int32 opt, char *cptr, t_stat *st)
{ {
int32 t; int32 t;
t_bool dfdu;
char *svptr, gbuf[CBUFSIZE]; char *svptr, gbuf[CBUFSIZE];
DEVICE *tdptr; DEVICE *tdptr;
UNIT *tuptr; UNIT *tuptr;
@ -3508,6 +3516,7 @@ sim_stab.mask = 0;
sim_stab.comp = 0; sim_stab.comp = 0;
sim_dfdev = sim_dflt_dev; sim_dfdev = sim_dflt_dev;
sim_dfunit = sim_dfdev->units; sim_dfunit = sim_dfdev->units;
dfdu = FALSE; /* no default yet */
*st = SCPE_OK; *st = SCPE_OK;
while (*cptr) { /* loop through modifiers */ while (*cptr) { /* loop through modifiers */
svptr = cptr; /* save current position */ svptr = cptr; /* save current position */
@ -3532,13 +3541,14 @@ while (*cptr) { /* loop through modifier
sim_switches = sim_switches | t; /* or in new switches */ sim_switches = sim_switches | t; /* or in new switches */
} }
else if ((opt & CMD_OPT_SCH) && /* if allowed, */ else if ((opt & CMD_OPT_SCH) && /* if allowed, */
get_search (gbuf, sim_dfdev->dradix, &sim_stab)) /* try for search */ get_search (gbuf, sim_dfdev->dradix, &sim_stab)) /* try for search */
sim_schptr = &sim_stab; /* set search */ sim_schptr = &sim_stab; /* set search */
else if ((opt & CMD_OPT_DFT) && /* if allowed, */ else if ((opt & CMD_OPT_DFT) && !dfdu && /* if allowed, none yet*/
(tdptr = find_unit (gbuf, &tuptr)) && /* try for default */ (tdptr = find_unit (gbuf, &tuptr)) && /* try for default */
(tuptr != NULL)) { (tuptr != NULL)) {
sim_dfdev = tdptr; /* set as default */ sim_dfdev = tdptr; /* set as default */
sim_dfunit = tuptr; sim_dfunit = tuptr;
dfdu = TRUE; /* indicate dflt seen */
} }
else return svptr; /* not rec, break out */ else return svptr; /* not rec, break out */
} }

View file

@ -1,6 +1,6 @@
/* sim_defs.h: simulator definitions /* sim_defs.h: simulator definitions
Copyright (c) 1993-2006, Robert M Supnik Copyright (c) 1993-2007, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -23,6 +23,8 @@
used in advertising or otherwise to promote the sale, use or other dealings used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik. in this Software without prior written authorization from Robert M Supnik.
18-Mar-07 RMS Added UNIT_TEXT flag
07-Mar-07 JDB Added DEBUG_PRJ macro
18-Oct-06 RMS Added limit check for clock synchronized keyboard waits 18-Oct-06 RMS Added limit check for clock synchronized keyboard waits
13-Jul-06 RMS Guarantee CBUFSIZE is at least 256 13-Jul-06 RMS Guarantee CBUFSIZE is at least 256
07-Jan-06 RMS Added support for breakpoint spaces 07-Jan-06 RMS Added support for breakpoint spaces
@ -363,6 +365,7 @@ struct sim_unit {
#define UNIT_DISABLE 002000 /* disable-able */ #define UNIT_DISABLE 002000 /* disable-able */
#define UNIT_DIS 004000 /* disabled */ #define UNIT_DIS 004000 /* disabled */
#define UNIT_RAW 010000 /* raw mode */ #define UNIT_RAW 010000 /* raw mode */
#define UNIT_TEXT 020000 /* text mode */
#define UNIT_UFMASK_31 (((1u << UNIT_V_RSV) - 1) & ~((1u << UNIT_V_UF_31) - 1)) #define UNIT_UFMASK_31 (((1u << UNIT_V_RSV) - 1) & ~((1u << UNIT_V_UF_31) - 1))
#define UNIT_UFMASK (((1u << UNIT_V_RSV) - 1) & ~((1u << UNIT_V_UF) - 1)) #define UNIT_UFMASK (((1u << UNIT_V_RSV) - 1) & ~((1u << UNIT_V_UF) - 1))
@ -470,6 +473,7 @@ struct sim_debtab {
#define DEBUG_PRS(d) (sim_deb && d.dctrl) #define DEBUG_PRS(d) (sim_deb && d.dctrl)
#define DEBUG_PRD(d) (sim_deb && d->dctrl) #define DEBUG_PRD(d) (sim_deb && d->dctrl)
#define DEBUG_PRI(d,m) (sim_deb && (d.dctrl & (m))) #define DEBUG_PRI(d,m) (sim_deb && (d.dctrl & (m)))
#define DEBUG_PRJ(d,m) (sim_deb && (d->dctrl & (m)))
/* The following macros define structure contents */ /* The following macros define structure contents */

View file

@ -1,6 +1,6 @@
/* sim_rev.h: simulator revisions and current rev level /* sim_rev.h: simulator revisions and current rev level
Copyright (c) 1993-2006, Robert M Supnik Copyright (c) 1993-2007, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -29,12 +29,67 @@
#define SIM_MAJOR 3 #define SIM_MAJOR 3
#define SIM_MINOR 7 #define SIM_MINOR 7
#define SIM_PATCH 0 #define SIM_PATCH 1
/* V3.7 revision history /* V3.7 revision history
patch date module(s) and fix(es) patch date module(s) and fix(es)
1 tbd scp.c:
- modified sim_instr invocation to call sim_rtcn_init_all
- fixed bug in get_sim_opt (reported by Don North)
- fixed bug in RESTORE with changed memory size
- added global 'RESTORE in progress' flag
- fixed breakpoint actions in DO command file processing
(from Dave Bryan)
all CPU's with clocks:
- removed clock initialization (now done in SCP)
hp2100_cpu.c (from Dave Bryan):
- EDT passes input flag and DMA channel in dat parameter
hp2100_ipl.c (from Dave Bryan):
- IPLI EDT delays DMA completion interrupt for TSB
hp2100_mux.c (from Dave Bryan):
- corrected "mux_sta" size from 16 to 21 elements
- fixed "muxc_reset" to clear lines 16-20
- fixed control card OTx to set current channel number
- fixed to set "muxl_ibuf" in response to a transmit interrupt
- changed "mux_xbuf", "mux_rbuf" declarations from 8 to 16 bits
- fixed to set "mux_rchp" when a line break is received
- fixed incorrect "odd_par" table values
- reversed test in "RCV_PAR" to return "LIL_PAR" on odd parity
- rixed mux reset (ioCRS) to clear port parameters
- fixed to use PUT_DCH instead of PUT_CCH for data channel status
- added DIAG/TERM modifiers to implement diagnostic mode
pdp11_cpumod.c:
- changed memory size routine to work with RESTORE
pdp11_hk.c:
- NOP and DCLR (at least) do not check drive type
- MR2 and MR3 only updated on NOP
pdp10_tu.c, pdp11_tu.c:
- TMK sets FCE only on read (found by Naoki Hamada)
pdp11_xu.c:
- added missing FC_RMAL command
- cleared multicast on write
vax_moddefs.h, vax_cpu1.c:
- separated PxBR and SBR mbz checks
vax780_defs.h
- separated PxBR and SBR mbz checks
- modified mbz checks to reflect 780 microcode patches
(found by Naoki Hamada)
vax_mmu.c:
- added address masking to all SBR-based memory reads
0 30-Jan-07 scp.c: 0 30-Jan-07 scp.c:
- implemented throttle commands - implemented throttle commands
- added -e to control error processing in DO command files - added -e to control error processing in DO command files

View file

@ -1,6 +1,6 @@
/* sim_timer.c: simulator timer library /* sim_timer.c: simulator timer library
Copyright (c) 1993-2006, Robert M Supnik Copyright (c) 1993-2007, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -23,9 +23,9 @@
used in advertising or otherwise to promote the sale, use or other dealings used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik. in this Software without prior written authorization from Robert M Supnik.
22-Aug-07 RMS Added sim_rtcn_init_all
17-Oct-06 RMS Added idle support (based on work by Mark Pizzolato) 17-Oct-06 RMS Added idle support (based on work by Mark Pizzolato)
Added throttle support Added throttle support
21-Aug-05 RMS Added sim_rtcn_init_all
16-Aug-05 RMS Fixed C++ declaration and cast problems 16-Aug-05 RMS Fixed C++ declaration and cast problems
02-Jan-04 RMS Split out from SCP 02-Jan-04 RMS Split out from SCP
@ -344,6 +344,16 @@ static int32 rtc_based[SIM_NTIMERS] = { 0 }; /* base delay */
static int32 rtc_currd[SIM_NTIMERS] = { 0 }; /* current delay */ static int32 rtc_currd[SIM_NTIMERS] = { 0 }; /* current delay */
static int32 rtc_initd[SIM_NTIMERS] = { 0 }; /* initial delay */ static int32 rtc_initd[SIM_NTIMERS] = { 0 }; /* initial delay */
void sim_rtcn_init_all (void)
{
uint32 i;
for (i = 0; i < SIM_NTIMERS; i++) {
if (rtc_initd[i] != 0) sim_rtcn_init (rtc_initd[i], i);
}
return;
}
int32 sim_rtcn_init (int32 time, int32 tmr) int32 sim_rtcn_init (int32 time, int32 tmr)
{ {
if (time == 0) time = 1; if (time == 0) time = 1;

View file

@ -1,6 +1,6 @@
/* sim_timer.h: simulator timer library headers /* sim_timer.h: simulator timer library headers
Copyright (c) 1993-2006, Robert M Supnik Copyright (c) 1993-2007, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -23,6 +23,7 @@
used in advertising or otherwise to promote the sale, use or other dealings used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik. in this Software without prior written authorization from Robert M Supnik.
28-Apr-07 RMS Added sim_rtc_init_all
17-Oct-06 RMS Added idle support 17-Oct-06 RMS Added idle support
02-Jan-04 RMS Split out from SCP 02-Jan-04 RMS Split out from SCP
*/ */
@ -48,6 +49,7 @@
t_bool sim_timer_init (void); t_bool sim_timer_init (void);
int32 sim_rtcn_init (int32 time, int32 tmr); int32 sim_rtcn_init (int32 time, int32 tmr);
void sim_rtcn_init_all (void);
int32 sim_rtcn_calb (int32 ticksper, int32 tmr); int32 sim_rtcn_calb (int32 ticksper, int32 tmr);
int32 sim_rtc_init (int32 time); int32 sim_rtc_init (int32 time);
int32 sim_rtc_calb (int32 ticksper); int32 sim_rtc_calb (int32 ticksper);