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:
parent
53d02f7fa7
commit
6149cc7e06
57 changed files with 10269 additions and 9632 deletions
|
@ -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
|
@ -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
|
@ -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, §orSize, &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, §orSize, &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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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) },
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
--------------------------------------------
|
--------------------------------------------
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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[] = {
|
||||||
|
|
|
@ -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[] = {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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[] = {
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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? */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) },
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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[] = {
|
||||||
|
|
|
@ -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.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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? */
|
||||||
|
|
|
@ -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 ();
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
4
makefile
4
makefile
|
@ -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
26
scp.c
|
@ -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 */
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
59
sim_rev.h
59
sim_rev.h
|
@ -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
|
||||||
|
|
14
sim_timer.c
14
sim_timer.c
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Reference in a new issue