Notes For V3.7

1. New Features

1.1 3.7-0

1.1.1 SCP

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

1.1.2 HP2100

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

1.1.3 Interdata

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

1.1.4 PDP-11

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

1.1.5 PDP-8

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

1.1.6 PDP-1

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

1.1.6 PDP-4/7/9/15

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

1.1.7 VAX, VAX780

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

1.1.8 PDP-10

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

2. Bugs Fixed

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

View file

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

View file

@ -160,12 +160,6 @@ void PutBYTEWrapper(const uint32 Addr, const uint32 Value);
int32 getBankSelect(void); int32 getBankSelect(void);
void setBankSelect(const int32 b); void setBankSelect(const int32 b);
uint32 getCommon(void); 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_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_norom (UNIT *uptr, int32 value, char *cptr, void *desc);
static t_stat cpu_set_altairrom (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_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_nonbanked (UNIT *uptr, int32 value, char *cptr, void *desc);
static t_stat cpu_set_size (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 data structures
cpu_dev CPU device descriptor cpu_dev CPU device descriptor
@ -194,7 +179,7 @@ UNIT cpu_unit = {
UDATA (NULL, UNIT_FIX + UNIT_BINK + UNIT_ROM + UNIT_ALTAIRROM, MAXMEMSIZE) 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 */ int32 saved_PC = 0; /* program counter */
static int32 AF_S; /* AF register */ static int32 AF_S; /* AF register */
static int32 BC_S; /* BC 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, 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); static void altairz80_init(void);
void (*sim_vm_init) (void) = &altairz80_init; void (*sim_vm_init) (void) = &altairz80_init;
static void altairz80_init(void) { 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 */ 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) { static void warnUnsuccessfulWriteAttempt(const uint32 Addr) {
if (cpu_unit.flags & UNIT_WARNROM) { if (cpu_unit.flags & UNIT_WARNROM) {
if (addressIsInROM(Addr)) { if (addressIsInROM(Addr)) {
@ -1485,18 +1480,8 @@ static uint8 warnUnsuccessfulReadAttempt(const uint32 Addr) {
return 0xff; 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 */ /* 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 */ uint32 addr = Addr & ADDRMASK; /* registers are NOT guaranteed to be always 16-bit values */
return (cpu_unit.flags & UNIT_BANKED) || (addr < MEMSIZE) || return (cpu_unit.flags & UNIT_BANKED) || (addr < MEMSIZE) ||
( ((cpu_unit.flags & UNIT_BANKED) == 0) && (cpu_unit.flags & UNIT_ROM) ( ((cpu_unit.flags & UNIT_BANKED) == 0) && (cpu_unit.flags & UNIT_ROM)
@ -5019,6 +5004,7 @@ t_stat sim_instr (void) {
tStates -= 5; tStates -= 5;
acu = HIGH_REGISTER(AF); acu = HIGH_REGISTER(AF);
BC &= ADDRMASK; BC &= ADDRMASK;
if (BC == 0) BC = 0x10000;
do { do {
tStates += 21; tStates += 21;
CHECK_BREAK_TWO_BYTES(HL, DE); CHECK_BREAK_TWO_BYTES(HL, DE);
@ -5033,6 +5019,7 @@ t_stat sim_instr (void) {
tStates -= 5; tStates -= 5;
acu = HIGH_REGISTER(AF); acu = HIGH_REGISTER(AF);
BC &= ADDRMASK; BC &= ADDRMASK;
if (BC == 0) BC = 0x10000;
do { do {
tStates += 21; tStates += 21;
CHECK_BREAK_BYTE(HL); CHECK_BREAK_BYTE(HL);
@ -5053,6 +5040,7 @@ t_stat sim_instr (void) {
case 0xb2: /* INIR */ case 0xb2: /* INIR */
tStates -= 5; tStates -= 5;
temp = HIGH_REGISTER(BC); temp = HIGH_REGISTER(BC);
if (temp == 0) temp = 0x100;
do { do {
tStates += 21; tStates += 21;
CHECK_BREAK_BYTE(HL); CHECK_BREAK_BYTE(HL);
@ -5067,6 +5055,7 @@ t_stat sim_instr (void) {
case 0xb3: /* OTIR */ case 0xb3: /* OTIR */
tStates -= 5; tStates -= 5;
temp = HIGH_REGISTER(BC); temp = HIGH_REGISTER(BC);
if (temp == 0) temp = 0x100;
do { do {
tStates += 21; tStates += 21;
CHECK_BREAK_BYTE(HL); CHECK_BREAK_BYTE(HL);
@ -5081,6 +5070,7 @@ t_stat sim_instr (void) {
case 0xb8: /* LDDR */ case 0xb8: /* LDDR */
tStates -= 5; tStates -= 5;
BC &= ADDRMASK; BC &= ADDRMASK;
if (BC == 0) BC = 0x10000;
do { do {
tStates += 21; tStates += 21;
CHECK_BREAK_TWO_BYTES(HL, DE); CHECK_BREAK_TWO_BYTES(HL, DE);
@ -5095,6 +5085,7 @@ t_stat sim_instr (void) {
tStates -= 5; tStates -= 5;
acu = HIGH_REGISTER(AF); acu = HIGH_REGISTER(AF);
BC &= ADDRMASK; BC &= ADDRMASK;
if (BC == 0) BC = 0x10000;
do { do {
tStates += 21; tStates += 21;
CHECK_BREAK_BYTE(HL); CHECK_BREAK_BYTE(HL);
@ -5115,6 +5106,7 @@ t_stat sim_instr (void) {
case 0xba: /* INDR */ case 0xba: /* INDR */
tStates -= 5; tStates -= 5;
temp = HIGH_REGISTER(BC); temp = HIGH_REGISTER(BC);
if (temp == 0) temp = 0x100;
do { do {
tStates += 21; tStates += 21;
CHECK_BREAK_BYTE(HL); CHECK_BREAK_BYTE(HL);
@ -5129,6 +5121,7 @@ t_stat sim_instr (void) {
case 0xbb: /* OTDR */ case 0xbb: /* OTDR */
tStates -= 5; tStates -= 5;
temp = HIGH_REGISTER(BC); temp = HIGH_REGISTER(BC);
if (temp == 0) temp = 0x100;
do { do {
tStates += 21; tStates += 21;
CHECK_BREAK_BYTE(HL); CHECK_BREAK_BYTE(HL);
@ -6061,6 +6054,27 @@ t_stat sim_instr (void) {
return reason; 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) { static void reset_memory(void) {
uint32 i, j; uint32 i, j;
checkROMBoundaries(); checkROMBoundaries();
@ -6090,7 +6104,7 @@ static void reset_memory(void) {
isProtected = FALSE; isProtected = FALSE;
} }
void printROMMessage(const uint32 cntROM) { static void printROMMessage(const uint32 cntROM) {
if (cntROM) { if (cntROM) {
printf("Warning: %d bytes written to ROM [%04X - %04X].\n", cntROM, ROMLow, ROMHigh); 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; 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) { static t_stat cpu_set_rom(UNIT *uptr, int32 value, char *cptr, void *desc) {
checkROMBoundaries(); checkROMBoundaries();
return SCPE_OK; return SCPE_OK;

View file

@ -110,8 +110,8 @@
#include "altairz80_defs.h" #include "altairz80_defs.h"
#define UNIT_V_DSKWLK (UNIT_V_UF + 0) /* write locked */ #define UNIT_V_DSK_WLK (UNIT_V_UF + 0) /* write locked */
#define UNIT_DSKWLK (1 << UNIT_V_DSKWLK) #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_V_DSK_VERBOSE (UNIT_V_UF + 1) /* verbose mode, i.e. show error messages */
#define UNIT_DSK_VERBOSE (1 << UNIT_V_DSK_VERBOSE) #define UNIT_DSK_VERBOSE (1 << UNIT_V_DSK_VERBOSE)
#define DSK_SECTSIZE 137 /* size of sector */ #define DSK_SECTSIZE 137 /* size of sector */
@ -129,18 +129,12 @@
int32 dsk10(const int32 port, const int32 io, const int32 data); int32 dsk10(const int32 port, const int32 io, const int32 data);
int32 dsk11(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); 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_boot(int32 unitno, DEVICE *dptr);
static t_stat dsk_reset(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 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 PCX;
extern int32 saved_PC; extern int32 saved_PC;
extern FILE *sim_log;
extern char messageBuffer[]; extern char messageBuffer[];
extern UNIT cpu_unit; extern UNIT cpu_unit;
@ -149,8 +143,9 @@ extern int32 install_bootrom(void);
/* global data on status */ /* global data on status */
static int32 current_disk = NUM_OF_DSK; /* currently selected drive (values are 0 .. 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 */ 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_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_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}; static int32 current_byte [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0};
@ -240,8 +235,8 @@ static REG dsk_reg[] = {
}; };
static MTAB dsk_mod[] = { static MTAB dsk_mod[] = {
{ UNIT_DSKWLK, 0, "write enabled", "WRITEENABLED", NULL }, { UNIT_DSK_WLK, 0, "WRTENB", "WRTENB", NULL },
{ UNIT_DSKWLK, UNIT_DSKWLK, "write locked", "LOCKED", NULL }, { UNIT_DSK_WLK, UNIT_DSK_WLK, "WRTLCK", "WRTLCK", NULL },
/* quiet, no warning messages */ /* quiet, no warning messages */
{ UNIT_DSK_VERBOSE, 0, "QUIET", "QUIET", NULL }, { UNIT_DSK_VERBOSE, 0, "QUIET", "QUIET", NULL },
/* verbose, show warning messages */ /* verbose, show warning messages */
@ -306,9 +301,6 @@ static t_stat dsk_reset(DEVICE *dptr) {
*/ */
static t_stat dsk_boot(int32 unitno, DEVICE *dptr) { static t_stat dsk_boot(int32 unitno, DEVICE *dptr) {
if (cpu_unit.flags & (UNIT_ALTAIRROM | UNIT_BANKED)) { if (cpu_unit.flags & (UNIT_ALTAIRROM | UNIT_BANKED)) {
if (install_bootrom()) {
printf("ALTAIR boot ROM installed.\n");
}
/* check whether we are really modifying an LD A,<> instruction */ /* check whether we are really modifying an LD A,<> instruction */
if ((bootrom[UNIT_NO_OFFSET_1 - 1] == LDA_INSTRUCTION) && (bootrom[UNIT_NO_OFFSET_2 - 1] == LDA_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> */
@ -318,11 +310,48 @@ static t_stat dsk_boot(int32 unitno, DEVICE *dptr) {
printf("Incorrect boot ROM offsets detected.\n"); printf("Incorrect boot ROM offsets detected.\n");
return SCPE_IERR; return SCPE_IERR;
} }
install_bootrom(); /* install modified ROM */
} }
saved_PC = DEFAULT_ROM_LOW; saved_PC = DEFAULT_ROM_LOW;
return SCPE_OK; 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 /* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued. 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 */ /* 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 dsk12(const int32 port, const int32 io, const int32 data) {
int32 i; int32 i;
UNIT *uptr; UNIT *uptr;
@ -533,34 +557,3 @@ int32 dsk12(const int32 port, const int32 io, const int32 data) {
return 0; /* ignored since OUT */ 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

@ -91,7 +91,6 @@
#define CONTROLG_CHAR 0x07 /* control G char., rings bell when displayed */ #define CONTROLG_CHAR 0x07 /* control G char., rings bell when displayed */
#define CONTROLZ_CHAR 0x1a /* control Z character */ #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 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_timeron (UNIT *uptr, int32 value, char *cptr, void *desc);
static t_stat simh_dev_set_timeroff (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 sio_detach(UNIT *uptr);
static t_stat ptr_reset(DEVICE *dptr); static t_stat ptr_reset(DEVICE *dptr);
static t_stat ptp_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 nulldev (const int32 port, const int32 io, const int32 data);
int32 sr_dev (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); 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 sio0s (const int32 port, const int32 io, const int32 data);
int32 sio1d (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); 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); void printMessage(void);
static void warnNoRealTimeClock(void);
extern int32 getBankSelect(void); extern int32 getBankSelect(void);
extern void setBankSelect(const int32 b); extern void setBankSelect(const int32 b);
@ -352,7 +339,7 @@ DEVICE simh_device = {
NULL, NULL, NULL NULL, NULL, NULL
}; };
char messageBuffer[256]; char messageBuffer[256] = {};
void printMessage(void) { void printMessage(void) {
printf(messageBuffer); printf(messageBuffer);
@ -1092,7 +1079,7 @@ static int32 simh_out(const int32 port, const int32 data) {
hFind = FindFirstFile(cpmCommandLine, &FindFileData); hFind = FindFirstFile(cpmCommandLine, &FindFileData);
if (hFind == INVALID_HANDLE_VALUE) { if (hFind == INVALID_HANDLE_VALUE) {
if (simh_unit.flags & UNIT_SIMH_VERBOSE) { 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; globValid = FALSE;
} }

View file

@ -30,28 +30,19 @@
#include <ctype.h> #include <ctype.h>
#include "altairz80_defs.h" #include "altairz80_defs.h"
extern DEVICE cpu_dev;
extern DEVICE dsk_dev;
extern DEVICE hdsk_dev;
extern UNIT cpu_unit; extern UNIT cpu_unit;
extern REG cpu_reg[]; extern REG cpu_reg[];
extern DEVICE cpu_dev;
extern DEVICE sio_dev; extern DEVICE sio_dev;
extern DEVICE simh_device; extern DEVICE simh_device;
extern DEVICE ptr_dev; extern DEVICE ptr_dev;
extern DEVICE ptp_dev; extern DEVICE ptp_dev;
extern DEVICE dsk_dev;
extern DEVICE hdsk_dev;
extern DEVICE net_dev; extern DEVICE net_dev;
extern int32 saved_PC;
int32 fprint_sym(FILE *of, int32 addr, uint32 *val, UNIT *uptr, int32 sw); 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); 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 /* SCP data structures
sim_name simulator name string sim_name simulator name string
@ -59,7 +50,6 @@ static int32 checkXY(const char xy);
sim_emax number of words needed for examine sim_emax number of words needed for examine
sim_devices array of pointers to simulated devices sim_devices array of pointers to simulated devices
sim_stop_messages array of pointers to stop messages sim_stop_messages array of pointers to stop messages
sim_load binary loader
*/ */
char sim_name[] = "Altair 8800 (Z80)"; char sim_name[] = "Altair 8800 (Z80)";

View file

@ -27,22 +27,23 @@
*/ */
#include "altairz80_defs.h" #include "altairz80_defs.h"
#include <assert.h>
/* the following routines provided courtesy of Howard M. Harte */ /* The following routines are based on work from Howard M. Harte */
t_stat set_geom(UNIT *uptr, int32 val, char *cptr, void *desc); t_stat set_geom(UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat show_geom(FILE *st, UNIT *uptr, int32 val, void *desc); t_stat show_geom(FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat set_format(UNIT *uptr, int32 val, char *cptr, void *desc); t_stat set_format(UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat show_format(FILE *st, UNIT *uptr, int32 val, void *desc); t_stat show_format(FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat hdsk_attach(UNIT *uptr, char *cptr); t_stat hdsk_attach(UNIT *uptr, char *cptr);
#define UNIT_V_HDSKWLK (UNIT_V_UF + 0) /* write locked */ #define UNIT_V_HDSK_WLK (UNIT_V_UF + 0) /* write locked */
#define UNIT_HDSKWLK (1 << UNIT_V_HDSKWLK) #define UNIT_HDSK_WLK (1 << UNIT_V_HDSK_WLK)
#define UNIT_V_HDSK_VERBOSE (UNIT_V_UF + 1) /* verbose mode, i.e. show error messages */ #define UNIT_V_HDSK_VERBOSE (UNIT_V_UF + 1) /* verbose mode, i.e. show error messages */
#define UNIT_HDSK_VERBOSE (1 << UNIT_V_HDSK_VERBOSE) #define UNIT_HDSK_VERBOSE (1 << UNIT_V_HDSK_VERBOSE)
#define HDSK_MAX_SECTOR_SIZE 1024 /* size of sector */ #define HDSK_MAX_SECTOR_SIZE 1024 /* maximum size of a sector */
#define HDSK_SECTOR_SIZE u5 /* size of sector */ #define HDSK_SECTOR_SIZE u5 /* size of sector */
#define HDSK_SECTORS_PER_TRACK u4 /* sectors per track */ #define HDSK_SECTORS_PER_TRACK u4 /* sectors per track */
#define HDSK_MAX_TRACKS u3 /* number of tracks */ #define HDSK_NUMBER_OF_TRACKS u3 /* number of tracks */
#define HDSK_FORMAT_TYPE u6 /* Disk Format Type */ #define HDSK_FORMAT_TYPE u6 /* Disk Format Type */
#define HDSK_CAPACITY (2048*32*128) /* Default Altair HDSK Capacity */ #define HDSK_CAPACITY (2048*32*128) /* Default Altair HDSK Capacity */
#define HDSK_NUMBER 8 /* number of hard disks */ #define HDSK_NUMBER 8 /* number of hard disks */
@ -55,11 +56,11 @@ t_stat hdsk_attach (UNIT *uptr, char *cptr);
#define HDSK_WRITE 3 #define HDSK_WRITE 3
#define HDSK_PARAM 4 #define HDSK_PARAM 4
#define HDSK_BOOT_ADDRESS 0x5c00 #define HDSK_BOOT_ADDRESS 0x5c00
#define DPB_NAME_LENGTH 15
extern char messageBuffer[]; extern char messageBuffer[];
extern int32 PCX; extern int32 PCX;
extern UNIT cpu_unit; extern UNIT cpu_unit;
extern uint8 M[MAXMEMSIZE][MAXBANKS];
extern int32 saved_PC; extern int32 saved_PC;
extern int32 install_bootrom(void); extern int32 install_bootrom(void);
@ -71,14 +72,7 @@ extern uint8 GetBYTEWrapper(const uint32 Addr);
extern int32 bootrom[BOOTROM_SIZE]; extern int32 bootrom[BOOTROM_SIZE];
static t_stat hdsk_boot(int32 unitno, DEVICE *dptr); static t_stat hdsk_boot(int32 unitno, DEVICE *dptr);
static int32 hdsk_hasVerbose(void);
int32 hdsk_io(const int32 port, const int32 io, const int32 data); int32 hdsk_io(const int32 port, const int32 io, const int32 data);
static int32 hdsk_in(const int32 port);
static int32 hdsk_out(const int32 data);
static int32 checkParameters(void);
static int32 doSeek(void);
static int32 doRead(void);
static int32 doWrite(void);
static int32 hdskLastCommand = HDSK_NONE; static int32 hdskLastCommand = HDSK_NONE;
static int32 hdskCommandPosition = 0; static int32 hdskCommandPosition = 0;
@ -87,31 +81,33 @@ static int32 selectedDisk;
static int32 selectedSector; static int32 selectedSector;
static int32 selectedTrack; static int32 selectedTrack;
static int32 selectedDMA; static int32 selectedDMA;
static int32 hdskTrace; static int32 hdskTrace = FALSE;
typedef struct { typedef struct {
char name[16]; char name[DPB_NAME_LENGTH + 1]; /* name of CP/M disk parameter block */
t_addr capac; t_addr capac; /* capacity */
uint16 spt; uint16 spt; /* sectors per track */
uint8 bsh; uint8 bsh; /* data allocation block shift factor */
uint8 blm; uint8 blm; /* data allocation block mask */
uint8 exm; uint8 exm; /* extent mask */
uint16 dsm; uint16 dsm; /* maximum data block number */
uint16 drm; uint16 drm; /* total number of directory entries */
uint8 al0; uint8 al0; /* determine reserved directory blocks */
uint8 al1; uint8 al1; /* determine reserved directory blocks */
uint16 cks; uint16 cks; /* size of directory check vector */
uint16 off; uint16 off; /* number of reserved tracks */
uint8 psh; uint8 psh; /* physical record shift factor, CP/M 3 */
uint8 phm; uint8 phm; /* physical record mask, CP/M 3 */
} DPB; } DPB;
/* Note in the following CKS = 0 for fixed media which are not supposed to be changed while CP/M is executing */
static DPB dpb[] = { static DPB dpb[] = {
/* NAME CAPAC SPT BSH BLM EXM DSM DRM AL0 AL1 CKS OFF PSH PHM */ /* name capac spt bsh blm exm dsm drm al0 al1 cks off psh phm */
{ "HDSK", HDSK_CAPACITY, 32, 0x05, 0x1F, 0x01, 0x07f9, 0x03FF, 0xFF, 0x00, 0x8000, 0x0006, 0x00, 0x00 }, /* AZ80 HDSK */ { "HDSK", HDSK_CAPACITY, 32, 0x05, 0x1F, 0x01, 0x07f9, 0x03FF, 0xFF, 0x00, 0x0000, 0x0006, 0x00, 0x00 }, /* AZ80 HDSK */
{ "EZ80FL", 131072, 32, 0x03, 0x07, 0x00, 127, 0x003E, 0xC0, 0x00, 0x0000, 0x0000, 0x02, 0x03 }, /* 128K FLASH */ { "EZ80FL", 131072, 32, 0x03, 0x07, 0x00, 127, 0x003E, 0xC0, 0x00, 0x0000, 0x0000, 0x02, 0x03 }, /* 128K FLASH */
{ "P112", 1474560, 72, 0x04, 0x0F, 0x00, 710, 0x00FE, 0xF0, 0x00, 0x0000, 0x0002, 0x02, 0x03 }, /* 1.44M P112 */ { "P112", 1474560, 72, 0x04, 0x0F, 0x00, 710, 0x00FE, 0xF0, 0x00, 0x0000, 0x0002, 0x02, 0x03 }, /* 1.44M P112 */
{ "SU720", 737280, 36, 0x04, 0x0F, 0x00, 354, 0x007E, 0xC0, 0x00, 0x0020, 0x0002, 0x02, 0x03 }, /* 720K Super I/O */ { "SU720", 737280, 36, 0x04, 0x0F, 0x00, 354, 0x007E, 0xC0, 0x00, 0x0020, 0x0002, 0x02, 0x03 }, /* 720K Super I/O */
{ "SSSD8", 256256, 26, 0x03, 0x07, 0x00, 242, 0x003F, 0xC0, 0x00, 0x0000, 0x0002, 0x00, 0x00 }, /* Standard 8" SS SD */
{ "", 0 } { "", 0 }
}; };
@ -139,8 +135,8 @@ static REG hdsk_reg[] = {
static MTAB hdsk_mod[] = { static MTAB hdsk_mod[] = {
{ MTAB_XTD|MTAB_VUN|MTAB_VAL, 0, "FORMAT", "FORMAT", &set_format, &show_format, NULL }, { MTAB_XTD|MTAB_VUN|MTAB_VAL, 0, "FORMAT", "FORMAT", &set_format, &show_format, NULL },
{ UNIT_HDSKWLK, 0, "WRTENB", "WRTENB", NULL }, { UNIT_HDSK_WLK, 0, "WRTENB", "WRTENB", NULL },
{ UNIT_HDSKWLK, UNIT_HDSKWLK, "WRTLCK", "WRTLCK", NULL }, { UNIT_HDSK_WLK, UNIT_HDSK_WLK, "WRTLCK", "WRTLCK", NULL },
/* quiet, no warning messages */ /* quiet, no warning messages */
{ UNIT_HDSK_VERBOSE, 0, "QUIET", "QUIET", NULL }, { UNIT_HDSK_VERBOSE, 0, "QUIET", "QUIET", NULL },
/* verbose, show warning messages */ /* verbose, show warning messages */
@ -160,101 +156,116 @@ DEVICE hdsk_dev = {
/* Attach routine */ /* Attach routine */
t_stat hdsk_attach(UNIT *uptr, char *cptr) { t_stat hdsk_attach(UNIT *uptr, char *cptr) {
uint32 flen;
t_stat r; t_stat r;
int32 i; int32 i;
char unitChar;
r = attach_unit(uptr, cptr); /* attach unit */ r = attach_unit(uptr, cptr); /* attach unit */
if (r != SCPE_OK) return r; /* error? */ if ( r != SCPE_OK) /* error? */
if ((flen = sim_fsize (uptr->fileref)) == 0) { /* new disk image? */ return r;
if (uptr->flags & UNIT_RO) return SCPE_OK; /* if ro, done */
return SCPE_OK;
}
if(flen>0) { /* Step 1: Determine capacity of this disk */
uptr->capac = flen; uptr -> capac = sim_fsize(uptr -> fileref); /* the file length is a good candidate */
if (uptr -> capac == 0) { /* file does not exist or has length 0 */
uptr -> capac = uptr -> HDSK_NUMBER_OF_TRACKS *
uptr -> HDSK_SECTORS_PER_TRACK * uptr -> HDSK_SECTOR_SIZE;
if (uptr -> capac == 0)
uptr -> capac = HDSK_CAPACITY;
} /* post condition: uptr -> capac > 0 */
assert(uptr -> capac);
uptr->HDSK_FORMAT_TYPE = -1; /* Default to unknown format type */ /* Step 2: Determine format based on disk capacity */
uptr -> HDSK_FORMAT_TYPE = -1; /* default to unknown format type */
for(i=0; dpb[i].spt != 0; i++) { for (i = 0; dpb[i].capac != 0; i++) { /* find disk parameter block */
if(dpb[i].capac == uptr->capac) { if (dpb[i].capac == uptr -> capac) { /* found if correct capacity */
uptr -> HDSK_FORMAT_TYPE = i; uptr -> HDSK_FORMAT_TYPE = i;
break; break;
} }
} }
}
if(uptr->HDSK_FORMAT_TYPE == -1) { /* Step 3: Set number of sectors per track and sector size */
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; uptr -> HDSK_FORMAT_TYPE = 0;
uptr->capac = dpb[uptr->HDSK_FORMAT_TYPE].capac; printf("HDSK%c: WARNING: Unsupported disk capacity, assuming HDSK type with capacity %iKB.\n",
printf("HDSK: WARNING: Unsupported disk capacity, assuming HDSK type.\n"); unitChar, uptr -> capac / 1000);
uptr->flags |= UNIT_HDSKWLK; uptr -> flags |= UNIT_HDSK_WLK;
printf("HDSK: WARNING: Forcing WRTLCK.\n"); printf("HDSK%c: WARNING: Forcing WRTLCK.\n", unitChar);
if(uptr->capac != (uptr->HDSK_MAX_TRACKS * uptr->HDSK_SECTORS_PER_TRACK * uptr->HDSK_SECTOR_SIZE)) { /* check whether capacity corresponds to setting of tracks, sectors per track and sector size */
printf("HDSK: WARNING: Geometry may be incorrect.\n"); 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_SECTOR_SIZE = (128 << dpb[uptr->HDSK_FORMAT_TYPE].psh);
uptr -> HDSK_SECTORS_PER_TRACK = dpb[uptr -> HDSK_FORMAT_TYPE].spt >> dpb[uptr -> HDSK_FORMAT_TYPE].psh; uptr -> HDSK_SECTORS_PER_TRACK = dpb[uptr -> HDSK_FORMAT_TYPE].spt >> dpb[uptr -> HDSK_FORMAT_TYPE].psh;
uptr->HDSK_MAX_TRACKS = uptr->capac / (uptr->HDSK_SECTORS_PER_TRACK * uptr->HDSK_SECTOR_SIZE); uptr -> HDSK_SECTOR_SIZE = (128 << dpb[uptr -> HDSK_FORMAT_TYPE].psh);
}
assert(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; return SCPE_OK;
} }
/* Set disk geometry routine */ /* Set disk geometry routine */
t_stat set_geom(UNIT *uptr, int32 val, char *cptr, void *desc) { t_stat set_geom(UNIT *uptr, int32 val, char *cptr, void *desc) {
DEVICE *dptr; uint32 numberOfTracks, numberOfSectors, sectorSize;
int result, n;
uint32 ncyl, nsect, ssize;
if (cptr == NULL) return SCPE_ARG; if (cptr == NULL) return SCPE_ARG;
if (uptr == NULL) return SCPE_IERR; if (uptr == NULL) return SCPE_IERR;
dptr = find_dev_from_unit (uptr); result = sscanf(cptr, "%d/%d/%d%n", &numberOfTracks, &numberOfSectors, &sectorSize, &n);
if (dptr == NULL) return SCPE_IERR; if ((result != 3) || (result == EOF) || (cptr[n] != 0)) {
result = sscanf(cptr, "T:%d/N:%d/S:%d%n", &numberOfTracks, &numberOfSectors, &sectorSize, &n);
sscanf(cptr, "%d/%d/%d", &ncyl, &nsect, &ssize); if ((result != 3) || (result == EOF) || (cptr[n] != 0)) return SCPE_ARG;
uptr->HDSK_MAX_TRACKS = ncyl; }
uptr->HDSK_SECTORS_PER_TRACK = nsect; uptr -> HDSK_NUMBER_OF_TRACKS = numberOfTracks;
uptr->HDSK_SECTOR_SIZE = ssize; uptr -> HDSK_SECTORS_PER_TRACK = numberOfSectors;
uptr -> HDSK_SECTOR_SIZE = sectorSize;
uptr -> capac = numberOfTracks * numberOfSectors * sectorSize;
return SCPE_OK; return SCPE_OK;
} }
/* Show disk geometry routine */ /* Show disk geometry routine */
t_stat show_geom(FILE *st, UNIT *uptr, int32 val, void *desc) { t_stat show_geom(FILE *st, UNIT *uptr, int32 val, void *desc) {
DEVICE *dptr;
if (uptr == NULL) return SCPE_IERR; if (uptr == NULL) return SCPE_IERR;
dptr = find_dev_from_unit (uptr); fprintf(st, "T:%d/N:%d/S:%d", uptr -> HDSK_NUMBER_OF_TRACKS,
if (dptr == NULL) return SCPE_IERR; uptr -> HDSK_SECTORS_PER_TRACK, uptr -> HDSK_SECTOR_SIZE);
fprintf (st, "T:%d/N:%d/S:%d", uptr->HDSK_MAX_TRACKS, uptr->HDSK_SECTORS_PER_TRACK, uptr->u5);
return SCPE_OK; return SCPE_OK;
} }
#define QUOTE1(text) #text
#define QUOTE2(text) QUOTE1(text)
/* Set disk format routine */ /* Set disk format routine */
t_stat set_format(UNIT *uptr, int32 val, char *cptr, void *desc) { t_stat set_format(UNIT *uptr, int32 val, char *cptr, void *desc) {
DEVICE *dptr; char fmtname[DPB_NAME_LENGTH + 1];
char fmtname[16];
int32 i; int32 i;
if (cptr == NULL) return SCPE_ARG; if (cptr == NULL) return SCPE_ARG;
if (uptr == NULL) return SCPE_IERR; if (uptr == NULL) return SCPE_IERR;
dptr = find_dev_from_unit (uptr); if (sscanf(cptr, "%" QUOTE2(DPB_NAME_LENGTH) "s", fmtname) == 0) return SCPE_ARG;
if (dptr == NULL) return SCPE_IERR; for (i = 0; dpb[i].capac != 0; i++) {
if (strncmp(fmtname, dpb[i].name, strlen(fmtname)) == 0) {
sscanf(cptr, "%s", fmtname);
for(i=0;dpb[i].spt != 0;i++) {
if(!strncmp(fmtname, dpb[i].name, strlen(fmtname))) {
uptr -> HDSK_FORMAT_TYPE = i; uptr -> HDSK_FORMAT_TYPE = i;
uptr -> capac = dpb[i].capac; /* Set capacity */ uptr -> capac = dpb[i].capac; /* Set capacity */
/* Configure physical disk geometry */ /* Configure physical disk geometry */
uptr -> HDSK_SECTOR_SIZE = (128 << dpb[uptr -> HDSK_FORMAT_TYPE].psh); uptr -> HDSK_SECTOR_SIZE = (128 << dpb[uptr -> HDSK_FORMAT_TYPE].psh);
uptr -> HDSK_SECTORS_PER_TRACK = dpb[uptr -> HDSK_FORMAT_TYPE].spt >> dpb[uptr -> HDSK_FORMAT_TYPE].psh; uptr -> HDSK_SECTORS_PER_TRACK = dpb[uptr -> HDSK_FORMAT_TYPE].spt >> dpb[uptr -> HDSK_FORMAT_TYPE].psh;
uptr->HDSK_MAX_TRACKS = uptr->capac / (uptr->HDSK_SECTORS_PER_TRACK * uptr->HDSK_SECTOR_SIZE); uptr -> HDSK_NUMBER_OF_TRACKS = (uptr -> capac +
uptr -> HDSK_SECTORS_PER_TRACK * uptr -> HDSK_SECTOR_SIZE - 1) /
(uptr -> HDSK_SECTORS_PER_TRACK * uptr -> HDSK_SECTOR_SIZE);
return SCPE_OK; return SCPE_OK;
} }
@ -264,12 +275,8 @@ t_stat set_format (UNIT *uptr, int32 val, char *cptr, void *desc) {
/* Show disk format routine */ /* Show disk format routine */
t_stat show_format(FILE *st, UNIT *uptr, int32 val, void *desc) { t_stat show_format(FILE *st, UNIT *uptr, int32 val, void *desc) {
DEVICE *dptr;
if (uptr == NULL) return SCPE_IERR; if (uptr == NULL) return SCPE_IERR;
dptr = find_dev_from_unit (uptr);
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; return SCPE_OK;
} }
@ -315,9 +322,6 @@ static t_stat hdsk_boot(int32 unitno, DEVICE *dptr) {
return SCPE_ARG; return SCPE_ARG;
} }
if (cpu_unit.flags & (UNIT_ALTAIRROM | UNIT_BANKED)) { if (cpu_unit.flags & (UNIT_ALTAIRROM | UNIT_BANKED)) {
if (install_bootrom()) {
printf("ALTAIR boot ROM installed.\n");
}
/* check whether we are really modifying an LD A,<> instruction */ /* check whether we are really modifying an LD A,<> instruction */
if (bootrom[UNIT_NO_OFFSET_1 - 1] == LDA_INSTRUCTION) { if (bootrom[UNIT_NO_OFFSET_1 - 1] == LDA_INSTRUCTION) {
bootrom[UNIT_NO_OFFSET_1] = (unitno + NUM_OF_DSK) & 0xff; /* LD A,<unitno> */ bootrom[UNIT_NO_OFFSET_1] = (unitno + NUM_OF_DSK) & 0xff; /* LD A,<unitno> */
@ -326,6 +330,7 @@ static t_stat hdsk_boot(int32 unitno, DEVICE *dptr) {
printf("Incorrect boot ROM offset detected.\n"); printf("Incorrect boot ROM offset detected.\n");
return SCPE_IERR; return SCPE_IERR;
} }
install_bootrom(); /* install modified ROM */
} }
for (i = 0; i < BOOTROM_SIZE; i++) { for (i = 0; i < BOOTROM_SIZE; i++) {
PutBYTEBasic(i + HDSK_BOOT_ADDRESS, 0, hdskBoot[i] & 0xff); PutBYTEBasic(i + HDSK_BOOT_ADDRESS, 0, hdskBoot[i] & 0xff);
@ -339,7 +344,7 @@ static t_stat hdsk_boot(int32 unitno, DEVICE *dptr) {
static int32 hdsk_hasVerbose(void) { static int32 hdsk_hasVerbose(void) {
int32 i; int32 i;
for (i = 0; i < HDSK_NUMBER; i++) { for (i = 0; i < HDSK_NUMBER; i++) {
if (((hdsk_dev.units + i) -> flags) & UNIT_HDSK_VERBOSE) { if (hdsk_dev.units[i].flags & UNIT_HDSK_VERBOSE) {
return TRUE; return TRUE;
} }
} }
@ -398,7 +403,7 @@ static int32 hdsk_hasVerbose(void) {
/* check the parameters and return TRUE iff parameters are correct or have been repaired */ /* check the parameters and return TRUE iff parameters are correct or have been repaired */
static int32 checkParameters(void) { static int32 checkParameters(void) {
UNIT *uptr = hdsk_dev.units + selectedDisk; UNIT *uptr = &hdsk_dev.units[selectedDisk];
int32 currentFlag; int32 currentFlag;
if ((selectedDisk < 0) || (selectedDisk >= HDSK_NUMBER)) { if ((selectedDisk < 0) || (selectedDisk >= HDSK_NUMBER)) {
if (hdsk_hasVerbose()) { if (hdsk_hasVerbose()) {
@ -406,7 +411,7 @@ static int32 checkParameters(void) {
} }
selectedDisk = 0; selectedDisk = 0;
} }
currentFlag = (hdsk_dev.units + selectedDisk) -> flags; currentFlag = hdsk_dev.units[selectedDisk].flags;
if ((currentFlag & UNIT_ATT) == 0) { if ((currentFlag & UNIT_ATT) == 0) {
if (currentFlag & UNIT_HDSK_VERBOSE) { if (currentFlag & UNIT_HDSK_VERBOSE) {
MESSAGE_2("HDSK%d is not attached.", selectedDisk); MESSAGE_2("HDSK%d is not attached.", selectedDisk);
@ -420,10 +425,10 @@ static int32 checkParameters(void) {
} }
selectedSector = 0; selectedSector = 0;
} }
if ((selectedTrack < 0) || (selectedTrack >= uptr->HDSK_MAX_TRACKS)) { if ((selectedTrack < 0) || (selectedTrack >= uptr -> HDSK_NUMBER_OF_TRACKS)) {
if (currentFlag & UNIT_HDSK_VERBOSE) { if (currentFlag & UNIT_HDSK_VERBOSE) {
MESSAGE_4("HDSK%d: 0 <= Track=%04d < %04d violated, will use 0 instead.", MESSAGE_4("HDSK%d: 0 <= Track=%04d < %04d violated, will use 0 instead.",
selectedDisk, selectedTrack, uptr->HDSK_MAX_TRACKS); selectedDisk, selectedTrack, uptr -> HDSK_NUMBER_OF_TRACKS);
} }
selectedTrack = 0; selectedTrack = 0;
} }
@ -437,9 +442,10 @@ static int32 checkParameters(void) {
} }
static int32 doSeek(void) { static int32 doSeek(void) {
UNIT *uptr = hdsk_dev.units + selectedDisk; UNIT *uptr = &hdsk_dev.units[selectedDisk];
if (fseek(uptr -> fileref, if (fseek(uptr -> fileref,
(uptr->HDSK_SECTORS_PER_TRACK * uptr->HDSK_SECTOR_SIZE) * selectedTrack + (uptr->HDSK_SECTOR_SIZE * selectedSector), SEEK_SET)) { (uptr -> HDSK_SECTORS_PER_TRACK * uptr -> HDSK_SECTOR_SIZE) * selectedTrack +
(uptr -> HDSK_SECTOR_SIZE * selectedSector), SEEK_SET)) {
if ((uptr -> flags) & UNIT_HDSK_VERBOSE) { if ((uptr -> flags) & UNIT_HDSK_VERBOSE) {
MESSAGE_4("Could not access HDSK%d Sector=%02d Track=%04d.", MESSAGE_4("Could not access HDSK%d Sector=%02d Track=%04d.",
selectedDisk, selectedSector, selectedTrack); selectedDisk, selectedSector, selectedTrack);
@ -451,11 +457,11 @@ static int32 doSeek(void) {
} }
} }
uint8 hdskbuf[HDSK_MAX_SECTOR_SIZE]; /* data buffer */ uint8 hdskbuf[HDSK_MAX_SECTOR_SIZE] = {}; /* data buffer */
static int32 doRead(void) { static int32 doRead(void) {
int32 i; int32 i;
UNIT *uptr = hdsk_dev.units + selectedDisk; UNIT *uptr = &hdsk_dev.units[selectedDisk];
if (doSeek()) { if (doSeek()) {
return CPM_ERROR; return CPM_ERROR;
} }
@ -479,8 +485,8 @@ static int32 doRead(void) {
static int32 doWrite(void) { static int32 doWrite(void) {
int32 i; int32 i;
UNIT *uptr = hdsk_dev.units + selectedDisk; UNIT *uptr = &hdsk_dev.units[selectedDisk];
if (((uptr -> flags) & UNIT_HDSKWLK) == 0) { /* write enabled */ if (((uptr -> flags) & UNIT_HDSK_WLK) == 0) { /* write enabled */
if (doSeek()) { if (doSeek()) {
return CPM_ERROR; return CPM_ERROR;
} }
@ -506,7 +512,7 @@ static int32 doWrite(void) {
} }
static int32 hdsk_in(const int32 port) { static int32 hdsk_in(const int32 port) {
UNIT *uptr = hdsk_dev.units + selectedDisk; UNIT *uptr = &hdsk_dev.units[selectedDisk];
int32 result; int32 result;
if ((hdskCommandPosition == 6) && ((hdskLastCommand == HDSK_READ) || (hdskLastCommand == HDSK_WRITE))) { if ((hdskCommandPosition == 6) && ((hdskLastCommand == HDSK_READ) || (hdskLastCommand == HDSK_WRITE))) {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

22
scp.c
View file

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

View file

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

View file

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

View file

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

View file

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