Notes For V3.7

1. New Features

1.1 3.7-0

1.1.1 SCP

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

1.1.2 HP2100

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

1.1.3 Interdata

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

1.1.4 PDP-11

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

1.1.5 PDP-8

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

1.1.6 PDP-1

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

1.1.6 PDP-4/7/9/15

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

1.1.7 VAX, VAX780

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

1.1.8 PDP-10

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

2. Bugs Fixed

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

View file

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

View file

@ -14,7 +14,7 @@
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
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
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.
@ -160,12 +160,6 @@ void PutBYTEWrapper(const uint32 Addr, const uint32 Value);
int32 getBankSelect(void);
void setBankSelect(const int32 b);
uint32 getCommon(void);
static void PutBYTEForced(uint32 Addr, const uint32 Value);
static int32 addressIsInROM(const uint32 Addr);
static int32 addressExists(const uint32 Addr);
static void printROMMessage(const uint32 cntROM);
static void warnUnsuccessfulWriteAttempt(const uint32 Addr);
static uint8 warnUnsuccessfulReadAttempt(const uint32 Addr);
static t_stat cpu_set_rom (UNIT *uptr, int32 value, char *cptr, void *desc);
static t_stat cpu_set_norom (UNIT *uptr, int32 value, char *cptr, void *desc);
static t_stat cpu_set_altairrom (UNIT *uptr, int32 value, char *cptr, void *desc);
@ -173,15 +167,6 @@ static t_stat cpu_set_warnrom (UNIT *uptr, int32 value, char *cptr, void *desc
static t_stat cpu_set_banked (UNIT *uptr, int32 value, char *cptr, void *desc);
static t_stat cpu_set_nonbanked (UNIT *uptr, int32 value, char *cptr, void *desc);
static t_stat cpu_set_size (UNIT *uptr, int32 value, char *cptr, void *desc);
static void prepareMemoryAccessMessage(t_addr loc);
static void checkROMBoundaries(void);
static void reset_memory(void);
static uint32 in(const uint32 Port);
static void out(const uint32 Port, const uint32 Value);
static void PutBYTE(register uint32 Addr, const register uint32 Value);
static void PutWORD(register uint32 Addr, const register uint32 Value);
static t_bool sim_brk_lookup (const t_addr bloc, const int32 btyp);
static void resetCell(const int32 address, const int32 bank);
/* CPU data structures
cpu_dev CPU device descriptor
@ -194,7 +179,7 @@ UNIT cpu_unit = {
UDATA (NULL, UNIT_FIX + UNIT_BINK + UNIT_ROM + UNIT_ALTAIRROM, MAXMEMSIZE)
};
int32 PCX; /* external view of PC */
int32 PCX = 0; /* external view of PC */
int32 saved_PC = 0; /* program counter */
static int32 AF_S; /* AF register */
static int32 BC_S; /* BC register */
@ -1183,7 +1168,7 @@ static const uint8 cpTable[256] = {
128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
};
/* remove comments to generate table contents
/* remove comments to generate table contents and define globally NEED_SIM_VM_INIT
static void altairz80_init(void);
void (*sim_vm_init) (void) = &altairz80_init;
static void altairz80_init(void) {
@ -1467,6 +1452,16 @@ void protect(const int32 l, const int32 h) {
static uint8 M[MAXMEMSIZE][MAXBANKS]; /* RAM which is present */
/* determine whether Addr points to Read Only Memory */
static int32 addressIsInROM(const uint32 Addr) {
uint32 addr = Addr & ADDRMASK; /* registers are NOT guaranteed to be always 16-bit values */
return (cpu_unit.flags & UNIT_ROM) && ( /* must have ROM enabled */
/* in banked case we have standard Altair ROM */
((cpu_unit.flags & UNIT_BANKED) && (DEFAULT_ROM_LOW <= addr)) ||
/* in non-banked case we check the bounds of the ROM */
(((cpu_unit.flags & UNIT_BANKED) == 0) && (ROMLow <= addr) && (addr <= ROMHigh)));
}
static void warnUnsuccessfulWriteAttempt(const uint32 Addr) {
if (cpu_unit.flags & UNIT_WARNROM) {
if (addressIsInROM(Addr)) {
@ -1485,18 +1480,8 @@ static uint8 warnUnsuccessfulReadAttempt(const uint32 Addr) {
return 0xff;
}
/* determine whether Addr points to Read Only Memory */
int32 addressIsInROM(const uint32 Addr) {
uint32 addr = Addr & ADDRMASK; /* registers are NOT guaranteed to be always 16-bit values */
return (cpu_unit.flags & UNIT_ROM) && ( /* must have ROM enabled */
/* in banked case we have standard Altair ROM */
((cpu_unit.flags & UNIT_BANKED) && (DEFAULT_ROM_LOW <= addr)) ||
/* in non-banked case we check the bounds of the ROM */
(((cpu_unit.flags & UNIT_BANKED) == 0) && (ROMLow <= addr) && (addr <= ROMHigh)));
}
/* determine whether Addr points to a valid memory address */
int32 addressExists(const uint32 Addr) {
static int32 addressExists(const uint32 Addr) {
uint32 addr = Addr & ADDRMASK; /* registers are NOT guaranteed to be always 16-bit values */
return (cpu_unit.flags & UNIT_BANKED) || (addr < MEMSIZE) ||
( ((cpu_unit.flags & UNIT_BANKED) == 0) && (cpu_unit.flags & UNIT_ROM)
@ -5019,6 +5004,7 @@ t_stat sim_instr (void) {
tStates -= 5;
acu = HIGH_REGISTER(AF);
BC &= ADDRMASK;
if (BC == 0) BC = 0x10000;
do {
tStates += 21;
CHECK_BREAK_TWO_BYTES(HL, DE);
@ -5033,6 +5019,7 @@ t_stat sim_instr (void) {
tStates -= 5;
acu = HIGH_REGISTER(AF);
BC &= ADDRMASK;
if (BC == 0) BC = 0x10000;
do {
tStates += 21;
CHECK_BREAK_BYTE(HL);
@ -5053,6 +5040,7 @@ t_stat sim_instr (void) {
case 0xb2: /* INIR */
tStates -= 5;
temp = HIGH_REGISTER(BC);
if (temp == 0) temp = 0x100;
do {
tStates += 21;
CHECK_BREAK_BYTE(HL);
@ -5067,6 +5055,7 @@ t_stat sim_instr (void) {
case 0xb3: /* OTIR */
tStates -= 5;
temp = HIGH_REGISTER(BC);
if (temp == 0) temp = 0x100;
do {
tStates += 21;
CHECK_BREAK_BYTE(HL);
@ -5081,6 +5070,7 @@ t_stat sim_instr (void) {
case 0xb8: /* LDDR */
tStates -= 5;
BC &= ADDRMASK;
if (BC == 0) BC = 0x10000;
do {
tStates += 21;
CHECK_BREAK_TWO_BYTES(HL, DE);
@ -5095,6 +5085,7 @@ t_stat sim_instr (void) {
tStates -= 5;
acu = HIGH_REGISTER(AF);
BC &= ADDRMASK;
if (BC == 0) BC = 0x10000;
do {
tStates += 21;
CHECK_BREAK_BYTE(HL);
@ -5115,6 +5106,7 @@ t_stat sim_instr (void) {
case 0xba: /* INDR */
tStates -= 5;
temp = HIGH_REGISTER(BC);
if (temp == 0) temp = 0x100;
do {
tStates += 21;
CHECK_BREAK_BYTE(HL);
@ -5129,6 +5121,7 @@ t_stat sim_instr (void) {
case 0xbb: /* OTDR */
tStates -= 5;
temp = HIGH_REGISTER(BC);
if (temp == 0) temp = 0x100;
do {
tStates += 21;
CHECK_BREAK_BYTE(HL);
@ -6061,6 +6054,27 @@ t_stat sim_instr (void) {
return reason;
}
static void checkROMBoundaries(void) {
uint32 temp;
if (ROMLow > ROMHigh) {
printf("ROMLOW [%04X] must be less than or equal to ROMHIGH [%04X]. Values exchanged.\n",
ROMLow, ROMHigh);
temp = ROMLow;
ROMLow = ROMHigh;
ROMHigh = temp;
}
if (cpu_unit.flags & UNIT_ALTAIRROM) {
if (DEFAULT_ROM_LOW < ROMLow) {
printf("ROMLOW [%04X] reset to %04X since Altair ROM was desired.\n", ROMLow, DEFAULT_ROM_LOW);
ROMLow = DEFAULT_ROM_LOW;
}
if (ROMHigh < DEFAULT_ROM_HIGH) {
printf("ROMHIGH [%04X] reset to %04X since Altair ROM was desired.\n", ROMHigh, DEFAULT_ROM_HIGH);
ROMHigh = DEFAULT_ROM_HIGH;
}
}
}
static void reset_memory(void) {
uint32 i, j;
checkROMBoundaries();
@ -6090,7 +6104,7 @@ static void reset_memory(void) {
isProtected = FALSE;
}
void printROMMessage(const uint32 cntROM) {
static void printROMMessage(const uint32 cntROM) {
if (cntROM) {
printf("Warning: %d bytes written to ROM [%04X - %04X].\n", cntROM, ROMLow, ROMHigh);
}
@ -6124,27 +6138,6 @@ t_stat cpu_reset(DEVICE *dptr) {
return SCPE_OK;
}
static void checkROMBoundaries(void) {
uint32 temp;
if (ROMLow > ROMHigh) {
printf("ROMLOW [%04X] must be less than or equal to ROMHIGH [%04X]. Values exchanged.\n",
ROMLow, ROMHigh);
temp = ROMLow;
ROMLow = ROMHigh;
ROMHigh = temp;
}
if (cpu_unit.flags & UNIT_ALTAIRROM) {
if (DEFAULT_ROM_LOW < ROMLow) {
printf("ROMLOW [%04X] reset to %04X since Altair ROM was desired.\n", ROMLow, DEFAULT_ROM_LOW);
ROMLow = DEFAULT_ROM_LOW;
}
if (ROMHigh < DEFAULT_ROM_HIGH) {
printf("ROMHIGH [%04X] reset to %04X since Altair ROM was desired.\n", ROMHigh, DEFAULT_ROM_HIGH);
ROMHigh = DEFAULT_ROM_HIGH;
}
}
}
static t_stat cpu_set_rom(UNIT *uptr, int32 value, char *cptr, void *desc) {
checkROMBoundaries();
return SCPE_OK;

View file

@ -14,7 +14,7 @@
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
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
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.

View file

@ -14,7 +14,7 @@
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
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
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.
@ -110,8 +110,8 @@
#include "altairz80_defs.h"
#define UNIT_V_DSKWLK (UNIT_V_UF + 0) /* write locked */
#define UNIT_DSKWLK (1 << UNIT_V_DSKWLK)
#define UNIT_V_DSK_WLK (UNIT_V_UF + 0) /* write locked */
#define UNIT_DSK_WLK (1 << UNIT_V_DSK_WLK)
#define UNIT_V_DSK_VERBOSE (UNIT_V_UF + 1) /* verbose mode, i.e. show error messages */
#define UNIT_DSK_VERBOSE (1 << UNIT_V_DSK_VERBOSE)
#define DSK_SECTSIZE 137 /* size of sector */
@ -129,18 +129,12 @@
int32 dsk10(const int32 port, const int32 io, const int32 data);
int32 dsk11(const int32 port, const int32 io, const int32 data);
int32 dsk12(const int32 port, const int32 io, const int32 data);
static int32 dskseek(const UNIT *xptr);
static t_stat dsk_boot(int32 unitno, DEVICE *dptr);
static t_stat dsk_reset(DEVICE *dptr);
static void writebuf(void);
static t_stat dsk_set_verbose(UNIT *uptr, int32 value, char *cptr, void *desc);
static void resetDSKWarningFlags(void);
static int32 hasVerbose(void);
static char* selectInOut(const int32 io);
extern int32 PCX;
extern int32 saved_PC;
extern FILE *sim_log;
extern char messageBuffer[];
extern UNIT cpu_unit;
@ -149,8 +143,9 @@ extern int32 install_bootrom(void);
/* global data on status */
static int32 current_disk = NUM_OF_DSK; /* currently selected drive (values are 0 .. NUM_OF_DSK)
current_disk < NUM_OF_DSK implies that the corresponding disk is attached to a file */
/* currently selected drive (values are 0 .. NUM_OF_DSK)
current_disk < NUM_OF_DSK implies that the corresponding disk is attached to a file */
static int32 current_disk = NUM_OF_DSK;
static int32 current_track [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0};
static int32 current_sector [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0};
static int32 current_byte [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0};
@ -240,12 +235,12 @@ static REG dsk_reg[] = {
};
static MTAB dsk_mod[] = {
{ UNIT_DSKWLK, 0, "write enabled", "WRITEENABLED", NULL },
{ UNIT_DSKWLK, UNIT_DSKWLK, "write locked", "LOCKED", NULL },
/* quiet, no warning messages */
{ UNIT_DSK_VERBOSE, 0, "QUIET", "QUIET", NULL },
{ UNIT_DSK_WLK, 0, "WRTENB", "WRTENB", NULL },
{ UNIT_DSK_WLK, UNIT_DSK_WLK, "WRTLCK", "WRTLCK", NULL },
/* quiet, no warning messages */
{ UNIT_DSK_VERBOSE, 0, "QUIET", "QUIET", NULL },
/* verbose, show warning messages */
{ UNIT_DSK_VERBOSE, UNIT_DSK_VERBOSE, "VERBOSE", "VERBOSE", &dsk_set_verbose },
{ UNIT_DSK_VERBOSE, UNIT_DSK_VERBOSE, "VERBOSE", "VERBOSE", &dsk_set_verbose },
{ 0 }
};
@ -306,23 +301,57 @@ static t_stat dsk_reset(DEVICE *dptr) {
*/
static t_stat dsk_boot(int32 unitno, DEVICE *dptr) {
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 */
if ((bootrom[UNIT_NO_OFFSET_1 - 1] == LDA_INSTRUCTION) && (bootrom[UNIT_NO_OFFSET_2 - 1] == LDA_INSTRUCTION)) {
bootrom[UNIT_NO_OFFSET_1] = unitno & 0xff; /* LD A,<unitno> */
bootrom[UNIT_NO_OFFSET_1] = unitno & 0xff; /* LD A,<unitno> */
bootrom[UNIT_NO_OFFSET_2] = 0x80 | (unitno & 0xff); /* LD a,80h | <unitno> */
}
else { /* Attempt to modify non LD A,<> instructions is refused. */
printf("Incorrect boot ROM offsets detected.\n");
return SCPE_IERR;
}
install_bootrom(); /* install modified ROM */
}
saved_PC = DEFAULT_ROM_LOW;
return SCPE_OK;
}
static int32 dskseek(const UNIT *xptr) {
return fseek(xptr -> fileref, DSK_TRACSIZE * current_track[current_disk] +
DSK_SECTSIZE * current_sector[current_disk], SEEK_SET);
}
/* precondition: current_disk < NUM_OF_DSK */
static void writebuf(void) {
int32 i, rtn;
UNIT *uptr;
i = current_byte[current_disk]; /* null-fill rest of sector if any */
while (i < DSK_SECTSIZE) {
dskbuf[i++] = 0;
}
uptr = dsk_dev.units + current_disk;
if (((uptr -> flags) & UNIT_DSK_WLK) == 0) { /* write enabled */
if (trace_flag & TRACE_READ_WRITE) {
MESSAGE_4("OUT 0x0a (WRITE) D%d T%d S%d", current_disk, current_track[current_disk], current_sector[current_disk]);
}
if (dskseek(uptr)) {
MESSAGE_4("fseek failed D%d T%d S%d", current_disk, current_track[current_disk], current_sector[current_disk]);
}
rtn = fwrite(dskbuf, DSK_SECTSIZE, 1, uptr -> fileref);
if (rtn != 1) {
MESSAGE_4("fwrite failed T%d S%d Return=%d", current_track[current_disk], current_sector[current_disk], rtn);
}
}
else if ( ((uptr -> flags) & UNIT_DSK_VERBOSE) && (warnLock[current_disk] < warnLevelDSK) ) {
/* write locked - print warning message if required */
warnLock[current_disk]++;
/*05*/ MESSAGE_2("Attempt to write to locked DSK%d - ignored.", current_disk);
}
current_flag[current_disk] &= 0xfe; /* ENWD off */
current_byte[current_disk] = 0xff;
dirty = FALSE;
}
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
@ -487,11 +516,6 @@ int32 dsk11(const int32 port, const int32 io, const int32 data) {
/* Disk Data In/Out */
static int32 dskseek(const UNIT *xptr) {
return fseek(xptr -> fileref, DSK_TRACSIZE * current_track[current_disk] +
DSK_SECTSIZE * current_sector[current_disk], SEEK_SET);
}
int32 dsk12(const int32 port, const int32 io, const int32 data) {
int32 i;
UNIT *uptr;
@ -533,34 +557,3 @@ int32 dsk12(const int32 port, const int32 io, const int32 data) {
return 0; /* ignored since OUT */
}
}
/* precondition: current_disk < NUM_OF_DSK */
static void writebuf(void) {
int32 i, rtn;
UNIT *uptr;
i = current_byte[current_disk]; /* null-fill rest of sector if any */
while (i < DSK_SECTSIZE) {
dskbuf[i++] = 0;
}
uptr = dsk_dev.units + current_disk;
if (((uptr -> flags) & UNIT_DSKWLK) == 0) { /* write enabled */
if (trace_flag & TRACE_READ_WRITE) {
MESSAGE_4("OUT 0x0a (WRITE) D%d T%d S%d", current_disk, current_track[current_disk], current_sector[current_disk]);
}
if (dskseek(uptr)) {
MESSAGE_4("fseek failed D%d T%d S%d", current_disk, current_track[current_disk], current_sector[current_disk]);
}
rtn = fwrite(dskbuf, DSK_SECTSIZE, 1, uptr -> fileref);
if (rtn != 1) {
MESSAGE_4("fwrite failed T%d S%d Return=%d", current_track[current_disk], current_sector[current_disk], rtn);
}
}
else if ( ((uptr -> flags) & UNIT_DSK_VERBOSE) && (warnLock[current_disk] < warnLevelDSK) ) {
/* write locked - print warning message if required */
warnLock[current_disk]++;
/*05*/ MESSAGE_2("Attempt to write to locked DSK%d - ignored.", current_disk);
}
current_flag[current_disk] &= 0xfe; /* ENWD off */
current_byte[current_disk] = 0xff;
dirty = FALSE;
}

View file

@ -14,7 +14,7 @@
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
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
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.
@ -91,7 +91,6 @@
#define CONTROLG_CHAR 0x07 /* control G char., rings bell when displayed */
#define CONTROLZ_CHAR 0x1a /* control Z character */
static void resetSIOWarningFlags(void);
static t_stat sio_set_verbose (UNIT *uptr, int32 value, char *cptr, void *desc);
static t_stat simh_dev_set_timeron (UNIT *uptr, int32 value, char *cptr, void *desc);
static t_stat simh_dev_set_timeroff (UNIT *uptr, int32 value, char *cptr, void *desc);
@ -100,6 +99,8 @@ static t_stat sio_attach(UNIT *uptr, char *cptr);
static t_stat sio_detach(UNIT *uptr);
static t_stat ptr_reset(DEVICE *dptr);
static t_stat ptp_reset(DEVICE *dptr);
static t_stat simh_dev_reset(DEVICE *dptr);
static t_stat simh_svc(UNIT *uptr);
int32 nulldev (const int32 port, const int32 io, const int32 data);
int32 sr_dev (const int32 port, const int32 io, const int32 data);
int32 simh_dev (const int32 port, const int32 io, const int32 data);
@ -107,21 +108,7 @@ int32 sio0d (const int32 port, const int32 io, const int32 data);
int32 sio0s (const int32 port, const int32 io, const int32 data);
int32 sio1d (const int32 port, const int32 io, const int32 data);
int32 sio1s (const int32 port, const int32 io, const int32 data);
static int32 mapCharacter(int32 ch);
static void pollConnection(void);
static t_stat simh_dev_reset(DEVICE *dptr);
static t_stat simh_svc(UNIT *uptr);
static int32 simh_in(const int32 port);
static int32 simh_out(const int32 port, const int32 data);
static void createCPMCommandLine(void);
static void attachCPM(UNIT *uptr);
static void setClockZSDOS(void);
static void setClockCPM3(void);
static time_t mkCPM3Origin(void);
static int32 toBCD(const int32 x);
static int32 fromBCD(const int32 x);
void printMessage(void);
static void warnNoRealTimeClock(void);
extern int32 getBankSelect(void);
extern void setBankSelect(const int32 b);
@ -352,7 +339,7 @@ DEVICE simh_device = {
NULL, NULL, NULL
};
char messageBuffer[256];
char messageBuffer[256] = {};
void printMessage(void) {
printf(messageBuffer);
@ -1092,7 +1079,7 @@ static int32 simh_out(const int32 port, const int32 data) {
hFind = FindFirstFile(cpmCommandLine, &FindFileData);
if (hFind == INVALID_HANDLE_VALUE) {
if (simh_unit.flags & UNIT_SIMH_VERBOSE) {
MESSAGE_3("Cannot expand '%s'. Error is %u.", cpmCommandLine, GetLastError());
MESSAGE_3("Cannot expand '%s'. Error is %lu.", cpmCommandLine, GetLastError());
}
globValid = FALSE;
}

View file

@ -14,7 +14,7 @@
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
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
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.
@ -30,28 +30,19 @@
#include <ctype.h>
#include "altairz80_defs.h"
extern DEVICE cpu_dev;
extern DEVICE dsk_dev;
extern DEVICE hdsk_dev;
extern UNIT cpu_unit;
extern REG cpu_reg[];
extern DEVICE cpu_dev;
extern DEVICE sio_dev;
extern DEVICE simh_device;
extern DEVICE ptr_dev;
extern DEVICE ptp_dev;
extern DEVICE dsk_dev;
extern DEVICE hdsk_dev;
extern DEVICE net_dev;
extern int32 saved_PC;
int32 fprint_sym(FILE *of, int32 addr, uint32 *val, UNIT *uptr, int32 sw);
static int32 checkbase(char ch, const char *numString);
static int32 numok(char ch, const char **numString, const int32 minvalue,
const int32 maxvalue, const int32 requireSign, int32 *result);
static int32 match(const char *pattern, const char *input, char *xyFirst, char *xy, int32 *number, int32 *star, int32 *at,
int32 *hat, int32 *dollar);
static int32 parse_X80(const char *cptr, const int32 addr, uint32 *val, char *const Mnemonics[]);
int32 parse_sym(char *cptr, int32 addr, UNIT *uptr, uint32 *val, int32 sw);
static int32 DAsm(char *S, const uint32 *val, const int32 useZ80Mnemonics, const int32 addr);
static int32 checkXY(const char xy);
/* SCP data structures
sim_name simulator name string
@ -59,13 +50,12 @@ static int32 checkXY(const char xy);
sim_emax number of words needed for examine
sim_devices array of pointers to simulated devices
sim_stop_messages array of pointers to stop messages
sim_load binary loader
*/
char sim_name[] = "Altair 8800 (Z80)";
REG *sim_PC = &cpu_reg[0];
int32 sim_emax = 4;
DEVICE *sim_devices[] = {
char sim_name[] = "Altair 8800 (Z80)";
REG *sim_PC = &cpu_reg[0];
int32 sim_emax = 4;
DEVICE *sim_devices[] = {
&cpu_dev, &sio_dev, &simh_device, &ptr_dev, &ptp_dev, &dsk_dev, &hdsk_dev, &net_dev, NULL
};
@ -366,7 +356,7 @@ static int32 DAsm(char *S, const uint32 *val, const int32 useZ80Mnemonics, const
}
}
if( (P = strchr(R, '*')) ) {
if ( (P = strchr(R, '*')) ) {
strncpy(S, R, P - R);
S[P - R] = '\0';
sprintf(H, "%02X", val[B++]);
@ -376,7 +366,7 @@ static int32 DAsm(char *S, const uint32 *val, const int32 useZ80Mnemonics, const
else if ( (P = strchr(R, '@')) ) {
strncpy(S, R, P - R);
S[P - R] = '\0';
if(!J) {
if (!J) {
Offset = val[B++];
}
strcat(S, Offset & 0x80 ? "-" : "+");

View file

@ -14,7 +14,7 @@
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
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
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.
@ -27,22 +27,23 @@
*/
#include "altairz80_defs.h"
#include <assert.h>
/* the following routines provided courtesy of Howard M. Harte */
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 set_format (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat show_format (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat hdsk_attach (UNIT *uptr, char *cptr);
/* 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 show_geom(FILE *st, UNIT *uptr, int32 val, 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 hdsk_attach(UNIT *uptr, char *cptr);
#define UNIT_V_HDSKWLK (UNIT_V_UF + 0) /* write locked */
#define UNIT_HDSKWLK (1 << UNIT_V_HDSKWLK)
#define UNIT_V_HDSK_WLK (UNIT_V_UF + 0) /* write locked */
#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_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_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_CAPACITY (2048*32*128) /* Default Altair HDSK Capacity */
#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_PARAM 4
#define HDSK_BOOT_ADDRESS 0x5c00
#define DPB_NAME_LENGTH 15
extern char messageBuffer[];
extern int32 PCX;
extern UNIT cpu_unit;
extern uint8 M[MAXMEMSIZE][MAXBANKS];
extern int32 saved_PC;
extern int32 install_bootrom(void);
@ -71,14 +72,7 @@ extern uint8 GetBYTEWrapper(const uint32 Addr);
extern int32 bootrom[BOOTROM_SIZE];
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);
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 hdskCommandPosition = 0;
@ -87,31 +81,33 @@ static int32 selectedDisk;
static int32 selectedSector;
static int32 selectedTrack;
static int32 selectedDMA;
static int32 hdskTrace;
static int32 hdskTrace = FALSE;
typedef struct {
char name[16];
t_addr capac;
uint16 spt;
uint8 bsh;
uint8 blm;
uint8 exm;
uint16 dsm;
uint16 drm;
uint8 al0;
uint8 al1;
uint16 cks;
uint16 off;
uint8 psh;
uint8 phm;
char name[DPB_NAME_LENGTH + 1]; /* name of CP/M disk parameter block */
t_addr capac; /* capacity */
uint16 spt; /* sectors per track */
uint8 bsh; /* data allocation block shift factor */
uint8 blm; /* data allocation block mask */
uint8 exm; /* extent mask */
uint16 dsm; /* maximum data block number */
uint16 drm; /* total number of directory entries */
uint8 al0; /* determine reserved directory blocks */
uint8 al1; /* determine reserved directory blocks */
uint16 cks; /* size of directory check vector */
uint16 off; /* number of reserved tracks */
uint8 psh; /* physical record shift factor, CP/M 3 */
uint8 phm; /* physical record mask, CP/M 3 */
} 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[] = {
/* 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 */
{ "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 */
{ "SU720", 737280, 36, 0x04, 0x0F, 0x00, 354, 0x007E, 0xC0, 0x00, 0x0020, 0x0002, 0x02, 0x03 }, /* 720K Super I/O */
/* 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, 0x0000, 0x0006, 0x00, 0x00 }, /* AZ80 HDSK */
{ "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 */
{ "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 }
};
@ -139,12 +135,12 @@ static REG hdsk_reg[] = {
static MTAB hdsk_mod[] = {
{ MTAB_XTD|MTAB_VUN|MTAB_VAL, 0, "FORMAT", "FORMAT", &set_format, &show_format, NULL },
{ UNIT_HDSKWLK, 0, "WRTENB", "WRTENB", NULL },
{ UNIT_HDSKWLK, UNIT_HDSKWLK, "WRTLCK", "WRTLCK", NULL },
{ UNIT_HDSK_WLK, 0, "WRTENB", "WRTENB", NULL },
{ UNIT_HDSK_WLK, UNIT_HDSK_WLK, "WRTLCK", "WRTLCK", NULL },
/* quiet, no warning messages */
{ UNIT_HDSK_VERBOSE, 0, "QUIET", "QUIET", NULL },
{ UNIT_HDSK_VERBOSE, 0, "QUIET", "QUIET", NULL },
/* 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 },
{ 0 }
};
@ -159,102 +155,117 @@ DEVICE hdsk_dev = {
};
/* Attach routine */
t_stat hdsk_attach (UNIT *uptr, char *cptr) {
uint32 flen;
t_stat hdsk_attach(UNIT *uptr, char *cptr) {
t_stat r;
int32 i;
char unitChar;
r = attach_unit (uptr, cptr); /* attach unit */
if (r != SCPE_OK) return r; /* error? */
if ((flen = sim_fsize (uptr->fileref)) == 0) { /* new disk image? */
if (uptr->flags & UNIT_RO) return SCPE_OK; /* if ro, done */
return SCPE_OK;
}
r = attach_unit(uptr, cptr); /* attach unit */
if ( r != SCPE_OK) /* error? */
return r;
if(flen>0) {
uptr->capac = flen;
/* Step 1: Determine capacity of this disk */
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 */
for(i=0; dpb[i].spt != 0; i++) {
if(dpb[i].capac == uptr->capac) {
uptr->HDSK_FORMAT_TYPE = i;
break;
}
/* Step 2: Determine format based on disk capacity */
uptr -> HDSK_FORMAT_TYPE = -1; /* default to unknown format type */
for (i = 0; dpb[i].capac != 0; i++) { /* find disk parameter block */
if (dpb[i].capac == uptr -> capac) { /* found if correct capacity */
uptr -> HDSK_FORMAT_TYPE = i;
break;
}
}
if(uptr->HDSK_FORMAT_TYPE == -1) {
uptr->HDSK_FORMAT_TYPE = 0;
uptr->capac = dpb[uptr->HDSK_FORMAT_TYPE].capac;
printf("HDSK: WARNING: Unsupported disk capacity, assuming HDSK type.\n");
uptr->flags |= UNIT_HDSKWLK;
printf("HDSK: WARNING: Forcing WRTLCK.\n");
if(uptr->capac != (uptr->HDSK_MAX_TRACKS * uptr->HDSK_SECTORS_PER_TRACK * uptr->HDSK_SECTOR_SIZE)) {
printf("HDSK: WARNING: Geometry may be incorrect.\n");
/* Step 3: Set number of sectors per track and sector size */
if (uptr -> HDSK_FORMAT_TYPE == -1) { /* Case 1: no disk parameter block found*/
for (i = 0; i < hdsk_dev.numunits; i++) /* find affected unit number */
if (&hdsk_unit[i] == uptr)
break; /* found */
unitChar = '0' + i;
uptr -> HDSK_FORMAT_TYPE = 0;
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);
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);
/* Step 4: Number of tracks is smallest number to accomodate capacity */
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);
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;
}
/* Set disk geometry routine */
t_stat set_geom (UNIT *uptr, int32 val, char *cptr, void *desc) {
DEVICE *dptr;
uint32 ncyl, nsect, ssize;
t_stat set_geom(UNIT *uptr, int32 val, char *cptr, void *desc) {
uint32 numberOfTracks, numberOfSectors, sectorSize;
int result, n;
if (cptr == NULL) return SCPE_ARG;
if (uptr == NULL) return SCPE_IERR;
dptr = find_dev_from_unit (uptr);
if (dptr == NULL) return SCPE_IERR;
sscanf(cptr, "%d/%d/%d", &ncyl, &nsect, &ssize);
uptr->HDSK_MAX_TRACKS = ncyl;
uptr->HDSK_SECTORS_PER_TRACK = nsect;
uptr->HDSK_SECTOR_SIZE = ssize;
result = sscanf(cptr, "%d/%d/%d%n", &numberOfTracks, &numberOfSectors, &sectorSize, &n);
if ((result != 3) || (result == EOF) || (cptr[n] != 0)) {
result = sscanf(cptr, "T:%d/N:%d/S:%d%n", &numberOfTracks, &numberOfSectors, &sectorSize, &n);
if ((result != 3) || (result == EOF) || (cptr[n] != 0)) return SCPE_ARG;
}
uptr -> HDSK_NUMBER_OF_TRACKS = numberOfTracks;
uptr -> HDSK_SECTORS_PER_TRACK = numberOfSectors;
uptr -> HDSK_SECTOR_SIZE = sectorSize;
uptr -> capac = numberOfTracks * numberOfSectors * sectorSize;
return SCPE_OK;
}
/* Show disk geometry routine */
t_stat show_geom (FILE *st, UNIT *uptr, int32 val, void *desc) {
DEVICE *dptr;
t_stat show_geom(FILE *st, UNIT *uptr, int32 val, void *desc) {
if (uptr == NULL) return SCPE_IERR;
dptr = find_dev_from_unit (uptr);
if (dptr == NULL) return SCPE_IERR;
fprintf (st, "T:%d/N:%d/S:%d", uptr->HDSK_MAX_TRACKS, uptr->HDSK_SECTORS_PER_TRACK, uptr->u5);
fprintf(st, "T:%d/N:%d/S:%d", uptr -> HDSK_NUMBER_OF_TRACKS,
uptr -> HDSK_SECTORS_PER_TRACK, uptr -> HDSK_SECTOR_SIZE);
return SCPE_OK;
}
#define QUOTE1(text) #text
#define QUOTE2(text) QUOTE1(text)
/* Set disk format routine */
t_stat set_format (UNIT *uptr, int32 val, char *cptr, void *desc) {
DEVICE *dptr;
char fmtname[16];
t_stat set_format(UNIT *uptr, int32 val, char *cptr, void *desc) {
char fmtname[DPB_NAME_LENGTH + 1];
int32 i;
if (cptr == NULL) return SCPE_ARG;
if (uptr == NULL) return SCPE_IERR;
dptr = find_dev_from_unit (uptr);
if (dptr == NULL) return SCPE_IERR;
sscanf(cptr, "%s", fmtname);
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 */
if (sscanf(cptr, "%" QUOTE2(DPB_NAME_LENGTH) "s", fmtname) == 0) return SCPE_ARG;
for (i = 0; dpb[i].capac != 0; i++) {
if (strncmp(fmtname, dpb[i].name, strlen(fmtname)) == 0) {
uptr -> HDSK_FORMAT_TYPE = i;
uptr -> capac = dpb[i].capac; /* Set capacity */
/* Configure physical disk geometry */
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_MAX_TRACKS = uptr->capac / (uptr->HDSK_SECTORS_PER_TRACK * uptr->HDSK_SECTOR_SIZE);
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_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;
}
@ -263,13 +274,9 @@ t_stat set_format (UNIT *uptr, int32 val, char *cptr, void *desc) {
}
/* Show disk format routine */
t_stat show_format (FILE *st, UNIT *uptr, int32 val, void *desc) {
DEVICE *dptr;
t_stat show_format(FILE *st, UNIT *uptr, int32 val, void *desc) {
if (uptr == NULL) return SCPE_IERR;
dptr = find_dev_from_unit (uptr);
if (dptr == NULL) return SCPE_IERR;
fprintf (st, "%s", dpb[uptr->HDSK_FORMAT_TYPE].name);
fprintf(st, "%s", dpb[uptr -> HDSK_FORMAT_TYPE].name);
return SCPE_OK;
}
@ -315,9 +322,6 @@ static t_stat hdsk_boot(int32 unitno, DEVICE *dptr) {
return SCPE_ARG;
}
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 */
if (bootrom[UNIT_NO_OFFSET_1 - 1] == LDA_INSTRUCTION) {
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");
return SCPE_IERR;
}
install_bootrom(); /* install modified ROM */
}
for (i = 0; i < BOOTROM_SIZE; i++) {
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) {
int32 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;
}
}
@ -398,7 +403,7 @@ static int32 hdsk_hasVerbose(void) {
/* check the parameters and return TRUE iff parameters are correct or have been repaired */
static int32 checkParameters(void) {
UNIT *uptr = hdsk_dev.units + selectedDisk;
UNIT *uptr = &hdsk_dev.units[selectedDisk];
int32 currentFlag;
if ((selectedDisk < 0) || (selectedDisk >= HDSK_NUMBER)) {
if (hdsk_hasVerbose()) {
@ -406,24 +411,24 @@ static int32 checkParameters(void) {
}
selectedDisk = 0;
}
currentFlag = (hdsk_dev.units + selectedDisk) -> flags;
currentFlag = hdsk_dev.units[selectedDisk].flags;
if ((currentFlag & UNIT_ATT) == 0) {
if (currentFlag & UNIT_HDSK_VERBOSE) {
MESSAGE_2("HDSK%d is not attached.", selectedDisk);
}
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) {
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;
}
if ((selectedTrack < 0) || (selectedTrack >= uptr->HDSK_MAX_TRACKS)) {
if ((selectedTrack < 0) || (selectedTrack >= uptr -> HDSK_NUMBER_OF_TRACKS)) {
if (currentFlag & UNIT_HDSK_VERBOSE) {
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;
}
@ -431,15 +436,16 @@ static int32 checkParameters(void) {
if (hdskTrace) {
MESSAGE_7("%s HDSK%d Track=%04d Sector=%02d Len=%04d DMA=%04x\n",
(hdskLastCommand == HDSK_READ) ? "Read" : "Write",
selectedDisk, selectedTrack, selectedSector, uptr->HDSK_SECTOR_SIZE, selectedDMA);
selectedDisk, selectedTrack, selectedSector, uptr -> HDSK_SECTOR_SIZE, selectedDMA);
}
return TRUE;
}
static int32 doSeek(void) {
UNIT *uptr = hdsk_dev.units + selectedDisk;
UNIT *uptr = &hdsk_dev.units[selectedDisk];
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) {
MESSAGE_4("Could not access HDSK%d Sector=%02d Track=%04d.",
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) {
int32 i;
UNIT *uptr = hdsk_dev.units + selectedDisk;
UNIT *uptr = &hdsk_dev.units[selectedDisk];
if (doSeek()) {
return CPM_ERROR;
}
if (fread(hdskbuf, uptr->HDSK_SECTOR_SIZE, 1, uptr -> fileref) != 1) {
for (i = 0; i < uptr->HDSK_SECTOR_SIZE; i++) {
if (fread(hdskbuf, uptr -> HDSK_SECTOR_SIZE, 1, uptr -> fileref) != 1) {
for (i = 0; i < uptr -> HDSK_SECTOR_SIZE; i++) {
hdskbuf[i] = CPM_EMPTY;
}
if ((uptr -> flags) & UNIT_HDSK_VERBOSE) {
@ -470,7 +476,7 @@ static int32 doRead(void) {
}
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]);
}
return CPM_OK;
@ -479,15 +485,15 @@ static int32 doRead(void) {
static int32 doWrite(void) {
int32 i;
UNIT *uptr = hdsk_dev.units + selectedDisk;
if (((uptr -> flags) & UNIT_HDSKWLK) == 0) { /* write enabled */
UNIT *uptr = &hdsk_dev.units[selectedDisk];
if (((uptr -> flags) & UNIT_HDSK_WLK) == 0) { /* write enabled */
if (doSeek()) {
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);
}
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) {
MESSAGE_4("Could not write HDSK%d Sector=%02d Track=%04d.",
selectedDisk, selectedSector, selectedTrack);
@ -506,7 +512,7 @@ static int32 doWrite(void) {
}
static int32 hdsk_in(const int32 port) {
UNIT *uptr = hdsk_dev.units + selectedDisk;
UNIT *uptr = &hdsk_dev.units[selectedDisk];
int32 result;
if ((hdskCommandPosition == 6) && ((hdskLastCommand == HDSK_READ) || (hdskLastCommand == HDSK_WRITE))) {
@ -515,7 +521,7 @@ static int32 hdsk_in(const int32 port) {
hdskCommandPosition = 0;
return result;
} else if (hdskLastCommand == HDSK_PARAM) {
DPB current = dpb[uptr->HDSK_FORMAT_TYPE];
DPB current = dpb[uptr -> HDSK_FORMAT_TYPE];
uint8 params[17];
params[ 0] = current.spt & 0xff; params[ 1] = (current.spt >> 8) & 0xff;
params[ 2] = current.bsh;
@ -535,9 +541,9 @@ static int32 hdsk_in(const int32 port) {
if (paramcount <= 17)
return params[paramcount - 1];
else if (paramcount == 18)
return (uptr->HDSK_SECTOR_SIZE & 0xff);
return (uptr -> HDSK_SECTOR_SIZE & 0xff);
else if (paramcount == 19)
return (uptr->HDSK_SECTOR_SIZE >> 8);
return (uptr -> HDSK_SECTOR_SIZE >> 8);
else
MESSAGE_2("HDSK%d Get parameter error.", selectedDisk);

View file

@ -14,7 +14,7 @@
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
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
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.

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
cpu GRI-909 CPU
28-Apr-07 RMS Removed clock initialization
22-Sep-05 RMS Fixed declarations (from Sterling Garwood)
18-Jul-04 RMS Fixed missing ao_update calls in AX, AY write
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;
t_stat reason;
extern UNIT rtc_unit;
/* Restore register state */
SC = SC & AMASK; /* load local PC */
reason = 0;
ao_update (); /* update AO */
sim_rtc_init (rtc_unit.wait); /* init calibration */
/* Main instruction fetch/decode loop */

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
cpu H316/H516 CPU
28-Apr-07 RMS Removed clock initialization
03-Apr-06 RMS Fixed bugs in LLL, LRL (from Theo Engel)
22-Sep-05 RMS Fixed declarations (from Sterling Garwood)
16-Aug-05 RMS Fixed C++ declaration and cast problems
@ -370,7 +371,6 @@ DEVICE cpu_dev = {
t_stat sim_instr (void)
{
extern UNIT clk_unit;
int32 AR, BR, MB, Y, t1, t2, t3, skip, dev;
uint32 ut;
t_stat reason;
@ -399,7 +399,6 @@ BR = saved_BR & DMASK;
XR = saved_XR & DMASK;
PC = PC & ((cpu_unit.flags & UNIT_EXT)? X_AMASK: NX_AMASK); /* mask PC */
reason = 0;
sim_rtc_init (clk_unit.wait); /* init calibration */
/* Main instruction fetch/decode loop */

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
lpt line printer
19-Jan-06 RMS Added UNIT_TEXT flag
03-Apr-06 RMS Fixed bug in blanks backscanning (from Theo Engel)
01-Dec-04 RMS Fixed bug in 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 };
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[] = {
{ DRDATA (WDPOS, lpt_wdpos, 6) },

View file

@ -28,6 +28,8 @@
DMA0,DMA1 12607B/12578A/12895A direct memory access 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
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
@ -378,7 +380,6 @@
#define UNIT_MP_INT (1 << UNIT_V_MP_INT)
#define UNIT_MP_SEL1 (1 << UNIT_V_MP_SEL1)
#define ABORT(val) longjmp (save_env, (val))
#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_uig_0 (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);
/* 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 */
}
}
sim_rtc_init (clk_delay (0)); /* recalibrate clock */
/* Configure interrupt deferral table */
@ -2023,7 +2021,7 @@ return dat;
- STC requested but not CLC: issue STC,C
- CLC requested but not STC: issue CLC,C
- 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)
@ -2101,7 +2099,7 @@ else {
} /* end output */
setFLG (DMA0 + ch); /* set DMA flg */
clrCMD (DMA0 + ch); /* clr DMA cmd */
devdisp (dev, ioEDT, dev, 0); /* do EDT */
devdisp (dev, ioEDT, dev, inp | ch); /* do EDT */
}
return;
}

View file

@ -1,6 +1,6 @@
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.
@ -62,8 +62,8 @@ The results of the diagnostic runs are summarized below:
103122 59310 Interface Bus Interface 1728 - No simulation
103003 12587 Asynchronous Data Set Interface 1553 - No simulation
103110 12920 Asynchronous Multiplexer (Data) 1805 - Not tested
103011 12920 Asynchronous Multiplexer (Cntl) 1444 - Not tested
103110 12920 Asynchronous Multiplexer (Data) 1805 3.7-1 Passed
103011 12920 Asynchronous Multiplexer (Cntl) 1444 3.7-1 Passed
103012 12621 Synchronous Data Set (Receive) 1532 - No simulation
103013 12621 Synchronous Data Set (Send) 1532 - No simulation
103116 12967 Synchronous Interface 1438 - No simulation
@ -114,11 +114,11 @@ not supported by the 24396 suite:
Paper Tape Date SIMH
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
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
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)
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)
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
--------------------------------------------

View file

@ -1,6 +1,6 @@
/* 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
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
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
07-Oct-04 JDB Fixed enable/disable from either device
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)
09-May-03 RMS Added network device flag
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"
@ -52,9 +68,17 @@
#define DSOCKET u3 /* data 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 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2], dev_srq[2];
extern FILE *sim_log;
extern FILE *sim_deb;
int32 ipl_edtdelay = 1; /* EDT delay (msec) */
int32 ipl_ptime = 31; /* polling interval */
int32 ipl_stopioe = 0; /* stop on error */
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_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_dev IPLI device descriptor
@ -125,7 +157,8 @@ DEVICE ipli_dev = {
1, 10, 31, 1, 16, 16,
&tmxr_ex, &tmxr_dep, &ipl_reset,
&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
@ -154,7 +187,8 @@ DEVICE iplo_dev = {
1, 10, 31, 1, 16, 16,
&tmxr_ex, &tmxr_dep, &ipl_reset,
&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 */
@ -169,12 +203,61 @@ int32 iploio (int32 inst, int32 IR, int32 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)
{
uint32 u, dev, odev;
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 */
switch (inst) { /* case on opcode */
@ -192,25 +275,42 @@ switch (inst) { /* case on opcode */
case ioOTX: /* output */
uptr->OBUF = dat;
if (DEBUG_PRJ (dbdev, DEB_CPU))
fprintf (sim_deb, ">>IPL%c OTx: %s = %06o\n", uc, iotype[u], dat);
break;
case ioLIX: /* load */
dat = uptr->IBUF; /* return val */
break;
dat = 0;
case ioMIX: /* merge */
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;
case ioCRS: /* control reset (action unverif) */
case ioCTL: /* control clear/set */
if (IR & I_CTL) { /* CLC */
clrCMD (dev); /* clear ctl, cmd */
clrCTL (dev);
if (DEBUG_PRJ (dbdev, DEB_CMDS))
fprintf (sim_deb, ">>IPL%c CLC: Command cleared\n", uc);
}
else { /* STC */
setCMD (dev); /* set ctl, cmd */
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_ESTB) == 0) { /* established? */
if (!ipl_check_conn (uptr)) /* not established? */
@ -220,6 +320,12 @@ switch (inst) { /* case on opcode */
msg[0] = (uptr->OBUF >> 8) & 0377;
msg[1] = uptr->OBUF & 0377;
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) {
printf ("IPL: socket write error\n");
return SCPE_IOERR;
@ -236,6 +342,16 @@ switch (inst) { /* case on opcode */
}
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:
break;
}
@ -249,7 +365,8 @@ return dat;
t_stat ipl_svc (UNIT *uptr)
{
int32 u, nb, dev;
char msg[2];
char msg[2], uc;
DEVICE *dbdev; /* device ptr for debug */
u = uptr - ipl_unit; /* get link number */
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 */
clrCMD (dev); /* clr cmd, set flag */
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;
}
@ -524,4 +649,3 @@ M[PC + IPL_DEVA] = devi;
M[PC + PTR_DEVA] = devp;
return SCPE_OK;
}

View file

@ -26,6 +26,7 @@
lps 12653A 2767 line printer
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)
Added ioCRS state to I/O decoders
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 };
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[] = {

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
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)
19-Nov-04 JDB Added restart when set online, etc.
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 };
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[] = {

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,7 +25,19 @@
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
22-Nov-05 RMS Revised for new terminal processing routines
29-Jun-05 RMS Added SET MUXLn DISCONNECT
@ -60,7 +72,9 @@
#define MUX_LINES 16 /* user lines */
#define MUX_ILINES 5 /* diag rcv only */
#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_DIAG (1 << UNIT_V_DIAG)
#define MUXU_INIT_POLL 8000
#define MUXL_WAIT 500
@ -85,7 +99,8 @@
#define OTL_V_BAUD 0 /* baud rate */
#define OTL_M_BAUD 0377
#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 */
@ -112,6 +127,7 @@
#define OTC_EC1 0000100
#define OTC_C2 0000040 /* Cn flops */
#define OTC_C1 0000020
#define OTC_V_C 4 /* S1 to C1 */
#define OTC_ES2 0000010 /* enb comparison */
#define OTC_ES1 0000004
#define OTC_V_ES 2
@ -139,14 +155,21 @@
((muxc_ota[ch] & (OTC_ES2|OTC_ES1)) >> OTC_V_ES)) \
<< 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 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_xpar[MUX_LINES]; /* xmt param */
uint8 mux_rbuf[MUX_LINES + MUX_ILINES]; /* rcv buf */
uint8 mux_xbuf[MUX_LINES]; /* xmt buf */
uint16 mux_rbuf[MUX_LINES + MUX_ILINES]; /* rcv buf */
uint16 mux_xbuf[MUX_LINES]; /* xmt buf */
uint8 mux_rchp[MUX_LINES + MUX_ILINES]; /* rcv chr pend */
uint8 mux_xdon[MUX_LINES]; /* xmt done */
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 mux_attach (UNIT *uptr, char *cptr);
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_show (FILE *st, UNIT *uptr, int32 val, void *desc);
void mux_data_int (void);
@ -179,24 +203,33 @@ void mux_diag (int32 c);
static uint8 odd_par[256] = {
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, 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, /* 020-037 */
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 */
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, /* 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, 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, /* 160-177 */
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, /* 240-257 */
0, 1, 1, 0, 1, 0, 1, 0, 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, /* 240-267 */
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 */
0, 1, 1, 0, 1, 0, 1, 0, 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, /* 320-337 */
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 */
};
#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[] = {
{ MUXL, 0, 0, 0, 0, 0, &muxlio },
@ -229,6 +262,8 @@ REG muxu_reg[] = {
};
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 },
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 1, "CONNECTIONS", NULL,
NULL, &mux_show, NULL },
@ -246,7 +281,8 @@ DEVICE muxu_dev = {
1, 10, 31, 1, 8, 8,
&tmxr_ex, &tmxr_dep, &muxc_reset,
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
@ -301,11 +337,11 @@ REG muxl_reg[] = {
{ FLDATA (FLG, muxl_dib.flg, 0) },
{ FLDATA (FBF, muxl_dib.fbf, 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 (XPAR, mux_xpar, 8, 16, MUX_LINES) },
{ BRDATA (RBUF, mux_rbuf, 8, 8, MUX_LINES + MUX_ILINES) },
{ BRDATA (XBUF, mux_xbuf, 8, 8, MUX_LINES) },
{ BRDATA (RBUF, mux_rbuf, 8, 16, MUX_LINES + MUX_ILINES) },
{ BRDATA (XBUF, mux_xbuf, 8, 16, MUX_LINES) },
{ BRDATA (RCHP, mux_rchp, 8, 1, MUX_LINES + MUX_ILINES) },
{ BRDATA (XDON, mux_xdon, 8, 1, MUX_LINES) },
{ URDATA (TIME, muxl_unit[0].wait, 10, 24, 0,
@ -362,13 +398,25 @@ DEVICE muxc_dev = {
&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 dev, ln;
t_bool is_crs;
static uint32 crs_count = 0; /* cntr for crs repeat */
dev = IR & I_DEVMASK; /* get device no */
is_crs = FALSE;
switch (inst) { /* case on opcode */
case ioFLG: /* flag clear/set */
@ -385,37 +433,107 @@ switch (inst) { /* case on opcode */
case ioOTX: /* output */
muxl_obuf = dat; /* store data */
break;
case ioMIX: /* merge */
dat = dat | muxl_ibuf;
if (DEBUG_PRI (muxu_dev, DEB_CPU))
if (dat & OTL_P)
fprintf (sim_deb, ">>MUXl OTx: Parameter = %06o\n", dat);
else
fprintf (sim_deb, ">>MUXl OTx: Data = %06o\n", dat);
break;
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;
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 */
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 */
setCTL (dev); /* set ctl */
ln = MUX_CHAN (muxu_obuf); /* get chan # */
if (muxl_obuf & OTL_P) { /* parameter set? */
if (muxl_obuf & OTL_TX) { /* transmit? */
if (ln < MUX_LINES) /* to valid line? */
mux_xpar[ln] = muxl_obuf;
}
else if (ln < (MUX_LINES + MUX_ILINES)) /* rcv, valid line? */
mux_rpar[ln] = muxl_obuf;
}
else if ((muxl_obuf & OTL_TX) && /* xmit data? */
(ln < MUX_LINES)) { /* to valid line? */
if (sim_is_active (&muxl_unit[ln])) /* still working? */
mux_sta[ln] = mux_sta[ln] | LIU_LOST;
else sim_activate (&muxl_unit[ln], muxl_unit[ln].wait);
mux_xbuf[ln] = muxl_obuf & OTL_CHAR; /* load buffer */
if (muxl_obuf & OTL_TX) { /* transmit? */
if (ln < MUX_LINES) { /* line valid? */
if (muxl_obuf & OTL_P) { /* parameter? */
mux_xpar[ln] = muxl_obuf; /* store param value */
if (DEBUG_PRI (muxu_dev, DEB_CMDS))
fprintf (sim_deb,
">>MUXl STC: Transmit channel %d parameter %06o stored\n",
ln, muxl_obuf);
}
else { /* data */
if (mux_xpar[ln] & OTL_TPAR) /* parity requested? */
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 */
break;
@ -423,6 +541,16 @@ switch (inst) { /* case on opcode */
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 */
clrFSR (dev); /* clear flag */
mux_data_int (); /* look for new int */
@ -436,14 +564,19 @@ switch (inst) { /* case on opcode */
case ioOTX: /* output */
muxu_obuf = dat; /* store data */
break;
case ioMIX: /* merge */
dat = dat | muxu_ibuf;
if (DEBUG_PRI (muxu_dev, DEB_CPU))
fprintf (sim_deb, ">>MUXu OTx: Data channel = %d\n", MUX_CHAN(dat));
break;
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;
default:
@ -453,7 +586,12 @@ switch (inst) { /* case on opcode */
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)
{
@ -475,38 +613,65 @@ switch (inst) { /* case on opcode */
break;
case ioOTX: /* output */
ln = muxc_chan = OTC_CHAN (dat); /* set channel */
if (dat & OTC_SCAN) muxc_scan = 1; /* set scan flag */
else muxc_scan = 0;
if (dat & OTC_UPD) { /* update? */
ln = OTC_CHAN (dat); /* get channel */
old = muxc_ota[ln]; /* save prior val */
muxc_ota[ln] = (muxc_ota[ln] & ~OTC_RW) | /* save ESn,SSn */
(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_EC1) muxc_ota[ln] = /* if EC1, upd C1 */
(muxc_ota[ln] & ~OTC_C1) | (dat & OTC_C1);
if ((muxl_unit[ln].flags & UNIT_MDM) && /* modem ctrl? */
(old & DTR) && !(muxc_ota[ln] & DTR)) { /* DTR drop? */
muxc_ota[ln] = /* save ESn,SSn */
(muxc_ota[ln] & ~OTC_RW) | (dat & OTC_RW);
if (dat & OTC_EC2) /* if EC2, upd C2 */
muxc_ota[ln] =
(muxc_ota[ln] & ~OTC_C2) | (dat & OTC_C2);
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_reset_ln (&mux_ldsc[ln]); /* reset line */
muxc_lia[ln] = 0; /* dataset off */
}
} /* 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;
case ioLIX: /* load */
dat = 0;
case ioMIX: /* merge */
t = LIC_MBO | PUT_CCH (muxc_chan) | /* mbo, chan num */
LIC_TSTI (muxc_chan) | /* I2, I1 */
(muxc_ota[muxc_chan] & (OTC_ES2 | OTC_ES1)) | /* ES2, ES1 */
(muxc_lia[muxc_chan] & (LIC_S2 | LIC_S1)); /* S2, S1 */
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 */
break;
case ioCRS: /* control reset (action unverif) */
case ioCRS: /* control reset */
case ioCTL: /* ctrl clear/set */
if (IR & I_CTL) { clrCTL (dev); } /* CLC */
else { setCTL (dev); } /* STC */
@ -532,41 +697,70 @@ return dat;
t_stat muxi_svc (UNIT *uptr)
{
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 */
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? */
mux_sta[ln] = mux_sta[ln] | LIU_BRK;
mux_rbuf[ln] = 0; /* no char */
}
else { /* normal */
if (mux_rchp[ln]) mux_sta[ln] = mux_sta[ln] | LIU_LOST;
c = sim_tt_inpcvt (c, TT_GET_MODE (muxl_unit[ln].flags));
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 */
if (mux_rchp[ln]) /* char already pending? */
mux_sta[ln] = mux_sta[ln] | LIU_LOST;
if (!loopback) { /* terminal mode? */
c = sim_tt_inpcvt (c, TT_GET_MODE (muxl_unit[ln].flags));
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_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? */
} /* end if char */
} /* end if connected */
else muxc_lia[ln] = 0; /* disconnected */
else /* not connected */
if (!loopback) /* terminal mode? */
muxc_lia[ln] = 0; /* line disconnected */
} /* end for */
if (!FLG (muxl_dib.devno)) mux_data_int (); /* scan for data int */
if (!FLG (muxc_dib.devno)) mux_ctrl_int (); /* scan modem */
@ -577,33 +771,55 @@ return SCPE_OK;
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].xmte) { /* xmt enabled? */
if (loopback) /* diagnostic mode? */
mux_ldsc[ln].conn = 0; /* clear connection */
if ((mux_xbuf[ln] & OTL_SYNC) == 0) { /* start bit 0? */
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));
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 ((TT_GET_MODE (muxl_unit[ln].flags) != TT_MODE_8B) &&
/* (c != 0x7f) && (c != 0x13) && /* not del, ^S? */
/* (c != 0x11) && (c != 0x5)) /* not ^Q, ^E? */
if (c >= 0) /* valid? */
tmxr_putc_ln (lp, c); /* output char */
tmxr_poll_tx (&mux_desc); /* poll xmt */
if (mux_xpar[ln] & OTL_DIAG) /* xmt diagnose? */
mux_diag (fc); /* before munge */
if (loopback) { /* diagnostic mode? */
mux_ldsc[altln].conn = 1; /* set recv connection */
sim_activate (&muxu_unit, 1); /* schedule receive */
}
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 */
tmxr_poll_tx (&mux_desc); /* poll xmt */
sim_activate (uptr, muxl_unit[ln].wait); /* wait */
return SCPE_OK;
}
}
if (!FLG (muxl_dib.devno)) mux_data_int (); /* scan for int */
return SCPE_OK;
}
@ -616,31 +832,48 @@ int32 i;
for (i = 0; i < MUX_LINES; i++) { /* rcv lines */
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]);
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_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 */
return;
}
}
for (i = 0; i < MUX_LINES; i++) { /* xmt lines */
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_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 */
return;
}
}
for (i = MUX_LINES; i < (MUX_LINES + MUX_ILINES); i++) { /* diag lines */
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]);
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_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);
return;
}
@ -648,16 +881,31 @@ for (i = MUX_LINES; i < (MUX_LINES + MUX_ILINES); i++) { /* diag lines */
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)
{
int32 i;
int32 i, line_count;
if (muxc_scan == 0) return;
for (i = 0; i < MUX_LINES; i++) {
muxc_chan = (muxc_chan + 1) & LIC_M_CHAN; /* step channel */
line_count = (muxc_scan ? MUX_LINES : 1); /* check one or all lines */
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 (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 */
break;
}
@ -694,7 +942,8 @@ mux_rpar[i] = mux_xpar[i] = 0;
mux_rchp[i] = mux_xdon[i] = 0;
mux_sta[i] = 0;
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 */
(muxl_unit[i].flags & UNIT_MDM? CDET: 0);
sim_cancel (&muxl_unit[i]);
@ -733,7 +982,9 @@ if (muxu_unit.flags & UNIT_ATT) { /* master att? */
}
}
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;
}
@ -744,6 +995,9 @@ t_stat mux_attach (UNIT *uptr, char *cptr)
t_stat r;
int32 t;
if (muxu_unit.flags & UNIT_DIAG) /* diag mode? */
return SCPE_NOFNC; /* command not allowed */
r = tmxr_attach (&mux_desc, uptr, cptr); /* attach */
if (r != SCPE_OK) return r; /* error */
t = sim_rtcn_init (muxu_unit.wait, TMR_MUX);
@ -764,12 +1018,50 @@ sim_cancel (uptr); /* stop poll */
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 */
t_stat mux_summ (FILE *st, UNIT *uptr, int32 val, void *desc)
{
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);
if (t == 1) fprintf (st, "1 connection");
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;
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);
if (t) {
for (i = 0; i < MUX_LINES; i++) {
@ -794,4 +1089,3 @@ if (t) {
else fprintf (st, "all disconnected\n");
return SCPE_OK;
}

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -35,6 +35,7 @@
Cards are represented as ASCII text streams terminated by newlines.
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
30-Aug-05 RMS Fixed read, punch to ignore modifier on 1,4 char inst
(reported by Van Snyder)
@ -73,7 +74,7 @@ char colbin_to_bcd (uint32 cb);
*/
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[] = {
@ -102,7 +103,7 @@ DEVICE cdr_dev = {
*/
UNIT cdp_unit = {
UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0)
UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0)
};
REG cdp_reg[] = {
@ -134,11 +135,11 @@ DEVICE cdp_dev = {
*/
UNIT stack_unit[] = {
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) },
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) },
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) },
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0) },
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0) },
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0) },
{ 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[] = {
@ -179,10 +180,10 @@ fgets (rbuf, (cbn)? 2 * CBUFSIZE: CBUFSIZE, /* rd bin/char card */
cdr_unit.fileref);
if (feof (cdr_unit.fileref)) return STOP_NOCD; /* eof? */
if (ferror (cdr_unit.fileref)) { /* error? */
ind[IN_READ] = 1;
perror ("Card reader I/O error");
clearerr (cdr_unit.fileref);
if (iochk) return SCPE_IOERR;
ind[IN_READ] = 1;
return SCPE_OK;
}
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 */
fputs (rbuf, uptr->fileref); /* write card */
fputc ('\n', uptr->fileref); /* plus new line */
uptr->pos = ftell (uptr->fileref); /* update position */
if (ferror (uptr->fileref)) { /* error? */
perror ("Card stacker I/O error");
clearerr (uptr->fileref);
if (iochk) return SCPE_IOERR;
}
uptr->pos = ftell (uptr->fileref); /* update position */
return SCPE_OK;
}
@ -293,13 +294,13 @@ else { /* normal */
}
fputs (pbuf, uptr->fileref); /* output card */
fputc ('\n', uptr->fileref); /* plus new line */
uptr->pos = ftell (uptr->fileref); /* update position */
if (ferror (uptr->fileref)) { /* error? */
perror ("Card punch I/O error");
clearerr (uptr->fileref);
if (iochk) return SCPE_IOERR;
ind[IN_PNCH] = 1;
}
uptr->pos = ftell (uptr->fileref); /* update position */
return SCPE_OK;
}

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
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)
25-Apr-03 RMS Revised for extended file support
30-May-02 RMS Widened POS to 32b
@ -69,7 +70,7 @@ char *pch_table[4] = {
*/
UNIT lpt_unit = {
UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0)
UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0)
};
REG lpt_reg[] = {
@ -136,10 +137,10 @@ else {
}
lines = lflag = 0; /* clear cc action */
if (ferror (lpt_unit.fileref)) { /* error? */
ind[IN_LPT] = 1;
perror ("Line printer I/O error");
clearerr (lpt_unit.fileref);
if (iochk) return SCPE_IOERR;
ind[IN_LPT] = 1;
}
return SCPE_OK;
}

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -26,6 +26,7 @@
cdr 1622 card reader
cdp 1622 card punch
19-Jan-07 RMS Set UNIT_TEXT flag
13-Jul-06 RMS Fixed card reader fgets call (from Tom McBride)
Fixed card reader boot sequence (from Tom McBride)
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 = {
UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0)
UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE+UNIT_TEXT, 0)
};
REG cdr_reg[] = {
@ -87,7 +88,7 @@ DEVICE cdr_dev = {
*/
UNIT cdp_unit = {
UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0)
UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0)
};
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 + 1] = 0;
if (fputs (cdp_buf, cdp_unit.fileref) == EOF) { /* write card */
ind[IN_WRCHK] = 1; /* error? */
fputs (cdp_buf, cdp_unit.fileref); /* write card */
cdp_unit.pos = ftell (cdp_unit.fileref); /* count char */
if (ferror (cdp_unit.fileref)) { /* error? */
ind[IN_WRCHK] = 1;
perror ("CDP I/O error");
clearerr (cdp_unit.fileref);
return SCPE_IOERR;
}
cdp_unit.pos = ftell (cdp_unit.fileref); /* count char */
return SCPE_OK;
}

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
lpt 1443 line printer
19-Jan-07 RMS Added UNIT_TEXT flag
21-Sep-05 RMS Revised translation tables for 7094/1401 compatibility
29-Dec-03 RMS Fixed bug in scheduling
25-Apr-03 RMS Revised for extended file support
@ -69,7 +70,7 @@ t_stat lpt_space (int32 lines, int32 lflag);
*/
UNIT lpt_unit = {
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE, 50)
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 50)
};
REG lpt_reg[] = {

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -26,6 +26,7 @@
cdr 711 card reader
cdp 721 card punch
19-Jan-07 RMS Added UNIT_TEXT
13-Jul-06 RMS Fixed problem with 80 column full cards
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 };
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[] = {
@ -144,7 +145,7 @@ DEVICE cdr_dev = {
DIB cdp_dib = { &cdp_chsel, &cdp_chwr };
UNIT cdp_unit = {
UDATA (&cdp_svc, UNIT_SEQ+UNIT_ATTABLE, 0)
UDATA (&cdp_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0)
};
REG cdp_reg[] = {
@ -443,12 +444,12 @@ for (i = ((2 * CD_CHRLNT) + 1); (i > 0) &&
cdp_cbuf[i++] = '\n'; /* append nl */
cdp_cbuf[i++] = 0; /* append nul */
fputs (cdp_cbuf, uptr->fileref); /* write card */
uptr->pos = ftell (uptr->fileref); /* update position */
if (ferror (uptr->fileref)) { /* error? */
perror ("CDP I/O error");
clearerr (uptr->fileref);
return SCPE_IOERR;
}
uptr->pos = ftell (uptr->fileref); /* update position */
cdp_sta = CDS_END; /* end state */
sim_cancel (uptr); /* cancel current */
sim_activate (uptr, cdp_tstop); /* long timer */

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
cpu 7094 central processor
28-Apr-07 RMS Removed clock initialization
29-Oct-06 RMS Added additional expanded core instructions
17-Oct-06 RMS Fixed the fix 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 DEVICE mt_dev[NUM_CHAN];
extern DEVICE ch_dev[NUM_CHAN];
extern UNIT clk_unit;
extern FILE *sim_deb;
extern int32 sim_int_char;
extern int32 sim_interval;
@ -625,7 +625,6 @@ ind_reloc = ind_reloc & VA_BLK; /* canonical form */
ind_start = ind_start & VA_BLK;
ind_limit = (ind_limit & VA_BLK) | VA_OFF;
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));
if (ht_pend) { /* HTR pending? */

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,8 @@
lpt 716 line printer
19-Jan-07 RMS Added UNIT_TEXT flag
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
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 };
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[] = {
@ -306,7 +308,7 @@ return SCPE_OK;
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];
t_uint64 dat;
@ -325,22 +327,23 @@ for (col = 0; col < 72; col++) { /* proc 72 columns */
}
for (i = LPT_CHRLNT; (i > 0) &&
(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? */
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? */
perror ("LPT I/O error");
clearerr (uptr->fileref);
return SCPE_IOERR;
}
uptr->pos = ftell (uptr->fileref); /* update position */
}
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 ('\n');
}
else return SCPE_UNATT; /* otherwise error */
uptr->pos = uptr->pos + strlen (lpt_cbuf); /* count char */
lpt_sta = LPS_END; /* end line state */
sim_cancel (uptr); /* cancel current */
sim_activate (uptr, lpt_tstop); /* long timer */

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
cpu Interdata 16b CPU
28-Apr-07 RMS Removed clock initialization
27-Oct-06 RMS Added idle support
Removed separate PASLA clock
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 uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
extern t_bool sim_idle_enab;
extern UNIT pic_unit, lfc_unit; /* timers */
uint32 ReadB (uint32 loc);
uint32 ReadH (uint32 loc);
@ -587,8 +587,6 @@ else {
}
int_eval (); /* eval interrupts */
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;
/* Process events */

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
cpu Interdata 32b CPU
28-Apr-07 RMS Removed clock initialization
27-Oct-06 RMS Added idle support
Removed separate PASLA clock
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 uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
extern t_bool sim_idle_enab;
extern UNIT pic_unit, lfc_unit; /* timers */
extern FILE *sim_deb;
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 */
int_eval (); /* eval interrupts */
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;
/* Abort handling

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
lpt M46-206 line printer
19-Jan-07 RMS Added UNIT_TEXT flag
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 };
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[] = {
{ HRDATA (STA, lpt_sta, 8) },

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
cpu Nova central processor
28-Apr-07 RMS Removed clock initialization
06-Feb-06 RMS Fixed bug in DIVS (found by Mark Hittinger)
22-Sep-05 RMS Fixed declarations (from Sterling Garwood)
25-Aug-05 RMS Fixed DIVS case 2^31 / - 1
@ -332,7 +333,6 @@ extern int32 sim_interval;
int32 PC, IR, i;
t_stat reason;
void mask_out (int32 mask);
extern int32 clk_sel, clk_time[4];
/* Restore register state */
@ -341,7 +341,6 @@ PC = saved_PC & AMASK; /* load local PC */
C = C & CBIT;
mask_out (pimask); /* reset int system */
reason = 0;
sim_rtc_init (clk_time[clk_sel]); /* init calibration */
/* Main instruction fetch/decode loop */

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
lpt line printer
19-Jan-07 RMS Added UNIT_TEXT
25-Apr-03 RMS Revised for extended file support
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 };
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[] = {
@ -110,12 +111,13 @@ dev_done = dev_done | INT_LPT; /* set done */
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable);
if ((lpt_unit.flags & UNIT_ATT) == 0) /* attached? */
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");
clearerr (lpt_unit.fileref);
clearerr (uptr->fileref);
return SCPE_IOERR;
}
lpt_unit.pos = lpt_unit.pos + 1;
return SCPE_OK;
}

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
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
07-Sep-03 RMS Changed ioc to ios
23-Jul-03 RMS Fixed bugs in instruction decoding, overprinting
@ -67,7 +68,7 @@ t_stat lpt_reset (DEVICE *dptr);
*/
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[] = {
@ -166,6 +167,7 @@ if (lpt_spc) { /* space? */
if ((uptr->flags & UNIT_ATT) == 0) /* attached? */
return IORETURN (lpt_stopioe, SCPE_UNATT);
fputs (lpt_cc[lpt_spc & 07], uptr->fileref); /* print cctl */
uptr->pos = ftell (uptr->fileref); /* update position */
if (ferror (uptr->fileref)) { /* error? */
perror ("LPT I/O error");
clearerr (uptr->fileref);
@ -179,6 +181,7 @@ else {
return IORETURN (lpt_stopioe, SCPE_UNATT);
if (lpt_ovrpr) fputc ('\r', uptr->fileref); /* overprint? */
fputs (lpt_buf, uptr->fileref); /* print buffer */
uptr->pos = ftell (uptr->fileref); /* update position */
if (ferror (uptr->fileref)) { /* test error */
perror ("LPT I/O error");
clearerr (uptr->fileref);
@ -188,7 +191,6 @@ else {
for (i = 0; i <= LPT_BSIZE; i++) lpt_buf[i] = 0; /* clear buffer */
lpt_ovrpr = 1; /* set overprint */
}
lpt_unit.pos = ftell (uptr->fileref); /* update position */
return SCPE_OK;
}

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
cpu KS10 central processor
28-Apr-07 RMS Removed clock initialization
22-Sep-05 RMS Fixed declarations (from Sterling Garwood)
Fixed warning in MOVNI
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_interval;
extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
extern UNIT tim_unit;
/* Forward and external declarations */
@ -633,7 +633,6 @@ pager_tc = FALSE; /* not in trap cycle */
pager_pi = FALSE; /* not in pi sequence */
rlog = 0; /* not in extend */
pi_eval (); /* eval pi system */
sim_rtc_init (tim_unit.wait); /* init calibration */
if (!Q_ITS) its_1pr = 0; /* ~ITS, clr 1-proc */
t20_idlelock = 0; /* clr T20 idle lock */

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
lp20 line printer
19-Jan-07 RMS Added UNIT_TEXT flag
04-Sep-05 RMS Fixed missing return (found by Peter Schorn)
07-Jul-05 RMS Removed extraneous externs
18-Mar-05 RMS Added attached test to detach routine
@ -185,7 +186,7 @@ DIB lp20_dib = {
};
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[] = {
@ -527,8 +528,9 @@ else {
if (lpcolc >= LP_WIDTH) /* line full? */
r = lp20_adv (1, TRUE); /* adv carriage */
}
for (i = 0; i < rpt; i++) putc (lppdat, lp20_unit.fileref);
lp20_unit.pos = lp20_unit.pos + rpt;
for (i = 0; i < rpt; i++)
fputc (lppdat, lp20_unit.fileref);
lp20_unit.pos = ftell (lp20_unit.fileref);
lpcolc = lpcolc + rpt;
return r;
}
@ -539,8 +541,9 @@ int32 i;
if (cnt == 0) return TRUE;
lpcolc = 0; /* reset col cntr */
for (i = 0; i < cnt; i++) putc ('\n', lp20_unit.fileref);
lp20_unit.pos = lp20_unit.pos + cnt; /* print 'n' newlines */
for (i = 0; i < cnt; i++)
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 (davfu[dvptr] & (1 << DV_TOF)) { /* at top of form? */
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 (cnt) return lp20_adv (i + 1, FALSE); /* ~TOF, adv */
if (lpcolc) lp20_adv (1, FALSE); /* TOF, need newline? */
putc ('\f', lp20_unit.fileref); /* print form feed */
lp20_unit.pos = lp20_unit.pos + 1;
fputc ('\f', lp20_unit.fileref); /* print form feed */
lp20_unit.pos = ftell (lp20_unit.fileref);
if (lppagc = (lppagc - 1) & PAGC_MASK) { /* decr page cntr */
lpcsa = lpcsa & ~CSA_PZRO; /* update status */
return TRUE;

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
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-Aug-05 RMS Fixed C++ declaration and cast problems
07-Jul-05 RMS Removed extraneous externs
@ -871,6 +872,7 @@ switch (fnc) { /* case on function */
tufs = tufs | FS_ID; /* PE BOT? ID burst */
TXFR (ba, wc, 0); /* validate transfer */
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 */
break; /* done */
}
@ -924,6 +926,7 @@ switch (fnc) { /* case on function */
tufc = 0; /* clear frame count */
TXFR (ba, wc, 1); /* validate xfer 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 */
break; /* done */
}
@ -1032,7 +1035,6 @@ switch (st) {
return SCPE_IERR;
case MTSE_TMK: /* end of file */
set_tuer (ER_FCE); /* also sets FCE */
tufs = tufs | FS_TMK;
break;

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
cpu PDP-11 CPU
28-Apr-07 RMS Removed clock initialization
27-Oct-06 RMS Added idle support
18-Oct-06 RMS Fixed bug in ASH -32 C value
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 sim_interval;
extern UNIT clk_unit, pclk_unit;
extern int32 sim_int_char;
extern uint32 sim_switches;
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 */
trapea = 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

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
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
16-Aug-05 RMS Fixed C++ declaration and cast problems
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 uint32 cpu_model, cpu_type, cpu_opt;
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_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);
M = nM;
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;
}

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,8 @@
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
13-Nov-05 RMS Fixed overlapped seek interaction with NOP, DCLR, PACK
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_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 FILE *sim_deb;
@ -338,7 +346,7 @@ int32 hk_min2wait = 300; /* min time to 2nd int *
int16 hkdb[3] = { 0 }; /* data buffer silo */
int16 hk_off[HK_NUMDR] = { 0 }; /* saved offset */
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 };
DEVICE hk_dev;
@ -453,12 +461,20 @@ MTAB hk_mod[] = {
{ 0 }
};
DEBTAB hk_deb[] = {
{ "OPS", HKDEB_OPS },
{ "RRD", HKDEB_RRD },
{ "RWR", HKDEB_RWR },
{ NULL, 0 }
};
DEVICE hk_dev = {
"HK", hk_unit, hk_reg, hk_mod,
HK_NUMDR, DEV_RDX, 24, 1, DEV_RDX, 16,
NULL, NULL, &hk_reset,
&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 */
@ -538,14 +554,16 @@ switch (j) { /* decode PA<4:1> */
break;
case 016: /* HKMR2 */
*data = hkmr2 = hk_rdmr2 (GET_MS (hkmr));
*data = hkmr2;
break;
case 017: /* HKMR3 */
*data = hkmr3 = hk_rdmr3 (GET_MS (hkmr));
*data = hkmr3;
break;
}
if (DEBUG_PRI (hk_dev, HKDEB_RRD))
fprintf (sim_deb, ">>HK%d read: reg%d=%o\n", drv, j, *data);
return SCPE_OK;
}
@ -565,6 +583,8 @@ if ((hkcs1 & CS1_GO) && /* busy? */
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> */
case 000: /* HKCS1 */
@ -648,23 +668,27 @@ void hk_go (int32 drv)
int32 fnc, t;
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
};
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
};
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
};
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
};
fnc = GET_FNC (hkcs1);
if (DEBUG_PRS (hk_dev)) fprintf (sim_deb,
">>HK%d go: fnc=%o, ds=%o, cyl=%o, da=%o, ba=%o, wc=%o\n",
drv, fnc, hkds[drv], hkdc, hkda, hkba, hkwc);
if (DEBUG_PRI (hk_dev, HKDEB_OPS)) fprintf (sim_deb,
">>HK%d strt: fnc=%o, cs1=%o, cs2=%o, ds=%o, er=%o, cyl=%o, da=%o, ba=%o, wc=%o\n",
drv, fnc, hkcs1, hkcs2, hkds[drv], hker[drv], hkdc, hkda, hkba, hkwc);
uptr = hk_dev.units + drv; /* get unit */
if (fnc != FNC_NOP) hkmr = hkmr & ~MR_MS; /* !nop, clr msg sel */
if (uptr->flags & UNIT_DIS) { /* nx unit? */
@ -672,11 +696,12 @@ if (uptr->flags & UNIT_DIS) { /* nx unit? */
update_hkcs (CS1_DONE, drv); /* done */
return;
}
if (((hkcs1 & CS1_DT) != 0) != /* dtype mismatch? */
((uptr->flags & UNIT_DTYPE) != 0)) {
hk_cmderr (ER_DTY, drv); /* type error */
return;
}
if (fnc_cdt[fnc] &&
(((hkcs1 & CS1_DT) != 0) != /* need dtype match? */
((uptr->flags & UNIT_DTYPE) != 0))) {
hk_cmderr (ER_DTY, drv); /* type error */
return;
}
if (fnc_nxf[fnc] && ((hkds[drv] & DS_VV) == 0)) { /* need vol valid? */
hk_cmderr (ER_NXF, drv); /* non exec func */
return;
@ -699,10 +724,15 @@ switch (fnc) { /* case on function */
/* 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 */
hkds[drv] &= ~DS_ATA; /* clr ATA */
hker[drv] = 0; /* clear errors */
case FNC_NOP: /* no operation */
update_hkcs (CS1_DONE, drv); /* done */
break;
@ -929,9 +959,6 @@ switch (fnc) { /* case on function */
break;
} /* 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;
}
@ -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 */
(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;
}

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
lpt LP11 line printer
19-Jan-07 RMS Added UNIT_TEXT flag
07-Jul-05 RMS Removed extraneous externs
19-May-03 RMS Revised for new conditional compilation scheme
25-Apr-03 RMS Revised for extended file support
@ -76,7 +77,7 @@ DIB lpt_dib = {
};
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[] = {
@ -151,15 +152,16 @@ t_stat lpt_svc (UNIT *uptr)
{
lpt_csr = lpt_csr | CSR_ERR | CSR_DONE;
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);
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");
clearerr (lpt_unit.fileref);
clearerr (uptr->fileref);
return SCPE_IOERR;
}
lpt_csr = lpt_csr & ~CSR_ERR;
lpt_unit.pos = lpt_unit.pos + 1;
return SCPE_OK;
}

View file

@ -25,6 +25,7 @@
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
12-Nov-05 RMS Changed default formatter to TM03 (for VMS)
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))
tufs = tufs | FS_ID; /* PE BOT? ID burst */
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 */
break; /* done */
}
@ -729,6 +731,7 @@ switch (fnc) { /* case on function */
case FNC_WCHKR: /* wcheck = read */
tufc = 0; /* clear frame count */
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 */
break; /* done */
}
@ -826,7 +829,6 @@ switch (st) {
case MTSE_TMK: /* end of file */
tufs = tufs | FS_TMK;
tu_set_er (ER_FCE); /* also sets FCE */
break;
case MTSE_IOERR: /* IO error */

View file

@ -32,31 +32,37 @@
These manuals can be found online at:
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:
1) Receives/Transmits single packet under custom RSX driver
2) Passes RSTS 10.1 controller diagnostics during boot
3) VMS 7.2 on VAX780 summary:
LAT - Runs properly both in and out
DECNET - Starts without error, but will not do anything
TCP/IP - Starts with errors, will ping in/out but nothing else
Clustering - Not tested
(May/2007: WinXP x64 host; MS VC++ 2005; SIMH v3.7-0 base; WinPcap 4.0)
LAT - SET HOST/LAT in/out
DECNET - SET HOST in/out, COPY in/out
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:
1) Transmit/Receive rings have not been thoroughly tested,
particularly when and where the ring pointers get reset.
2) Most auxiliary commands are not implemented yet.
3) System_ID broadcast is not implemented
4) Error/Interrupt signalling is still iffy from merge of FvK and sim_ether
3) System_ID broadcast is not implemented.
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:
03-May-07 DTH Added missing FC_RMAL command; cleared multicast on write
29-Oct-06 RMS Synced poll and clock
08-Dec-05 DTH Implemented ancilliary functions 022/023/024/025
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)
{
uint32 udbb;
int fnc, mtlen;
int fnc, mtlen, i, j;
uint16 value, pltlen;
t_stat status, rstatus, wstatus, wstatus2, wstatus3;
struct xu_stats* stats = &xu->var->stats;
@ -666,12 +672,24 @@ int32 xu_command(CTLR* xu)
return PCSR0_PCEI;
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 */
mtlen = (xu->var->pcb[2] & 0xFF00) >> 8;
sim_debug(DBG_TRC, xu->dev, "FC_WAL: mtlen=%d\n", mtlen);
if (mtlen > 10)
return PCSR0_PCEI;
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]);
if (rstatus == 0) {
xu->var->setup.mac_count = mtlen + 1;

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
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)
30-Oct-06 RMS Added idle and infinite loop detection
08-Oct-06 RMS Added RDCLK instruction
@ -581,7 +582,6 @@ int32 api_int, api_usmd, skp;
int32 iot_data, device, pulse;
int32 last_IR;
t_stat reason;
extern UNIT clk_unit;
if (build_dev_tab ()) return SCPE_STOP; /* build, chk tables */
PC = PC & AMASK; /* clean variables */
@ -589,8 +589,8 @@ LAC = LAC & LACMASK;
MQ = MQ & DMASK;
reason = 0;
last_IR = -1;
sim_rtc_init (clk_unit.wait); /* init calibration */
if (cpu_unit.flags & UNIT_NOAPI) api_enb = api_req = api_act = 0;
if (cpu_unit.flags & UNIT_NOAPI) /* no API? */
api_enb = api_req = api_act = 0;
api_int = api_eval (&int_pend); /* eval API */
api_usmd = 0; /* not API user cycle */

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -28,6 +28,7 @@
lp09 (PDP-9,15) LP09 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
14-Jan-04 RMS Revised IO device call interface
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 } };
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[] = {
@ -179,6 +180,7 @@ if (lp62_spc) { /* space? */
if ((uptr->flags & UNIT_ATT) == 0) /* attached? */
return IORETURN (lp62_stopioe, SCPE_UNATT);
fputs (lp62_cc[lp62_spc & 07], uptr->fileref); /* print cctl */
uptr->pos = ftell (uptr->fileref); /* update position */
if (ferror (uptr->fileref)) { /* error? */
perror ("LPT I/O error");
clearerr (uptr->fileref);
@ -192,6 +194,7 @@ else {
return IORETURN (lp62_stopioe, SCPE_UNATT);
if (lp62_ovrpr) fputc ('\r', uptr->fileref); /* overprint? */
fputs (lp62_buf, uptr->fileref); /* print buffer */
uptr->pos = ftell (uptr->fileref); /* update position */
if (ferror (uptr->fileref)) { /* test error */
perror ("LPT I/O error");
clearerr (uptr->fileref);
@ -201,7 +204,6 @@ else {
for (i = 0; i <= LP62_BSIZE; i++) lp62_buf[i] = 0; /* clear buffer */
lp62_ovrpr = 1; /* set overprint */
}
uptr->pos = ftell (uptr->fileref); /* update position */
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 } };
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[] = {
@ -393,7 +395,7 @@ return dat;
t_stat lp647_svc (UNIT *uptr)
{
int32 i;
char pbuf[LP647_BSIZE + 1];
char pbuf[LP647_BSIZE + 2];
lp647_don = 1;
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 */
pbuf[i] = lp647_buf[i] | ((lp647_buf[i] >= 040)? 0: 0100);
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 */
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? */
perror ("LPT I/O error");
clearerr (uptr->fileref);
@ -417,13 +421,13 @@ if ((lp647_iot & 020) == 0) { /* print? */
}
if (lp647_iot & 060) { /* space? */
fputs (lp647_cc[lp647_iot & 07], uptr->fileref); /* write cctl */
uptr->pos = ftell (uptr->fileref); /* update position */
if (ferror (uptr->fileref)) { /* error? */
perror ("LPT I/O error");
clearerr (uptr->fileref);
return SCPE_IOERR;
}
}
uptr->pos = ftell (uptr->fileref); /* update position */
return SCPE_OK;
}
@ -501,7 +505,7 @@ t_stat lp09_detach (UNIT *uptr);
DIB lp09_dib = { DEV_LPT, 2, &lp09_iors, { NULL, &lp09_66 } };
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[] = {
@ -582,12 +586,13 @@ if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
}
c = uptr->buf & 0177; /* get char */
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");
clearerr (uptr->fileref);
return SCPE_IOERR;
}
uptr->pos = uptr->pos + 1; /* update position */
return SCPE_OK;
}
@ -657,7 +662,7 @@ int32 lp15_stopioe = 0;
int32 lp15_mode = 0;
int32 lp15_lc = 0;
int32 lp15_bp = 0;
char lp15_buf[LP15_BSIZE] = { 0 };
char lp15_buf[LP15_BSIZE + 1] = { 0 };
DEVICE lp15_dev;
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 } };
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[] = {
@ -786,8 +791,10 @@ for (more = 1; more != 0; ) { /* loop until ctrl */
}
for (i = 0; i < ccnt; i++) { /* loop through */
if ((c[i] <= 037) && ctrl[c[i]]) { /* control char? */
fwrite (lp15_buf, 1, lp15_bp, uptr->fileref);
fputs (ctrl[c[i]], uptr->fileref);
lp15_buf[lp15_bp] = 0; /* append nul */
fputs (lp15_buf, uptr->fileref); /* print line */
fputs (ctrl[c[i]], uptr->fileref); /* space */
uptr->pos = ftell (uptr->fileref);
if (ferror (uptr->fileref)) { /* error? */
perror ("LPT I/O error");
clearerr (uptr->fileref);
@ -795,7 +802,6 @@ for (more = 1; more != 0; ) { /* loop until ctrl */
lp15_updsta (STA_DON | STA_ALM);
return SCPE_IOERR;
}
uptr->pos = ftell (uptr->fileref);
lp15_bp = more = 0;
}
else {

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
cpu central processor
28-Apr-07 RMS Removed clock initialization
30-Oct-06 RMS Added idle and infinite loop detection
30-Sep-06 RMS Fixed SC value after DVI overflow (found by Don North)
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 DEVICE *sim_devices[];
extern FILE *sim_log;
extern UNIT clk_unit, ttix_unit;
extern t_bool sim_idle_enab;
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;
int_req = INT_UPDATE;
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 */

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
lpt LP8E line printer
19-Jan-07 RMS Added UNIT_TEXT
25-Apr-03 RMS Revised for extended file support
04-Oct-02 RMS Added DIB, enable/disable, device number support
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 } };
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[] = {
@ -135,16 +136,17 @@ t_stat lpt_svc (UNIT *uptr)
{
dev_done = dev_done | INT_LPT; /* set done */
int_req = INT_UPDATE; /* update interrupts */
if ((lpt_unit.flags & UNIT_ATT) == 0) {
if ((uptr->flags & UNIT_ATT) == 0) {
lpt_err = 1;
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");
clearerr (lpt_unit.fileref);
clearerr (uptr->fileref);
return SCPE_IOERR;
}
lpt_unit.pos = lpt_unit.pos + 1;
return SCPE_OK;
}

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -26,6 +26,7 @@
cpu central processor
rtc real time clock
28-Apr-07 RMS Removed clock initialization
29-Dec-06 RMS Fixed breakpoint variable declarations
16-Aug-05 RMS Fixed C++ declaration and cast problems
07-Nov-04 RMS Added instruction history
@ -195,7 +196,6 @@ int32 rtc_tps = 60; /* rtc ticks/sec */
extern int32 sim_int_char;
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_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 */
int_reqhi = api_findreq (); /* recalc int req */
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 */

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
lpt line printer
19-Jan-07 RMS Added UNIT_TEXT flag
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 };
UNIT lpt_unit = {
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE, 0)
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0)
};
REG lpt_reg[] = {

View file

@ -51,6 +51,10 @@
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.
52. TMR: tmr_inc not updated in standard (100Hz) mode.
53. MTPR SBR/PCBB/SCBB: 11/780 only checks that bits<1:0> == 0.
54. MTPR xLR: 11/780 excludes bits<31:24> from mbz test.
55. MTPR PxBR: 11/780 only checks bits<31,1:0> == 1,00.

View file

@ -1,6 +1,6 @@
/* vax780_defs.h: VAX 780 model-specific definitions file
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
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
in this Software without prior written authorization from Robert M Supnik.
29-Oct-2006 RMS Added clock coscheduler function
17-May-2006 RMS Added CR11/CD11 support (from John Dundas)
10-May-2006 RMS Added model-specific reserved operand check macros
29-Apr-07 RMS Modified model-specific reserved operand check macros
to reflect 780 microcode patches (found by Naoki Hamada)
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.
@ -119,10 +121,20 @@
/* Machine specific reserved operand tests */
#define ML_PA_TEST(r) if ((r) & 0xC0000003) RSVD_OPND_FAULT
#define ML_LR_TEST(r) if ((uint32)(r) > 0x200000) RSVD_OPND_FAULT
#define ML_BR_TEST(r) if ((((r) & 0xC0000000) != 0x80000000) || \
/* 780 microcode patch 37 - only test LR<23:0> for appropriate length */
#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
#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_MBZ84_TEST(r) if ((r) & 0xF8C00000) RSVD_OPND_FAULT
#define LP_MBZ92_TEST(r) if ((r) & 0x7FC00000) RSVD_OPND_FAULT

View file

@ -1,6 +1,6 @@
/* vax_cpu.c: VAX CPU
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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
cpu VAX central processor
28-Apr-07 RMS Removed clock initialization
29-Oct-06 RMS Added idle support
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
@ -284,7 +285,6 @@ extern int32 sim_int_char;
extern int32 sim_switches;
extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
extern t_bool sim_idle_enab;
extern UNIT clk_unit;
extern t_stat build_dib_tab (void);
extern UNIT rom_unit, nvr_unit;
@ -501,7 +501,6 @@ set_map_reg (); /* set map reg */
GET_CUR; /* set access mask */
SET_IRQL; /* eval interrupts */
FLUSH_ISTR; /* clear prefetch */
sim_rtcn_init (clk_unit.wait, TMR_CLK); /* init clock */
abortval = setjmp (save_env); /* set abort hdlr */
if (abortval > 0) { /* sim stop? */

View file

@ -1,6 +1,6 @@
/* 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
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
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
Added mbz check in LDPCTX for 11/780
22-Sep-06 RMS Fixed declarations (from Sterling Garwood)
@ -1230,7 +1231,7 @@ newpc = ReadLP (pcbpa + 72); /* get PC, PSL */
newpsl = ReadLP (pcbpa + 76);
t = ReadLP (pcbpa + 80);
ML_BR_TEST (t); /* validate P0BR */
ML_PXBR_TEST (t); /* validate P0BR */
P0BR = t & BR_MASK; /* restore P0BR */
t = ReadLP (pcbpa + 84);
LP_MBZ84_TEST (t); /* test mbz */
@ -1240,7 +1241,7 @@ t = (t >> 24) & AST_MASK;
LP_AST_TEST (t); /* validate AST */
ASTLVL = t; /* restore AST */
t = ReadLP (pcbpa + 88);
ML_BR_TEST (t + 0x800000); /* validate P1BR */
ML_PXBR_TEST (t + 0x800000); /* validate P1BR */
P1BR = t & BR_MASK; /* restore P1BR */
t = ReadLP (pcbpa + 92);
LP_MBZ92_TEST (t); /* test MBZ */
@ -1387,7 +1388,7 @@ switch (prn) { /* case on reg # */
break;
case MT_P0BR: /* P0BR */
ML_BR_TEST (val); /* validate */
ML_PXBR_TEST (val); /* validate */
P0BR = val & BR_MASK; /* lw aligned */
zap_tb (0); /* clr proc TLB */
set_map_reg ();
@ -1401,7 +1402,7 @@ switch (prn) { /* case on reg # */
break;
case MT_P1BR: /* P1BR */
ML_BR_TEST (val + 0x800000); /* validate */
ML_PXBR_TEST (val + 0x800000); /* validate */
P1BR = val & BR_MASK; /* lw aligned */
zap_tb (0); /* clr proc TLB */
set_map_reg ();
@ -1415,7 +1416,7 @@ switch (prn) { /* case on reg # */
break;
case MT_SBR: /* SBR */
ML_PA_TEST (val); /* validate */
ML_SBR_TEST (val); /* validate */
SBR = val & BR_MASK; /* lw aligned */
zap_tb (1); /* clr entire TLB */
set_map_reg ();

View file

@ -1,6 +1,6 @@
/* 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
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
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)
30-Sep-04 RMS Comment and formating changes
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 (ptidx >= d_slr) /* system */
MM_ERR (PR_LNV);
ptead = d_sbr + ptidx;
ptead = (d_sbr + ptidx) & PAMASK;
}
else {
if (va & VA_P1) { /* P1? */
@ -463,7 +464,7 @@ else {
ptidx = ((uint32) ptead) >> 7; /* xlate like sys */
if (ptidx >= d_slr)
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 ((pte & PTE_ACC) == 0) MM_ERR (PR_PACV); /* spte ACV? */
#endif

View file

@ -1,6 +1,6 @@
/* 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
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
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
10-May-06 RMS Added NOP'd reserved operand checking macros
05-Oct-05 RMS Added XU definitions for autoconfigure
@ -204,7 +205,8 @@
#define ML_PA_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_MBZ84_TEST(r)
#define LP_MBZ92_TEST(r)

View file

@ -10,7 +10,11 @@ OS_CCDEFS = -lsocket -lnsl -lpthread -D_GNU_SOURCE
else
OS_CCDEFS = -D_GNU_SOURCE
endif
ifeq ($(OSTYPE),macos)
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),)
else
NETWORK_OPT = -DUSE_NETWORK -isystem /usr/local/include /usr/local/lib/libpcap.a

26
scp.c
View file

@ -23,6 +23,10 @@
used in advertising or otherwise to promote the sale, use or other dealings
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
17-Oct-06 RMS Added idle support
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 */
do {
ocptr = cptr = read_line (cbuf, CBUFSIZE, fpin); /* get cmd line */
sub_args (cbuf, gbuf, CBUFSIZE, nargs, do_arg);
ocptr = cptr = sim_brk_getact (cbuf, CBUFSIZE); /* get bkpt action */
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? */
stat = SCPE_OK; /* set good return */
break;
@ -2169,6 +2175,7 @@ if (v32) { /* [V3.2+] time as strin
else READ_I (sim_time); /* sim time */
READ_I (sim_rtime); /* [V2.6+] sim rel time */
sim_switches = SIM_SW_REST; /* flag restore */
for ( ;; ) { /* device loop */
READ_S (buf); /* read device name */
if (buf[0] == 0) break; /* last? */
@ -2214,7 +2221,6 @@ for ( ;; ) { /* device loop */
(!(dptr->flags & DEV_NET) || /* not net dev or */
!(uptr->flags & UNIT_ATT) || /* not currently 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 */
if (r != SCPE_OK) return r;
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);
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) &&
((dptr->msize == NULL) ||
(dptr->msize (uptr, (int32) high, NULL, NULL) != SCPE_OK))) {
printf ("Can't change memory size: %s%d\n",
sim_dname (dptr), unitno);
uptr->capac = old_capac;
return SCPE_INCOMP;
}
uptr->capac = high;
uptr->capac = high; /* new memory size */
printf ("Memory size changed: %s%d = ", sim_dname (dptr), unitno);
fprint_capac (stdout, dptr, uptr);
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_is_running = 1; /* flag running */
sim_brk_clract (); /* defang actions */
sim_rtcn_init_all (); /* re-init clocks */
r = sim_instr();
sim_is_running = 0; /* flag idle */
@ -3495,6 +3502,7 @@ return cptr;
char *get_sim_opt (int32 opt, char *cptr, t_stat *st)
{
int32 t;
t_bool dfdu;
char *svptr, gbuf[CBUFSIZE];
DEVICE *tdptr;
UNIT *tuptr;
@ -3508,6 +3516,7 @@ sim_stab.mask = 0;
sim_stab.comp = 0;
sim_dfdev = sim_dflt_dev;
sim_dfunit = sim_dfdev->units;
dfdu = FALSE; /* no default yet */
*st = SCPE_OK;
while (*cptr) { /* loop through modifiers */
svptr = cptr; /* save current position */
@ -3532,13 +3541,14 @@ while (*cptr) { /* loop through modifier
sim_switches = sim_switches | t; /* or in new switches */
}
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 */
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 */
(tuptr != NULL)) {
sim_dfdev = tdptr; /* set as default */
sim_dfunit = tuptr;
dfdu = TRUE; /* indicate dflt seen */
}
else return svptr; /* not rec, break out */
}

View file

@ -1,6 +1,6 @@
/* 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
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
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
13-Jul-06 RMS Guarantee CBUFSIZE is at least 256
07-Jan-06 RMS Added support for breakpoint spaces
@ -363,6 +365,7 @@ struct sim_unit {
#define UNIT_DISABLE 002000 /* disable-able */
#define UNIT_DIS 004000 /* disabled */
#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 (((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_PRD(d) (sim_deb && d->dctrl)
#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 */

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -29,12 +29,67 @@
#define SIM_MAJOR 3
#define SIM_MINOR 7
#define SIM_PATCH 0
#define SIM_PATCH 1
/* V3.7 revision history
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:
- implemented throttle commands
- added -e to control error processing in DO command files

View file

@ -1,6 +1,6 @@
/* 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
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
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)
Added throttle support
21-Aug-05 RMS Added sim_rtcn_init_all
16-Aug-05 RMS Fixed C++ declaration and cast problems
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_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)
{
if (time == 0) time = 1;

View file

@ -1,6 +1,6 @@
/* 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
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
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
02-Jan-04 RMS Split out from SCP
*/
@ -48,6 +49,7 @@
t_bool sim_timer_init (void);
int32 sim_rtcn_init (int32 time, int32 tmr);
void sim_rtcn_init_all (void);
int32 sim_rtcn_calb (int32 ticksper, int32 tmr);
int32 sim_rtc_init (int32 time);
int32 sim_rtc_calb (int32 ticksper);