Notes For V3.7
1. New Features 1.1 3.7-0 1.1.1 SCP - Added SET THROTTLE and SET NOTHROTTLE commands to regulate simulator execution rate and host resource utilization. - Added idle support (based on work by Mark Pizzolato). - Added -e to control error processing in nested DO commands (from Dave Bryan). 1.1.2 HP2100 - Added Double Integer instructions, 1000-F CPU, and Floating Point Processor (from Dave Bryan). - Added 2114 and 2115 CPUs, 12607B and 12578A DMA controllers, and 21xx binary loader protection (from Dave Bryan). 1.1.3 Interdata - Added SET IDLE and SET NOIDLE commands to idle the simulator in wait state. 1.1.4 PDP-11 - Added SET IDLE and SET NOIDLE commands to idle the simulator in wait state (WAIT instruction executed). - Added TA11/TU60 cassette support. 1.1.5 PDP-8 - Added SET IDLE and SET NOIDLE commands to idle the simulator in wait state (keyboard poll loop or jump-to-self). - Added TA8E/TU60 cassette support. 1.1.6 PDP-1 - Added support for 16-channel sequence break system. - Added support for PDP-1D extended features and timesharing clock. - Added support for Type 630 data communications subsystem. 1.1.6 PDP-4/7/9/15 - Added SET IDLE and SET NOIDLE commands to idle the simulator in wait state (keyboard poll loop or jump-to-self). 1.1.7 VAX, VAX780 - Added SET IDLE and SET NOIDLE commands to idle the simulator in wait state (more than 200 cycles at IPL's 0, 1, or 3 in kernel mode). 1.1.8 PDP-10 - Added SET IDLE and SET NOIDLE commands to idle the simulator in wait state (operating system dependent). - Added CD20 (CD11) support. 2. Bugs Fixed Please see the revision history on http://simh.trailing-edge.com or in the source module sim_rev.h.
This commit is contained in:
parent
53d02f7fa7
commit
6149cc7e06
57 changed files with 10269 additions and 9632 deletions
|
@ -1,4 +1,4 @@
|
|||
Notes For V3.7-0
|
||||
Notes For V3.7
|
||||
|
||||
|
||||
1. New Features
|
||||
|
|
|
@ -160,12 +160,6 @@ void PutBYTEWrapper(const uint32 Addr, const uint32 Value);
|
|||
int32 getBankSelect(void);
|
||||
void setBankSelect(const int32 b);
|
||||
uint32 getCommon(void);
|
||||
static void PutBYTEForced(uint32 Addr, const uint32 Value);
|
||||
static int32 addressIsInROM(const uint32 Addr);
|
||||
static int32 addressExists(const uint32 Addr);
|
||||
static void printROMMessage(const uint32 cntROM);
|
||||
static void warnUnsuccessfulWriteAttempt(const uint32 Addr);
|
||||
static uint8 warnUnsuccessfulReadAttempt(const uint32 Addr);
|
||||
static t_stat cpu_set_rom (UNIT *uptr, int32 value, char *cptr, void *desc);
|
||||
static t_stat cpu_set_norom (UNIT *uptr, int32 value, char *cptr, void *desc);
|
||||
static t_stat cpu_set_altairrom (UNIT *uptr, int32 value, char *cptr, void *desc);
|
||||
|
@ -173,15 +167,6 @@ static t_stat cpu_set_warnrom (UNIT *uptr, int32 value, char *cptr, void *desc
|
|||
static t_stat cpu_set_banked (UNIT *uptr, int32 value, char *cptr, void *desc);
|
||||
static t_stat cpu_set_nonbanked (UNIT *uptr, int32 value, char *cptr, void *desc);
|
||||
static t_stat cpu_set_size (UNIT *uptr, int32 value, char *cptr, void *desc);
|
||||
static void prepareMemoryAccessMessage(t_addr loc);
|
||||
static void checkROMBoundaries(void);
|
||||
static void reset_memory(void);
|
||||
static uint32 in(const uint32 Port);
|
||||
static void out(const uint32 Port, const uint32 Value);
|
||||
static void PutBYTE(register uint32 Addr, const register uint32 Value);
|
||||
static void PutWORD(register uint32 Addr, const register uint32 Value);
|
||||
static t_bool sim_brk_lookup (const t_addr bloc, const int32 btyp);
|
||||
static void resetCell(const int32 address, const int32 bank);
|
||||
|
||||
/* CPU data structures
|
||||
cpu_dev CPU device descriptor
|
||||
|
@ -194,7 +179,7 @@ UNIT cpu_unit = {
|
|||
UDATA (NULL, UNIT_FIX + UNIT_BINK + UNIT_ROM + UNIT_ALTAIRROM, MAXMEMSIZE)
|
||||
};
|
||||
|
||||
int32 PCX; /* external view of PC */
|
||||
int32 PCX = 0; /* external view of PC */
|
||||
int32 saved_PC = 0; /* program counter */
|
||||
static int32 AF_S; /* AF register */
|
||||
static int32 BC_S; /* BC register */
|
||||
|
@ -1183,7 +1168,7 @@ static const uint8 cpTable[256] = {
|
|||
128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
|
||||
};
|
||||
|
||||
/* remove comments to generate table contents
|
||||
/* remove comments to generate table contents and define globally NEED_SIM_VM_INIT
|
||||
static void altairz80_init(void);
|
||||
void (*sim_vm_init) (void) = &altairz80_init;
|
||||
static void altairz80_init(void) {
|
||||
|
@ -1467,6 +1452,16 @@ void protect(const int32 l, const int32 h) {
|
|||
|
||||
static uint8 M[MAXMEMSIZE][MAXBANKS]; /* RAM which is present */
|
||||
|
||||
/* determine whether Addr points to Read Only Memory */
|
||||
static int32 addressIsInROM(const uint32 Addr) {
|
||||
uint32 addr = Addr & ADDRMASK; /* registers are NOT guaranteed to be always 16-bit values */
|
||||
return (cpu_unit.flags & UNIT_ROM) && ( /* must have ROM enabled */
|
||||
/* in banked case we have standard Altair ROM */
|
||||
((cpu_unit.flags & UNIT_BANKED) && (DEFAULT_ROM_LOW <= addr)) ||
|
||||
/* in non-banked case we check the bounds of the ROM */
|
||||
(((cpu_unit.flags & UNIT_BANKED) == 0) && (ROMLow <= addr) && (addr <= ROMHigh)));
|
||||
}
|
||||
|
||||
static void warnUnsuccessfulWriteAttempt(const uint32 Addr) {
|
||||
if (cpu_unit.flags & UNIT_WARNROM) {
|
||||
if (addressIsInROM(Addr)) {
|
||||
|
@ -1485,18 +1480,8 @@ static uint8 warnUnsuccessfulReadAttempt(const uint32 Addr) {
|
|||
return 0xff;
|
||||
}
|
||||
|
||||
/* determine whether Addr points to Read Only Memory */
|
||||
int32 addressIsInROM(const uint32 Addr) {
|
||||
uint32 addr = Addr & ADDRMASK; /* registers are NOT guaranteed to be always 16-bit values */
|
||||
return (cpu_unit.flags & UNIT_ROM) && ( /* must have ROM enabled */
|
||||
/* in banked case we have standard Altair ROM */
|
||||
((cpu_unit.flags & UNIT_BANKED) && (DEFAULT_ROM_LOW <= addr)) ||
|
||||
/* in non-banked case we check the bounds of the ROM */
|
||||
(((cpu_unit.flags & UNIT_BANKED) == 0) && (ROMLow <= addr) && (addr <= ROMHigh)));
|
||||
}
|
||||
|
||||
/* determine whether Addr points to a valid memory address */
|
||||
int32 addressExists(const uint32 Addr) {
|
||||
static int32 addressExists(const uint32 Addr) {
|
||||
uint32 addr = Addr & ADDRMASK; /* registers are NOT guaranteed to be always 16-bit values */
|
||||
return (cpu_unit.flags & UNIT_BANKED) || (addr < MEMSIZE) ||
|
||||
( ((cpu_unit.flags & UNIT_BANKED) == 0) && (cpu_unit.flags & UNIT_ROM)
|
||||
|
@ -5019,6 +5004,7 @@ t_stat sim_instr (void) {
|
|||
tStates -= 5;
|
||||
acu = HIGH_REGISTER(AF);
|
||||
BC &= ADDRMASK;
|
||||
if (BC == 0) BC = 0x10000;
|
||||
do {
|
||||
tStates += 21;
|
||||
CHECK_BREAK_TWO_BYTES(HL, DE);
|
||||
|
@ -5033,6 +5019,7 @@ t_stat sim_instr (void) {
|
|||
tStates -= 5;
|
||||
acu = HIGH_REGISTER(AF);
|
||||
BC &= ADDRMASK;
|
||||
if (BC == 0) BC = 0x10000;
|
||||
do {
|
||||
tStates += 21;
|
||||
CHECK_BREAK_BYTE(HL);
|
||||
|
@ -5053,6 +5040,7 @@ t_stat sim_instr (void) {
|
|||
case 0xb2: /* INIR */
|
||||
tStates -= 5;
|
||||
temp = HIGH_REGISTER(BC);
|
||||
if (temp == 0) temp = 0x100;
|
||||
do {
|
||||
tStates += 21;
|
||||
CHECK_BREAK_BYTE(HL);
|
||||
|
@ -5067,6 +5055,7 @@ t_stat sim_instr (void) {
|
|||
case 0xb3: /* OTIR */
|
||||
tStates -= 5;
|
||||
temp = HIGH_REGISTER(BC);
|
||||
if (temp == 0) temp = 0x100;
|
||||
do {
|
||||
tStates += 21;
|
||||
CHECK_BREAK_BYTE(HL);
|
||||
|
@ -5081,6 +5070,7 @@ t_stat sim_instr (void) {
|
|||
case 0xb8: /* LDDR */
|
||||
tStates -= 5;
|
||||
BC &= ADDRMASK;
|
||||
if (BC == 0) BC = 0x10000;
|
||||
do {
|
||||
tStates += 21;
|
||||
CHECK_BREAK_TWO_BYTES(HL, DE);
|
||||
|
@ -5095,6 +5085,7 @@ t_stat sim_instr (void) {
|
|||
tStates -= 5;
|
||||
acu = HIGH_REGISTER(AF);
|
||||
BC &= ADDRMASK;
|
||||
if (BC == 0) BC = 0x10000;
|
||||
do {
|
||||
tStates += 21;
|
||||
CHECK_BREAK_BYTE(HL);
|
||||
|
@ -5115,6 +5106,7 @@ t_stat sim_instr (void) {
|
|||
case 0xba: /* INDR */
|
||||
tStates -= 5;
|
||||
temp = HIGH_REGISTER(BC);
|
||||
if (temp == 0) temp = 0x100;
|
||||
do {
|
||||
tStates += 21;
|
||||
CHECK_BREAK_BYTE(HL);
|
||||
|
@ -5129,6 +5121,7 @@ t_stat sim_instr (void) {
|
|||
case 0xbb: /* OTDR */
|
||||
tStates -= 5;
|
||||
temp = HIGH_REGISTER(BC);
|
||||
if (temp == 0) temp = 0x100;
|
||||
do {
|
||||
tStates += 21;
|
||||
CHECK_BREAK_BYTE(HL);
|
||||
|
@ -6061,6 +6054,27 @@ t_stat sim_instr (void) {
|
|||
return reason;
|
||||
}
|
||||
|
||||
static void checkROMBoundaries(void) {
|
||||
uint32 temp;
|
||||
if (ROMLow > ROMHigh) {
|
||||
printf("ROMLOW [%04X] must be less than or equal to ROMHIGH [%04X]. Values exchanged.\n",
|
||||
ROMLow, ROMHigh);
|
||||
temp = ROMLow;
|
||||
ROMLow = ROMHigh;
|
||||
ROMHigh = temp;
|
||||
}
|
||||
if (cpu_unit.flags & UNIT_ALTAIRROM) {
|
||||
if (DEFAULT_ROM_LOW < ROMLow) {
|
||||
printf("ROMLOW [%04X] reset to %04X since Altair ROM was desired.\n", ROMLow, DEFAULT_ROM_LOW);
|
||||
ROMLow = DEFAULT_ROM_LOW;
|
||||
}
|
||||
if (ROMHigh < DEFAULT_ROM_HIGH) {
|
||||
printf("ROMHIGH [%04X] reset to %04X since Altair ROM was desired.\n", ROMHigh, DEFAULT_ROM_HIGH);
|
||||
ROMHigh = DEFAULT_ROM_HIGH;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void reset_memory(void) {
|
||||
uint32 i, j;
|
||||
checkROMBoundaries();
|
||||
|
@ -6090,7 +6104,7 @@ static void reset_memory(void) {
|
|||
isProtected = FALSE;
|
||||
}
|
||||
|
||||
void printROMMessage(const uint32 cntROM) {
|
||||
static void printROMMessage(const uint32 cntROM) {
|
||||
if (cntROM) {
|
||||
printf("Warning: %d bytes written to ROM [%04X - %04X].\n", cntROM, ROMLow, ROMHigh);
|
||||
}
|
||||
|
@ -6124,27 +6138,6 @@ t_stat cpu_reset(DEVICE *dptr) {
|
|||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static void checkROMBoundaries(void) {
|
||||
uint32 temp;
|
||||
if (ROMLow > ROMHigh) {
|
||||
printf("ROMLOW [%04X] must be less than or equal to ROMHIGH [%04X]. Values exchanged.\n",
|
||||
ROMLow, ROMHigh);
|
||||
temp = ROMLow;
|
||||
ROMLow = ROMHigh;
|
||||
ROMHigh = temp;
|
||||
}
|
||||
if (cpu_unit.flags & UNIT_ALTAIRROM) {
|
||||
if (DEFAULT_ROM_LOW < ROMLow) {
|
||||
printf("ROMLOW [%04X] reset to %04X since Altair ROM was desired.\n", ROMLow, DEFAULT_ROM_LOW);
|
||||
ROMLow = DEFAULT_ROM_LOW;
|
||||
}
|
||||
if (ROMHigh < DEFAULT_ROM_HIGH) {
|
||||
printf("ROMHIGH [%04X] reset to %04X since Altair ROM was desired.\n", ROMHigh, DEFAULT_ROM_HIGH);
|
||||
ROMHigh = DEFAULT_ROM_HIGH;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static t_stat cpu_set_rom(UNIT *uptr, int32 value, char *cptr, void *desc) {
|
||||
checkROMBoundaries();
|
||||
return SCPE_OK;
|
||||
|
|
|
@ -110,8 +110,8 @@
|
|||
|
||||
#include "altairz80_defs.h"
|
||||
|
||||
#define UNIT_V_DSKWLK (UNIT_V_UF + 0) /* write locked */
|
||||
#define UNIT_DSKWLK (1 << UNIT_V_DSKWLK)
|
||||
#define UNIT_V_DSK_WLK (UNIT_V_UF + 0) /* write locked */
|
||||
#define UNIT_DSK_WLK (1 << UNIT_V_DSK_WLK)
|
||||
#define UNIT_V_DSK_VERBOSE (UNIT_V_UF + 1) /* verbose mode, i.e. show error messages */
|
||||
#define UNIT_DSK_VERBOSE (1 << UNIT_V_DSK_VERBOSE)
|
||||
#define DSK_SECTSIZE 137 /* size of sector */
|
||||
|
@ -129,18 +129,12 @@
|
|||
int32 dsk10(const int32 port, const int32 io, const int32 data);
|
||||
int32 dsk11(const int32 port, const int32 io, const int32 data);
|
||||
int32 dsk12(const int32 port, const int32 io, const int32 data);
|
||||
static int32 dskseek(const UNIT *xptr);
|
||||
static t_stat dsk_boot(int32 unitno, DEVICE *dptr);
|
||||
static t_stat dsk_reset(DEVICE *dptr);
|
||||
static void writebuf(void);
|
||||
static t_stat dsk_set_verbose(UNIT *uptr, int32 value, char *cptr, void *desc);
|
||||
static void resetDSKWarningFlags(void);
|
||||
static int32 hasVerbose(void);
|
||||
static char* selectInOut(const int32 io);
|
||||
|
||||
extern int32 PCX;
|
||||
extern int32 saved_PC;
|
||||
extern FILE *sim_log;
|
||||
extern char messageBuffer[];
|
||||
extern UNIT cpu_unit;
|
||||
|
||||
|
@ -149,8 +143,9 @@ extern int32 install_bootrom(void);
|
|||
|
||||
/* global data on status */
|
||||
|
||||
static int32 current_disk = NUM_OF_DSK; /* currently selected drive (values are 0 .. NUM_OF_DSK)
|
||||
/* currently selected drive (values are 0 .. NUM_OF_DSK)
|
||||
current_disk < NUM_OF_DSK implies that the corresponding disk is attached to a file */
|
||||
static int32 current_disk = NUM_OF_DSK;
|
||||
static int32 current_track [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
static int32 current_sector [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
static int32 current_byte [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
@ -240,8 +235,8 @@ static REG dsk_reg[] = {
|
|||
};
|
||||
|
||||
static MTAB dsk_mod[] = {
|
||||
{ UNIT_DSKWLK, 0, "write enabled", "WRITEENABLED", NULL },
|
||||
{ UNIT_DSKWLK, UNIT_DSKWLK, "write locked", "LOCKED", NULL },
|
||||
{ UNIT_DSK_WLK, 0, "WRTENB", "WRTENB", NULL },
|
||||
{ UNIT_DSK_WLK, UNIT_DSK_WLK, "WRTLCK", "WRTLCK", NULL },
|
||||
/* quiet, no warning messages */
|
||||
{ UNIT_DSK_VERBOSE, 0, "QUIET", "QUIET", NULL },
|
||||
/* verbose, show warning messages */
|
||||
|
@ -306,9 +301,6 @@ static t_stat dsk_reset(DEVICE *dptr) {
|
|||
*/
|
||||
static t_stat dsk_boot(int32 unitno, DEVICE *dptr) {
|
||||
if (cpu_unit.flags & (UNIT_ALTAIRROM | UNIT_BANKED)) {
|
||||
if (install_bootrom()) {
|
||||
printf("ALTAIR boot ROM installed.\n");
|
||||
}
|
||||
/* check whether we are really modifying an LD A,<> instruction */
|
||||
if ((bootrom[UNIT_NO_OFFSET_1 - 1] == LDA_INSTRUCTION) && (bootrom[UNIT_NO_OFFSET_2 - 1] == LDA_INSTRUCTION)) {
|
||||
bootrom[UNIT_NO_OFFSET_1] = unitno & 0xff; /* LD A,<unitno> */
|
||||
|
@ -318,11 +310,48 @@ static t_stat dsk_boot(int32 unitno, DEVICE *dptr) {
|
|||
printf("Incorrect boot ROM offsets detected.\n");
|
||||
return SCPE_IERR;
|
||||
}
|
||||
install_bootrom(); /* install modified ROM */
|
||||
}
|
||||
saved_PC = DEFAULT_ROM_LOW;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static int32 dskseek(const UNIT *xptr) {
|
||||
return fseek(xptr -> fileref, DSK_TRACSIZE * current_track[current_disk] +
|
||||
DSK_SECTSIZE * current_sector[current_disk], SEEK_SET);
|
||||
}
|
||||
|
||||
/* precondition: current_disk < NUM_OF_DSK */
|
||||
static void writebuf(void) {
|
||||
int32 i, rtn;
|
||||
UNIT *uptr;
|
||||
i = current_byte[current_disk]; /* null-fill rest of sector if any */
|
||||
while (i < DSK_SECTSIZE) {
|
||||
dskbuf[i++] = 0;
|
||||
}
|
||||
uptr = dsk_dev.units + current_disk;
|
||||
if (((uptr -> flags) & UNIT_DSK_WLK) == 0) { /* write enabled */
|
||||
if (trace_flag & TRACE_READ_WRITE) {
|
||||
MESSAGE_4("OUT 0x0a (WRITE) D%d T%d S%d", current_disk, current_track[current_disk], current_sector[current_disk]);
|
||||
}
|
||||
if (dskseek(uptr)) {
|
||||
MESSAGE_4("fseek failed D%d T%d S%d", current_disk, current_track[current_disk], current_sector[current_disk]);
|
||||
}
|
||||
rtn = fwrite(dskbuf, DSK_SECTSIZE, 1, uptr -> fileref);
|
||||
if (rtn != 1) {
|
||||
MESSAGE_4("fwrite failed T%d S%d Return=%d", current_track[current_disk], current_sector[current_disk], rtn);
|
||||
}
|
||||
}
|
||||
else if ( ((uptr -> flags) & UNIT_DSK_VERBOSE) && (warnLock[current_disk] < warnLevelDSK) ) {
|
||||
/* write locked - print warning message if required */
|
||||
warnLock[current_disk]++;
|
||||
/*05*/ MESSAGE_2("Attempt to write to locked DSK%d - ignored.", current_disk);
|
||||
}
|
||||
current_flag[current_disk] &= 0xfe; /* ENWD off */
|
||||
current_byte[current_disk] = 0xff;
|
||||
dirty = FALSE;
|
||||
}
|
||||
|
||||
/* I/O instruction handlers, called from the CPU module when an
|
||||
IN or OUT instruction is issued.
|
||||
|
||||
|
@ -487,11 +516,6 @@ int32 dsk11(const int32 port, const int32 io, const int32 data) {
|
|||
|
||||
/* Disk Data In/Out */
|
||||
|
||||
static int32 dskseek(const UNIT *xptr) {
|
||||
return fseek(xptr -> fileref, DSK_TRACSIZE * current_track[current_disk] +
|
||||
DSK_SECTSIZE * current_sector[current_disk], SEEK_SET);
|
||||
}
|
||||
|
||||
int32 dsk12(const int32 port, const int32 io, const int32 data) {
|
||||
int32 i;
|
||||
UNIT *uptr;
|
||||
|
@ -533,34 +557,3 @@ int32 dsk12(const int32 port, const int32 io, const int32 data) {
|
|||
return 0; /* ignored since OUT */
|
||||
}
|
||||
}
|
||||
|
||||
/* precondition: current_disk < NUM_OF_DSK */
|
||||
static void writebuf(void) {
|
||||
int32 i, rtn;
|
||||
UNIT *uptr;
|
||||
i = current_byte[current_disk]; /* null-fill rest of sector if any */
|
||||
while (i < DSK_SECTSIZE) {
|
||||
dskbuf[i++] = 0;
|
||||
}
|
||||
uptr = dsk_dev.units + current_disk;
|
||||
if (((uptr -> flags) & UNIT_DSKWLK) == 0) { /* write enabled */
|
||||
if (trace_flag & TRACE_READ_WRITE) {
|
||||
MESSAGE_4("OUT 0x0a (WRITE) D%d T%d S%d", current_disk, current_track[current_disk], current_sector[current_disk]);
|
||||
}
|
||||
if (dskseek(uptr)) {
|
||||
MESSAGE_4("fseek failed D%d T%d S%d", current_disk, current_track[current_disk], current_sector[current_disk]);
|
||||
}
|
||||
rtn = fwrite(dskbuf, DSK_SECTSIZE, 1, uptr -> fileref);
|
||||
if (rtn != 1) {
|
||||
MESSAGE_4("fwrite failed T%d S%d Return=%d", current_track[current_disk], current_sector[current_disk], rtn);
|
||||
}
|
||||
}
|
||||
else if ( ((uptr -> flags) & UNIT_DSK_VERBOSE) && (warnLock[current_disk] < warnLevelDSK) ) {
|
||||
/* write locked - print warning message if required */
|
||||
warnLock[current_disk]++;
|
||||
/*05*/ MESSAGE_2("Attempt to write to locked DSK%d - ignored.", current_disk);
|
||||
}
|
||||
current_flag[current_disk] &= 0xfe; /* ENWD off */
|
||||
current_byte[current_disk] = 0xff;
|
||||
dirty = FALSE;
|
||||
}
|
||||
|
|
|
@ -91,7 +91,6 @@
|
|||
#define CONTROLG_CHAR 0x07 /* control G char., rings bell when displayed */
|
||||
#define CONTROLZ_CHAR 0x1a /* control Z character */
|
||||
|
||||
static void resetSIOWarningFlags(void);
|
||||
static t_stat sio_set_verbose (UNIT *uptr, int32 value, char *cptr, void *desc);
|
||||
static t_stat simh_dev_set_timeron (UNIT *uptr, int32 value, char *cptr, void *desc);
|
||||
static t_stat simh_dev_set_timeroff (UNIT *uptr, int32 value, char *cptr, void *desc);
|
||||
|
@ -100,6 +99,8 @@ static t_stat sio_attach(UNIT *uptr, char *cptr);
|
|||
static t_stat sio_detach(UNIT *uptr);
|
||||
static t_stat ptr_reset(DEVICE *dptr);
|
||||
static t_stat ptp_reset(DEVICE *dptr);
|
||||
static t_stat simh_dev_reset(DEVICE *dptr);
|
||||
static t_stat simh_svc(UNIT *uptr);
|
||||
int32 nulldev (const int32 port, const int32 io, const int32 data);
|
||||
int32 sr_dev (const int32 port, const int32 io, const int32 data);
|
||||
int32 simh_dev (const int32 port, const int32 io, const int32 data);
|
||||
|
@ -107,21 +108,7 @@ int32 sio0d (const int32 port, const int32 io, const int32 data);
|
|||
int32 sio0s (const int32 port, const int32 io, const int32 data);
|
||||
int32 sio1d (const int32 port, const int32 io, const int32 data);
|
||||
int32 sio1s (const int32 port, const int32 io, const int32 data);
|
||||
static int32 mapCharacter(int32 ch);
|
||||
static void pollConnection(void);
|
||||
static t_stat simh_dev_reset(DEVICE *dptr);
|
||||
static t_stat simh_svc(UNIT *uptr);
|
||||
static int32 simh_in(const int32 port);
|
||||
static int32 simh_out(const int32 port, const int32 data);
|
||||
static void createCPMCommandLine(void);
|
||||
static void attachCPM(UNIT *uptr);
|
||||
static void setClockZSDOS(void);
|
||||
static void setClockCPM3(void);
|
||||
static time_t mkCPM3Origin(void);
|
||||
static int32 toBCD(const int32 x);
|
||||
static int32 fromBCD(const int32 x);
|
||||
void printMessage(void);
|
||||
static void warnNoRealTimeClock(void);
|
||||
|
||||
extern int32 getBankSelect(void);
|
||||
extern void setBankSelect(const int32 b);
|
||||
|
@ -352,7 +339,7 @@ DEVICE simh_device = {
|
|||
NULL, NULL, NULL
|
||||
};
|
||||
|
||||
char messageBuffer[256];
|
||||
char messageBuffer[256] = {};
|
||||
|
||||
void printMessage(void) {
|
||||
printf(messageBuffer);
|
||||
|
@ -1092,7 +1079,7 @@ static int32 simh_out(const int32 port, const int32 data) {
|
|||
hFind = FindFirstFile(cpmCommandLine, &FindFileData);
|
||||
if (hFind == INVALID_HANDLE_VALUE) {
|
||||
if (simh_unit.flags & UNIT_SIMH_VERBOSE) {
|
||||
MESSAGE_3("Cannot expand '%s'. Error is %u.", cpmCommandLine, GetLastError());
|
||||
MESSAGE_3("Cannot expand '%s'. Error is %lu.", cpmCommandLine, GetLastError());
|
||||
}
|
||||
globValid = FALSE;
|
||||
}
|
||||
|
|
|
@ -30,28 +30,19 @@
|
|||
#include <ctype.h>
|
||||
#include "altairz80_defs.h"
|
||||
|
||||
extern DEVICE cpu_dev;
|
||||
extern DEVICE dsk_dev;
|
||||
extern DEVICE hdsk_dev;
|
||||
extern UNIT cpu_unit;
|
||||
extern REG cpu_reg[];
|
||||
extern DEVICE cpu_dev;
|
||||
extern DEVICE sio_dev;
|
||||
extern DEVICE simh_device;
|
||||
extern DEVICE ptr_dev;
|
||||
extern DEVICE ptp_dev;
|
||||
extern DEVICE dsk_dev;
|
||||
extern DEVICE hdsk_dev;
|
||||
extern DEVICE net_dev;
|
||||
extern int32 saved_PC;
|
||||
|
||||
int32 fprint_sym(FILE *of, int32 addr, uint32 *val, UNIT *uptr, int32 sw);
|
||||
static int32 checkbase(char ch, const char *numString);
|
||||
static int32 numok(char ch, const char **numString, const int32 minvalue,
|
||||
const int32 maxvalue, const int32 requireSign, int32 *result);
|
||||
static int32 match(const char *pattern, const char *input, char *xyFirst, char *xy, int32 *number, int32 *star, int32 *at,
|
||||
int32 *hat, int32 *dollar);
|
||||
static int32 parse_X80(const char *cptr, const int32 addr, uint32 *val, char *const Mnemonics[]);
|
||||
int32 parse_sym(char *cptr, int32 addr, UNIT *uptr, uint32 *val, int32 sw);
|
||||
static int32 DAsm(char *S, const uint32 *val, const int32 useZ80Mnemonics, const int32 addr);
|
||||
static int32 checkXY(const char xy);
|
||||
|
||||
/* SCP data structures
|
||||
sim_name simulator name string
|
||||
|
@ -59,7 +50,6 @@ static int32 checkXY(const char xy);
|
|||
sim_emax number of words needed for examine
|
||||
sim_devices array of pointers to simulated devices
|
||||
sim_stop_messages array of pointers to stop messages
|
||||
sim_load binary loader
|
||||
*/
|
||||
|
||||
char sim_name[] = "Altair 8800 (Z80)";
|
||||
|
|
|
@ -27,22 +27,23 @@
|
|||
*/
|
||||
|
||||
#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 show_geom(FILE *st, UNIT *uptr, int32 val, void *desc);
|
||||
t_stat set_format(UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
t_stat show_format(FILE *st, UNIT *uptr, int32 val, void *desc);
|
||||
t_stat hdsk_attach(UNIT *uptr, char *cptr);
|
||||
|
||||
#define UNIT_V_HDSKWLK (UNIT_V_UF + 0) /* write locked */
|
||||
#define UNIT_HDSKWLK (1 << UNIT_V_HDSKWLK)
|
||||
#define UNIT_V_HDSK_WLK (UNIT_V_UF + 0) /* write locked */
|
||||
#define UNIT_HDSK_WLK (1 << UNIT_V_HDSK_WLK)
|
||||
#define UNIT_V_HDSK_VERBOSE (UNIT_V_UF + 1) /* verbose mode, i.e. show error messages */
|
||||
#define UNIT_HDSK_VERBOSE (1 << UNIT_V_HDSK_VERBOSE)
|
||||
#define HDSK_MAX_SECTOR_SIZE 1024 /* size of sector */
|
||||
#define HDSK_MAX_SECTOR_SIZE 1024 /* maximum size of a sector */
|
||||
#define HDSK_SECTOR_SIZE u5 /* size of sector */
|
||||
#define HDSK_SECTORS_PER_TRACK u4 /* sectors per track */
|
||||
#define HDSK_MAX_TRACKS u3 /* number of tracks */
|
||||
#define HDSK_NUMBER_OF_TRACKS u3 /* number of tracks */
|
||||
#define HDSK_FORMAT_TYPE u6 /* Disk Format Type */
|
||||
#define HDSK_CAPACITY (2048*32*128) /* Default Altair HDSK Capacity */
|
||||
#define HDSK_NUMBER 8 /* number of hard disks */
|
||||
|
@ -55,11 +56,11 @@ t_stat hdsk_attach (UNIT *uptr, char *cptr);
|
|||
#define HDSK_WRITE 3
|
||||
#define HDSK_PARAM 4
|
||||
#define HDSK_BOOT_ADDRESS 0x5c00
|
||||
#define DPB_NAME_LENGTH 15
|
||||
|
||||
extern char messageBuffer[];
|
||||
extern int32 PCX;
|
||||
extern UNIT cpu_unit;
|
||||
extern uint8 M[MAXMEMSIZE][MAXBANKS];
|
||||
extern int32 saved_PC;
|
||||
|
||||
extern int32 install_bootrom(void);
|
||||
|
@ -71,14 +72,7 @@ extern uint8 GetBYTEWrapper(const uint32 Addr);
|
|||
extern int32 bootrom[BOOTROM_SIZE];
|
||||
|
||||
static t_stat hdsk_boot(int32 unitno, DEVICE *dptr);
|
||||
static int32 hdsk_hasVerbose(void);
|
||||
int32 hdsk_io(const int32 port, const int32 io, const int32 data);
|
||||
static int32 hdsk_in(const int32 port);
|
||||
static int32 hdsk_out(const int32 data);
|
||||
static int32 checkParameters(void);
|
||||
static int32 doSeek(void);
|
||||
static int32 doRead(void);
|
||||
static int32 doWrite(void);
|
||||
|
||||
static int32 hdskLastCommand = HDSK_NONE;
|
||||
static int32 hdskCommandPosition = 0;
|
||||
|
@ -87,31 +81,33 @@ static int32 selectedDisk;
|
|||
static int32 selectedSector;
|
||||
static int32 selectedTrack;
|
||||
static int32 selectedDMA;
|
||||
static int32 hdskTrace;
|
||||
static int32 hdskTrace = FALSE;
|
||||
|
||||
typedef struct {
|
||||
char name[16];
|
||||
t_addr capac;
|
||||
uint16 spt;
|
||||
uint8 bsh;
|
||||
uint8 blm;
|
||||
uint8 exm;
|
||||
uint16 dsm;
|
||||
uint16 drm;
|
||||
uint8 al0;
|
||||
uint8 al1;
|
||||
uint16 cks;
|
||||
uint16 off;
|
||||
uint8 psh;
|
||||
uint8 phm;
|
||||
char name[DPB_NAME_LENGTH + 1]; /* name of CP/M disk parameter block */
|
||||
t_addr capac; /* capacity */
|
||||
uint16 spt; /* sectors per track */
|
||||
uint8 bsh; /* data allocation block shift factor */
|
||||
uint8 blm; /* data allocation block mask */
|
||||
uint8 exm; /* extent mask */
|
||||
uint16 dsm; /* maximum data block number */
|
||||
uint16 drm; /* total number of directory entries */
|
||||
uint8 al0; /* determine reserved directory blocks */
|
||||
uint8 al1; /* determine reserved directory blocks */
|
||||
uint16 cks; /* size of directory check vector */
|
||||
uint16 off; /* number of reserved tracks */
|
||||
uint8 psh; /* physical record shift factor, CP/M 3 */
|
||||
uint8 phm; /* physical record mask, CP/M 3 */
|
||||
} DPB;
|
||||
|
||||
/* Note in the following CKS = 0 for fixed media which are not supposed to be changed while CP/M is executing */
|
||||
static DPB dpb[] = {
|
||||
/* NAME CAPAC SPT BSH BLM EXM DSM DRM AL0 AL1 CKS OFF PSH PHM */
|
||||
{ "HDSK", HDSK_CAPACITY, 32, 0x05, 0x1F, 0x01, 0x07f9, 0x03FF, 0xFF, 0x00, 0x8000, 0x0006, 0x00, 0x00 }, /* AZ80 HDSK */
|
||||
/* name capac spt bsh blm exm dsm drm al0 al1 cks off psh phm */
|
||||
{ "HDSK", HDSK_CAPACITY, 32, 0x05, 0x1F, 0x01, 0x07f9, 0x03FF, 0xFF, 0x00, 0x0000, 0x0006, 0x00, 0x00 }, /* AZ80 HDSK */
|
||||
{ "EZ80FL", 131072, 32, 0x03, 0x07, 0x00, 127, 0x003E, 0xC0, 0x00, 0x0000, 0x0000, 0x02, 0x03 }, /* 128K FLASH */
|
||||
{ "P112", 1474560, 72, 0x04, 0x0F, 0x00, 710, 0x00FE, 0xF0, 0x00, 0x0000, 0x0002, 0x02, 0x03 }, /* 1.44M P112 */
|
||||
{ "SU720", 737280, 36, 0x04, 0x0F, 0x00, 354, 0x007E, 0xC0, 0x00, 0x0020, 0x0002, 0x02, 0x03 }, /* 720K Super I/O */
|
||||
{ "SSSD8", 256256, 26, 0x03, 0x07, 0x00, 242, 0x003F, 0xC0, 0x00, 0x0000, 0x0002, 0x00, 0x00 }, /* Standard 8" SS SD */
|
||||
{ "", 0 }
|
||||
};
|
||||
|
||||
|
@ -139,8 +135,8 @@ static REG hdsk_reg[] = {
|
|||
|
||||
static MTAB hdsk_mod[] = {
|
||||
{ MTAB_XTD|MTAB_VUN|MTAB_VAL, 0, "FORMAT", "FORMAT", &set_format, &show_format, NULL },
|
||||
{ UNIT_HDSKWLK, 0, "WRTENB", "WRTENB", NULL },
|
||||
{ UNIT_HDSKWLK, UNIT_HDSKWLK, "WRTLCK", "WRTLCK", NULL },
|
||||
{ UNIT_HDSK_WLK, 0, "WRTENB", "WRTENB", NULL },
|
||||
{ UNIT_HDSK_WLK, UNIT_HDSK_WLK, "WRTLCK", "WRTLCK", NULL },
|
||||
/* quiet, no warning messages */
|
||||
{ UNIT_HDSK_VERBOSE, 0, "QUIET", "QUIET", NULL },
|
||||
/* verbose, show warning messages */
|
||||
|
@ -160,101 +156,116 @@ DEVICE hdsk_dev = {
|
|||
|
||||
/* Attach routine */
|
||||
t_stat hdsk_attach(UNIT *uptr, char *cptr) {
|
||||
uint32 flen;
|
||||
t_stat r;
|
||||
int32 i;
|
||||
char unitChar;
|
||||
|
||||
r = attach_unit(uptr, cptr); /* attach unit */
|
||||
if (r != SCPE_OK) return r; /* error? */
|
||||
if ((flen = sim_fsize (uptr->fileref)) == 0) { /* new disk image? */
|
||||
if (uptr->flags & UNIT_RO) return SCPE_OK; /* if ro, done */
|
||||
return SCPE_OK;
|
||||
}
|
||||
if ( r != SCPE_OK) /* error? */
|
||||
return r;
|
||||
|
||||
if(flen>0) {
|
||||
uptr->capac = flen;
|
||||
/* Step 1: Determine capacity of this disk */
|
||||
uptr -> capac = sim_fsize(uptr -> fileref); /* the file length is a good candidate */
|
||||
if (uptr -> capac == 0) { /* file does not exist or has length 0 */
|
||||
uptr -> capac = uptr -> HDSK_NUMBER_OF_TRACKS *
|
||||
uptr -> HDSK_SECTORS_PER_TRACK * uptr -> HDSK_SECTOR_SIZE;
|
||||
if (uptr -> capac == 0)
|
||||
uptr -> capac = HDSK_CAPACITY;
|
||||
} /* post condition: uptr -> capac > 0 */
|
||||
assert(uptr -> capac);
|
||||
|
||||
uptr->HDSK_FORMAT_TYPE = -1; /* Default to unknown format type */
|
||||
|
||||
for(i=0; dpb[i].spt != 0; i++) {
|
||||
if(dpb[i].capac == uptr->capac) {
|
||||
/* Step 2: Determine format based on disk capacity */
|
||||
uptr -> HDSK_FORMAT_TYPE = -1; /* default to unknown format type */
|
||||
for (i = 0; dpb[i].capac != 0; i++) { /* find disk parameter block */
|
||||
if (dpb[i].capac == uptr -> capac) { /* found if correct capacity */
|
||||
uptr -> HDSK_FORMAT_TYPE = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(uptr->HDSK_FORMAT_TYPE == -1) {
|
||||
/* 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->capac = dpb[uptr->HDSK_FORMAT_TYPE].capac;
|
||||
printf("HDSK: WARNING: Unsupported disk capacity, assuming HDSK type.\n");
|
||||
uptr->flags |= UNIT_HDSKWLK;
|
||||
printf("HDSK: WARNING: Forcing WRTLCK.\n");
|
||||
if(uptr->capac != (uptr->HDSK_MAX_TRACKS * uptr->HDSK_SECTORS_PER_TRACK * uptr->HDSK_SECTOR_SIZE)) {
|
||||
printf("HDSK: WARNING: Geometry may be incorrect.\n");
|
||||
printf("HDSK%c: WARNING: Unsupported disk capacity, assuming HDSK type with capacity %iKB.\n",
|
||||
unitChar, uptr -> capac / 1000);
|
||||
uptr -> flags |= UNIT_HDSK_WLK;
|
||||
printf("HDSK%c: WARNING: Forcing WRTLCK.\n", unitChar);
|
||||
/* check whether capacity corresponds to setting of tracks, sectors per track and sector size */
|
||||
if (uptr -> capac != (uptr -> HDSK_NUMBER_OF_TRACKS *
|
||||
uptr -> HDSK_SECTORS_PER_TRACK * uptr -> HDSK_SECTOR_SIZE)) {
|
||||
printf("HDSK%c: WARNING: Fixing geometry.\n", unitChar);
|
||||
if (uptr -> HDSK_SECTORS_PER_TRACK == 0) uptr -> HDSK_SECTORS_PER_TRACK = 32;
|
||||
if (uptr -> HDSK_SECTOR_SIZE == 0) uptr -> HDSK_SECTOR_SIZE = 128;
|
||||
}
|
||||
}
|
||||
|
||||
uptr->HDSK_SECTOR_SIZE = (128 << dpb[uptr->HDSK_FORMAT_TYPE].psh);
|
||||
else { /* Case 2: disk parameter block found */
|
||||
uptr -> HDSK_SECTORS_PER_TRACK = dpb[uptr -> HDSK_FORMAT_TYPE].spt >> dpb[uptr -> HDSK_FORMAT_TYPE].psh;
|
||||
uptr->HDSK_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;
|
||||
}
|
||||
|
||||
/* Set disk geometry routine */
|
||||
t_stat set_geom(UNIT *uptr, int32 val, char *cptr, void *desc) {
|
||||
DEVICE *dptr;
|
||||
|
||||
uint32 ncyl, nsect, ssize;
|
||||
uint32 numberOfTracks, numberOfSectors, sectorSize;
|
||||
int result, n;
|
||||
|
||||
if (cptr == NULL) return SCPE_ARG;
|
||||
if (uptr == NULL) return SCPE_IERR;
|
||||
dptr = find_dev_from_unit (uptr);
|
||||
if (dptr == NULL) return SCPE_IERR;
|
||||
|
||||
sscanf(cptr, "%d/%d/%d", &ncyl, &nsect, &ssize);
|
||||
uptr->HDSK_MAX_TRACKS = ncyl;
|
||||
uptr->HDSK_SECTORS_PER_TRACK = nsect;
|
||||
uptr->HDSK_SECTOR_SIZE = ssize;
|
||||
|
||||
result = sscanf(cptr, "%d/%d/%d%n", &numberOfTracks, &numberOfSectors, §orSize, &n);
|
||||
if ((result != 3) || (result == EOF) || (cptr[n] != 0)) {
|
||||
result = sscanf(cptr, "T:%d/N:%d/S:%d%n", &numberOfTracks, &numberOfSectors, §orSize, &n);
|
||||
if ((result != 3) || (result == EOF) || (cptr[n] != 0)) return SCPE_ARG;
|
||||
}
|
||||
uptr -> HDSK_NUMBER_OF_TRACKS = numberOfTracks;
|
||||
uptr -> HDSK_SECTORS_PER_TRACK = numberOfSectors;
|
||||
uptr -> HDSK_SECTOR_SIZE = sectorSize;
|
||||
uptr -> capac = numberOfTracks * numberOfSectors * sectorSize;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Show disk geometry routine */
|
||||
t_stat show_geom(FILE *st, UNIT *uptr, int32 val, void *desc) {
|
||||
DEVICE *dptr;
|
||||
if (uptr == NULL) return SCPE_IERR;
|
||||
dptr = find_dev_from_unit (uptr);
|
||||
if (dptr == NULL) return SCPE_IERR;
|
||||
fprintf (st, "T:%d/N:%d/S:%d", uptr->HDSK_MAX_TRACKS, uptr->HDSK_SECTORS_PER_TRACK, uptr->u5);
|
||||
|
||||
fprintf(st, "T:%d/N:%d/S:%d", uptr -> HDSK_NUMBER_OF_TRACKS,
|
||||
uptr -> HDSK_SECTORS_PER_TRACK, uptr -> HDSK_SECTOR_SIZE);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
#define QUOTE1(text) #text
|
||||
#define QUOTE2(text) QUOTE1(text)
|
||||
/* Set disk format routine */
|
||||
t_stat set_format(UNIT *uptr, int32 val, char *cptr, void *desc) {
|
||||
DEVICE *dptr;
|
||||
|
||||
char fmtname[16];
|
||||
char fmtname[DPB_NAME_LENGTH + 1];
|
||||
int32 i;
|
||||
|
||||
if (cptr == NULL) return SCPE_ARG;
|
||||
if (uptr == NULL) return SCPE_IERR;
|
||||
dptr = find_dev_from_unit (uptr);
|
||||
if (dptr == NULL) return SCPE_IERR;
|
||||
|
||||
sscanf(cptr, "%s", fmtname);
|
||||
|
||||
for(i=0;dpb[i].spt != 0;i++) {
|
||||
if(!strncmp(fmtname, dpb[i].name, strlen(fmtname))) {
|
||||
if (sscanf(cptr, "%" QUOTE2(DPB_NAME_LENGTH) "s", fmtname) == 0) return SCPE_ARG;
|
||||
for (i = 0; dpb[i].capac != 0; i++) {
|
||||
if (strncmp(fmtname, dpb[i].name, strlen(fmtname)) == 0) {
|
||||
uptr -> HDSK_FORMAT_TYPE = i;
|
||||
uptr -> capac = dpb[i].capac; /* Set capacity */
|
||||
|
||||
/* Configure physical disk geometry */
|
||||
uptr -> HDSK_SECTOR_SIZE = (128 << dpb[uptr -> HDSK_FORMAT_TYPE].psh);
|
||||
uptr -> HDSK_SECTORS_PER_TRACK = dpb[uptr -> HDSK_FORMAT_TYPE].spt >> dpb[uptr -> HDSK_FORMAT_TYPE].psh;
|
||||
uptr->HDSK_MAX_TRACKS = uptr->capac / (uptr->HDSK_SECTORS_PER_TRACK * uptr->HDSK_SECTOR_SIZE);
|
||||
uptr -> HDSK_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;
|
||||
}
|
||||
|
@ -264,12 +275,8 @@ t_stat set_format (UNIT *uptr, int32 val, char *cptr, void *desc) {
|
|||
|
||||
/* Show disk format routine */
|
||||
t_stat show_format(FILE *st, UNIT *uptr, int32 val, void *desc) {
|
||||
DEVICE *dptr;
|
||||
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);
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
@ -315,9 +322,6 @@ static t_stat hdsk_boot(int32 unitno, DEVICE *dptr) {
|
|||
return SCPE_ARG;
|
||||
}
|
||||
if (cpu_unit.flags & (UNIT_ALTAIRROM | UNIT_BANKED)) {
|
||||
if (install_bootrom()) {
|
||||
printf("ALTAIR boot ROM installed.\n");
|
||||
}
|
||||
/* check whether we are really modifying an LD A,<> instruction */
|
||||
if (bootrom[UNIT_NO_OFFSET_1 - 1] == LDA_INSTRUCTION) {
|
||||
bootrom[UNIT_NO_OFFSET_1] = (unitno + NUM_OF_DSK) & 0xff; /* LD A,<unitno> */
|
||||
|
@ -326,6 +330,7 @@ static t_stat hdsk_boot(int32 unitno, DEVICE *dptr) {
|
|||
printf("Incorrect boot ROM offset detected.\n");
|
||||
return SCPE_IERR;
|
||||
}
|
||||
install_bootrom(); /* install modified ROM */
|
||||
}
|
||||
for (i = 0; i < BOOTROM_SIZE; i++) {
|
||||
PutBYTEBasic(i + HDSK_BOOT_ADDRESS, 0, hdskBoot[i] & 0xff);
|
||||
|
@ -339,7 +344,7 @@ static t_stat hdsk_boot(int32 unitno, DEVICE *dptr) {
|
|||
static int32 hdsk_hasVerbose(void) {
|
||||
int32 i;
|
||||
for (i = 0; i < HDSK_NUMBER; i++) {
|
||||
if (((hdsk_dev.units + i) -> flags) & UNIT_HDSK_VERBOSE) {
|
||||
if (hdsk_dev.units[i].flags & UNIT_HDSK_VERBOSE) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -398,7 +403,7 @@ static int32 hdsk_hasVerbose(void) {
|
|||
|
||||
/* check the parameters and return TRUE iff parameters are correct or have been repaired */
|
||||
static int32 checkParameters(void) {
|
||||
UNIT *uptr = hdsk_dev.units + selectedDisk;
|
||||
UNIT *uptr = &hdsk_dev.units[selectedDisk];
|
||||
int32 currentFlag;
|
||||
if ((selectedDisk < 0) || (selectedDisk >= HDSK_NUMBER)) {
|
||||
if (hdsk_hasVerbose()) {
|
||||
|
@ -406,7 +411,7 @@ static int32 checkParameters(void) {
|
|||
}
|
||||
selectedDisk = 0;
|
||||
}
|
||||
currentFlag = (hdsk_dev.units + selectedDisk) -> flags;
|
||||
currentFlag = hdsk_dev.units[selectedDisk].flags;
|
||||
if ((currentFlag & UNIT_ATT) == 0) {
|
||||
if (currentFlag & UNIT_HDSK_VERBOSE) {
|
||||
MESSAGE_2("HDSK%d is not attached.", selectedDisk);
|
||||
|
@ -420,10 +425,10 @@ static int32 checkParameters(void) {
|
|||
}
|
||||
selectedSector = 0;
|
||||
}
|
||||
if ((selectedTrack < 0) || (selectedTrack >= uptr->HDSK_MAX_TRACKS)) {
|
||||
if ((selectedTrack < 0) || (selectedTrack >= uptr -> HDSK_NUMBER_OF_TRACKS)) {
|
||||
if (currentFlag & UNIT_HDSK_VERBOSE) {
|
||||
MESSAGE_4("HDSK%d: 0 <= Track=%04d < %04d violated, will use 0 instead.",
|
||||
selectedDisk, selectedTrack, uptr->HDSK_MAX_TRACKS);
|
||||
selectedDisk, selectedTrack, uptr -> HDSK_NUMBER_OF_TRACKS);
|
||||
}
|
||||
selectedTrack = 0;
|
||||
}
|
||||
|
@ -437,9 +442,10 @@ static int32 checkParameters(void) {
|
|||
}
|
||||
|
||||
static int32 doSeek(void) {
|
||||
UNIT *uptr = hdsk_dev.units + selectedDisk;
|
||||
UNIT *uptr = &hdsk_dev.units[selectedDisk];
|
||||
if (fseek(uptr -> fileref,
|
||||
(uptr->HDSK_SECTORS_PER_TRACK * uptr->HDSK_SECTOR_SIZE) * selectedTrack + (uptr->HDSK_SECTOR_SIZE * selectedSector), SEEK_SET)) {
|
||||
(uptr -> HDSK_SECTORS_PER_TRACK * uptr -> HDSK_SECTOR_SIZE) * selectedTrack +
|
||||
(uptr -> HDSK_SECTOR_SIZE * selectedSector), SEEK_SET)) {
|
||||
if ((uptr -> flags) & UNIT_HDSK_VERBOSE) {
|
||||
MESSAGE_4("Could not access HDSK%d Sector=%02d Track=%04d.",
|
||||
selectedDisk, selectedSector, selectedTrack);
|
||||
|
@ -451,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) {
|
||||
int32 i;
|
||||
UNIT *uptr = hdsk_dev.units + selectedDisk;
|
||||
UNIT *uptr = &hdsk_dev.units[selectedDisk];
|
||||
if (doSeek()) {
|
||||
return CPM_ERROR;
|
||||
}
|
||||
|
@ -479,8 +485,8 @@ static int32 doRead(void) {
|
|||
static int32 doWrite(void) {
|
||||
int32 i;
|
||||
|
||||
UNIT *uptr = hdsk_dev.units + selectedDisk;
|
||||
if (((uptr -> flags) & UNIT_HDSKWLK) == 0) { /* write enabled */
|
||||
UNIT *uptr = &hdsk_dev.units[selectedDisk];
|
||||
if (((uptr -> flags) & UNIT_HDSK_WLK) == 0) { /* write enabled */
|
||||
if (doSeek()) {
|
||||
return CPM_ERROR;
|
||||
}
|
||||
|
@ -506,7 +512,7 @@ static int32 doWrite(void) {
|
|||
}
|
||||
|
||||
static int32 hdsk_in(const int32 port) {
|
||||
UNIT *uptr = hdsk_dev.units + selectedDisk;
|
||||
UNIT *uptr = &hdsk_dev.units[selectedDisk];
|
||||
|
||||
int32 result;
|
||||
if ((hdskCommandPosition == 6) && ((hdskLastCommand == HDSK_READ) || (hdskLastCommand == HDSK_WRITE))) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* gri_cpu.c: GRI-909 CPU simulator
|
||||
|
||||
Copyright (c) 2001-2005, Robert M. Supnik
|
||||
Copyright (c) 2001-2007, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
cpu GRI-909 CPU
|
||||
|
||||
28-Apr-07 RMS Removed clock initialization
|
||||
22-Sep-05 RMS Fixed declarations (from Sterling Garwood)
|
||||
18-Jul-04 RMS Fixed missing ao_update calls in AX, AY write
|
||||
17-Jul-04 RMS Revised MSR, EAO based on additional documentation
|
||||
|
@ -380,14 +381,12 @@ t_stat sim_instr (void)
|
|||
{
|
||||
uint32 src, dst, op, t, jmp;
|
||||
t_stat reason;
|
||||
extern UNIT rtc_unit;
|
||||
|
||||
/* Restore register state */
|
||||
|
||||
SC = SC & AMASK; /* load local PC */
|
||||
reason = 0;
|
||||
ao_update (); /* update AO */
|
||||
sim_rtc_init (rtc_unit.wait); /* init calibration */
|
||||
|
||||
/* Main instruction fetch/decode loop */
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* h316_cpu.c: Honeywell 316/516 CPU simulator
|
||||
|
||||
Copyright (c) 1999-2006, Robert M. Supnik
|
||||
Copyright (c) 1999-2007, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
cpu H316/H516 CPU
|
||||
|
||||
28-Apr-07 RMS Removed clock initialization
|
||||
03-Apr-06 RMS Fixed bugs in LLL, LRL (from Theo Engel)
|
||||
22-Sep-05 RMS Fixed declarations (from Sterling Garwood)
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
|
@ -370,7 +371,6 @@ DEVICE cpu_dev = {
|
|||
|
||||
t_stat sim_instr (void)
|
||||
{
|
||||
extern UNIT clk_unit;
|
||||
int32 AR, BR, MB, Y, t1, t2, t3, skip, dev;
|
||||
uint32 ut;
|
||||
t_stat reason;
|
||||
|
@ -399,7 +399,6 @@ BR = saved_BR & DMASK;
|
|||
XR = saved_XR & DMASK;
|
||||
PC = PC & ((cpu_unit.flags & UNIT_EXT)? X_AMASK: NX_AMASK); /* mask PC */
|
||||
reason = 0;
|
||||
sim_rtc_init (clk_unit.wait); /* init calibration */
|
||||
|
||||
/* Main instruction fetch/decode loop */
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* h316_lp.c: Honeywell 316/516 line printer
|
||||
|
||||
Copyright (c) 1999-2006, Robert M. Supnik
|
||||
Copyright (c) 1999-2007, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
lpt line printer
|
||||
|
||||
19-Jan-06 RMS Added UNIT_TEXT flag
|
||||
03-Apr-06 RMS Fixed bug in blanks backscanning (from Theo Engel)
|
||||
01-Dec-04 RMS Fixed bug in DMA/DMC support
|
||||
24-Oct-03 RMS Added DMA/DMC support
|
||||
|
@ -105,7 +106,7 @@ t_stat lpt_reset (DEVICE *dptr);
|
|||
|
||||
DIB lpt_dib = { LPT, IOBUS, 1, &lptio };
|
||||
|
||||
UNIT lpt_unit = { UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE, 0) };
|
||||
UNIT lpt_unit = { UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0) };
|
||||
|
||||
REG lpt_reg[] = {
|
||||
{ DRDATA (WDPOS, lpt_wdpos, 6) },
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
DMA0,DMA1 12607B/12578A/12895A direct memory access controller
|
||||
DCPC0,DCPC1 12897B dual channel port controller
|
||||
|
||||
28-Apr-07 RMS Removed clock initialization
|
||||
02-Mar-07 JDB EDT passes input flag and DMA channel in dat parameter
|
||||
11-Jan-07 JDB Added 12578A DMA byte packing
|
||||
28-Dec-06 JDB CLC 0 now sends CRS instead of CLC to devices
|
||||
26-Dec-06 JDB Fixed improper IRQ deferral for 21xx CPUs
|
||||
|
@ -378,7 +380,6 @@
|
|||
#define UNIT_MP_INT (1 << UNIT_V_MP_INT)
|
||||
#define UNIT_MP_SEL1 (1 << UNIT_V_MP_SEL1)
|
||||
|
||||
|
||||
#define ABORT(val) longjmp (save_env, (val))
|
||||
|
||||
#define DMAR0 1
|
||||
|
@ -521,8 +522,6 @@ void hp_post_cmd (t_bool from_scp);
|
|||
extern t_stat cpu_eau (uint32 IR, uint32 intrq);
|
||||
extern t_stat cpu_uig_0 (uint32 IR, uint32 intrq, uint32 iotrap);
|
||||
extern t_stat cpu_uig_1 (uint32 IR, uint32 intrq, uint32 iotrap);
|
||||
|
||||
extern int32 clk_delay (int32 flg);
|
||||
extern void (*sim_vm_post) (t_bool from_scp);
|
||||
|
||||
/* CPU data structures
|
||||
|
@ -841,7 +840,6 @@ for (i = 0; dptr = sim_devices[i]; i++) { /* loop thru dev */
|
|||
dtab[dev] = dibp->iot; /* set I/O dispatch */
|
||||
}
|
||||
}
|
||||
sim_rtc_init (clk_delay (0)); /* recalibrate clock */
|
||||
|
||||
/* Configure interrupt deferral table */
|
||||
|
||||
|
@ -2023,7 +2021,7 @@ return dat;
|
|||
- STC requested but not CLC: issue STC,C
|
||||
- CLC requested but not STC: issue CLC,C
|
||||
- STC and CLC both requested: issue STC,C and CLC,C, in that order
|
||||
Either: issue EDT
|
||||
Either: issue EDT (pass DMA channel number and I/O flag)
|
||||
*/
|
||||
|
||||
void dma_cycle (uint32 ch, uint32 map)
|
||||
|
@ -2101,7 +2099,7 @@ else {
|
|||
} /* end output */
|
||||
setFLG (DMA0 + ch); /* set DMA flg */
|
||||
clrCMD (DMA0 + ch); /* clr DMA cmd */
|
||||
devdisp (dev, ioEDT, dev, 0); /* do EDT */
|
||||
devdisp (dev, ioEDT, dev, inp | ch); /* do EDT */
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
SIMH/HP 21XX DIAGNOSTICS PERFORMANCE
|
||||
====================================
|
||||
Last update: 2007-01-12
|
||||
Last update: 2007-03-05
|
||||
|
||||
|
||||
The HP 24396 diagnostic suite has been run against the SIMH HP 21xx simulation.
|
||||
|
@ -62,8 +62,8 @@ The results of the diagnostic runs are summarized below:
|
|||
103122 59310 Interface Bus Interface 1728 - No simulation
|
||||
|
||||
103003 12587 Asynchronous Data Set Interface 1553 - No simulation
|
||||
103110 12920 Asynchronous Multiplexer (Data) 1805 - Not tested
|
||||
103011 12920 Asynchronous Multiplexer (Cntl) 1444 - Not tested
|
||||
103110 12920 Asynchronous Multiplexer (Data) 1805 3.7-1 Passed
|
||||
103011 12920 Asynchronous Multiplexer (Cntl) 1444 3.7-1 Passed
|
||||
103012 12621 Synchronous Data Set (Receive) 1532 - No simulation
|
||||
103013 12621 Synchronous Data Set (Send) 1532 - No simulation
|
||||
103116 12967 Synchronous Interface 1438 - No simulation
|
||||
|
@ -114,11 +114,11 @@ not supported by the 24396 suite:
|
|||
Paper Tape Date SIMH
|
||||
Part Number DSN Diagnostic Name Code Vers. Result
|
||||
----------- ------ --------------------------------------- ---- ----- ----------
|
||||
24203-60001 -- HP2100A Cartridge Disc Memory (2871) A 3.3-0 Partial
|
||||
22682-16017 177777 HP 2100 Fixed Head Disc/Drum (277x) 1612 3.3-0 Passed
|
||||
13207-16001 101217 2000/Access Comm Processor for 21MX 1728 3.2-3 Passed
|
||||
20433-????? -- HP 3030 Magnetic Tape Subsystem -- - Not tested
|
||||
|
||||
24197-60001 -- 12875 Processor Interconnect Cable B 3.7-1 Passed
|
||||
24203-60001 -- HP2100A Cartridge Disc Memory (2871) A 3.3-0 Partial
|
||||
22682-16017 177777 HP 2100 Fixed Head Disc/Drum (277x) 1612 3.3-0 Passed
|
||||
|
||||
The "SIMH Version" is the version number of the earliest SIMH system that was
|
||||
tested with the given diagnostic. Earlier versions may or may not work
|
||||
|
@ -988,31 +988,71 @@ TEST RESULT: Passed.
|
|||
|
||||
|
||||
|
||||
--------------------------------------------------
|
||||
DSN 103110 - 12920 Asynchronous Multiplexer (Data)
|
||||
--------------------------------------------------
|
||||
---------------------------------------------------
|
||||
DSN 103110 - 12920A Asynchronous Multiplexer (Data)
|
||||
---------------------------------------------------
|
||||
|
||||
TESTED DEVICE: MUX, MUXL (hp2100_mux.c)
|
||||
|
||||
CONFIGURATION:
|
||||
CONFIGURATION: sim> set MUX DIAG
|
||||
sim> deposit S 004040
|
||||
sim> reset
|
||||
sim> go 100
|
||||
|
||||
TEST REPORT:
|
||||
HALT instruction 102074
|
||||
|
||||
TEST RESULT: Not tested.
|
||||
sim> deposit S 000000
|
||||
sim> reset
|
||||
sim> go
|
||||
|
||||
TEST REPORT: ASYNC MULTIPLEXER DATA BOARD DIAGNOSTIC DSN 103110
|
||||
H024 PRESS PRESET (EXT&INT),RUN
|
||||
|
||||
HALT instruction 102024
|
||||
|
||||
sim> reset
|
||||
sim> go
|
||||
|
||||
H025 BI-O COMP
|
||||
PASS 000001
|
||||
|
||||
HALT instruction 102077
|
||||
|
||||
TEST RESULT: Passed.
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------
|
||||
DSN 103011 - 12920 Asynchronous Multiplexer (Cntl)
|
||||
--------------------------------------------------
|
||||
---------------------------------------------------
|
||||
DSN 103011 - 12920A Asynchronous Multiplexer (Cntl)
|
||||
---------------------------------------------------
|
||||
|
||||
TESTED DEVICE: MUXM (hp2100_mux.c)
|
||||
|
||||
CONFIGURATION:
|
||||
CONFIGURATION: sim> set MUX DIAG
|
||||
sim> deposit S 004042
|
||||
sim> reset
|
||||
sim> go 100
|
||||
|
||||
TEST REPORT:
|
||||
HALT instruction 102074
|
||||
|
||||
TEST RESULT: Not tested.
|
||||
sim> deposit S 000000
|
||||
sim> reset
|
||||
sim> go
|
||||
|
||||
TEST REPORT: ASYNC MULTIPLEXER CONTROL BOARD DIAGNOSTIC
|
||||
H024 PRESS PRESET (EXT&INT),RUN
|
||||
|
||||
HALT instruction 102024
|
||||
|
||||
sim> reset
|
||||
sim> go
|
||||
|
||||
H025 BI-O COMP
|
||||
PASS 000001
|
||||
|
||||
HALT instruction 102077
|
||||
|
||||
TEST RESULT: Passed.
|
||||
|
||||
|
||||
|
||||
|
@ -3117,6 +3157,41 @@ TEST RESULT: Passed.
|
|||
|
||||
|
||||
|
||||
-----------------------------------------------
|
||||
DSN (none) - 12875 Processor Interconnect Cable
|
||||
-----------------------------------------------
|
||||
|
||||
TESTED DEVICE: IPLI, IPLO (hp2100_ipl.c)
|
||||
|
||||
BINARY TAPE: 24197-60001 Rev. B
|
||||
|
||||
CONFIGURATION: sim> set IPLI DIAG
|
||||
sim> set IPLO DIAG
|
||||
sim> deposit S 003332
|
||||
sim> reset
|
||||
sim> go 2
|
||||
|
||||
HALT instruction 107076
|
||||
|
||||
sim> deposit S 010000
|
||||
sim> reset
|
||||
sim> go
|
||||
|
||||
HALT instruction 107077
|
||||
|
||||
sim> deposit S 000000
|
||||
sim> reset
|
||||
sim> go 100
|
||||
|
||||
TEST REPORT: H14. START 12875 CABLE DIAGNOSTIC
|
||||
H77. END 12875 CABLE DIAGNOSTIC
|
||||
|
||||
HALT instruction 102077
|
||||
|
||||
TEST RESULT: Passed.
|
||||
|
||||
|
||||
|
||||
--------------------------------------------
|
||||
DSN (none) - HP 3030 Magnetic Tape Subsystem
|
||||
--------------------------------------------
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* hp2100_ipl.c: HP 2000 interprocessor link simulator
|
||||
|
||||
Copyright (c) 2002-2006, Robert M Supnik
|
||||
Copyright (c) 2002-2007, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -23,9 +23,11 @@
|
|||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
ipli, iplo 12566B interprocessor link pair
|
||||
ipli, iplo 12875A interprocessor link
|
||||
|
||||
28-Dec-06 JDB Added ioCRS state to I/O decoders (action unverified)
|
||||
01-Mar-07 JDB IPLI EDT delays DMA completion interrupt for TSB
|
||||
Added debug printouts
|
||||
28-Dec-06 JDB Added ioCRS state to I/O decoders
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
07-Oct-04 JDB Fixed enable/disable from either device
|
||||
26-Apr-04 RMS Fixed SFS x,C and SFC x,C
|
||||
|
@ -33,6 +35,20 @@
|
|||
21-Dec-03 RMS Adjusted ipl_ptime for TSB (from Mike Gemeny)
|
||||
09-May-03 RMS Added network device flag
|
||||
31-Jan-03 RMS Links are full duplex (found by Mike Gemeny)
|
||||
|
||||
The 12875A Processor Interconnect Kit consists four 12566A Microcircuit
|
||||
Interface cards. Two are used in each processor. One card in each system is
|
||||
used to initiate transmissions to the other, and the second card is used to
|
||||
receive transmissions from the other. Each pair of cards forms a
|
||||
bidirectional link, as the sixteen data lines are cross-connected, so that
|
||||
data sent and status returned are supported. In each processor, data is sent
|
||||
on the lower priority card and received on the higher priority card. Two
|
||||
sets of cards are used to support simultaneous transmission in both
|
||||
directions.
|
||||
|
||||
Reference:
|
||||
- 12875A Processor Interconnect Kit Operating and Service Manual
|
||||
(12875-90002, Jan-1974)
|
||||
*/
|
||||
|
||||
#include "hp2100_defs.h"
|
||||
|
@ -52,9 +68,17 @@
|
|||
#define DSOCKET u3 /* data socket */
|
||||
#define LSOCKET u4 /* listening socket */
|
||||
|
||||
/* Debug flags */
|
||||
|
||||
#define DEB_CMDS (1 << 0) /* Command initiation and completion */
|
||||
#define DEB_CPU (1 << 1) /* CPU I/O */
|
||||
#define DEB_XFER (1 << 2) /* Socket receive and transmit */
|
||||
|
||||
extern uint32 PC;
|
||||
extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2], dev_srq[2];
|
||||
extern FILE *sim_log;
|
||||
extern FILE *sim_deb;
|
||||
int32 ipl_edtdelay = 1; /* EDT delay (msec) */
|
||||
int32 ipl_ptime = 31; /* polling interval */
|
||||
int32 ipl_stopioe = 0; /* stop on error */
|
||||
int32 ipl_hold[2] = { 0 }; /* holding character */
|
||||
|
@ -72,6 +96,14 @@ t_stat ipl_dscln (UNIT *uptr, int32 val, char *cptr, void *desc);
|
|||
t_stat ipl_setdiag (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
t_bool ipl_check_conn (UNIT *uptr);
|
||||
|
||||
/* Debug flags table */
|
||||
|
||||
DEBTAB ipl_deb[] = {
|
||||
{ "CMDS", DEB_CMDS },
|
||||
{ "CPU", DEB_CPU },
|
||||
{ "XFER", DEB_XFER },
|
||||
{ NULL, 0 } };
|
||||
|
||||
/* IPLI data structures
|
||||
|
||||
ipli_dev IPLI device descriptor
|
||||
|
@ -125,7 +157,8 @@ DEVICE ipli_dev = {
|
|||
1, 10, 31, 1, 16, 16,
|
||||
&tmxr_ex, &tmxr_dep, &ipl_reset,
|
||||
&ipl_boot, &ipl_attach, &ipl_detach,
|
||||
&ipli_dib, DEV_NET | DEV_DISABLE | DEV_DIS
|
||||
&ipli_dib, DEV_NET | DEV_DISABLE | DEV_DIS | DEV_DEBUG,
|
||||
0, ipl_deb, NULL, NULL
|
||||
};
|
||||
|
||||
/* IPLO data structures
|
||||
|
@ -154,7 +187,8 @@ DEVICE iplo_dev = {
|
|||
1, 10, 31, 1, 16, 16,
|
||||
&tmxr_ex, &tmxr_dep, &ipl_reset,
|
||||
&ipl_boot, &ipl_attach, &ipl_detach,
|
||||
&iplo_dib, DEV_NET | DEV_DISABLE | DEV_DIS
|
||||
&iplo_dib, DEV_NET | DEV_DISABLE | DEV_DIS | DEV_DEBUG,
|
||||
0, ipl_deb, NULL, NULL
|
||||
};
|
||||
|
||||
/* I/O instructions */
|
||||
|
@ -169,12 +203,61 @@ int32 iploio (int32 inst, int32 IR, int32 dat)
|
|||
return iplio (&iplo_unit, inst, IR, dat);
|
||||
}
|
||||
|
||||
/* I/O handler for the IPLI and IPLO devices.
|
||||
|
||||
Implementation note: 2000 Access has a race condition that manifests itself
|
||||
by an apparently normal boot and operational system console but no PLEASE LOG
|
||||
IN response to terminals connected to the multiplexer. The frequency of
|
||||
occurrence is higher on multiprocessor host systems, where the SP and IOP
|
||||
instances may execute concurrently.
|
||||
|
||||
The cause is this code in the SP disc loader source (2883.asm, 7900.asm,
|
||||
790X.asm, 79X3.asm, and 79XX.asm):
|
||||
|
||||
LDA SDVTR REQUEST
|
||||
JSB IOPMA,I DEVICE TABLE
|
||||
[...]
|
||||
STC DMAHS,C TURN ON DMA
|
||||
SFS DMAHS WAIT FOR
|
||||
JMP *-1 DEVICE TABLE
|
||||
STC CH2,C SET CORRECT
|
||||
CLC CH2 FLAG DIRECTION
|
||||
|
||||
The STC/CLC normally would cause a second "request device table" command to
|
||||
be recognized by the IOP, except that the IOP DMA setup routine "DMAXF" (in
|
||||
D61.asm) has specified an end-of-block CLC that holds off the IPL interrupt,
|
||||
and the completion interrupt routine "DMACP" ends with a STC,C that clears
|
||||
the IPL flag.
|
||||
|
||||
In hardware, the two CPUs are essentially interlocked by the DMA transfer,
|
||||
and DMA completion interrupts occur almost simultaneously. Therefore, the
|
||||
STC/CLC in the SP is guaranteed to occur before the STC,C in the IOP. Under
|
||||
simulation, and especially on multiprocessor hosts, that guarantee does not
|
||||
hold. If the STC/CLC occurs after the STC,C, then the IOP starts a second
|
||||
device table DMA transfer, which the SP is not expecting. The IOP never
|
||||
processes the subsequent "start timesharing" command, and the muxtiplexer is
|
||||
non-reponsive.
|
||||
|
||||
We employ a workaround that decreases the incidence of the problem: DMA
|
||||
output completion interrupts are delayed to allow the other SIMH instance a
|
||||
chance to process its own DMA completion. We do this by processing the EDT
|
||||
(End Data Transfer) I/O backplane signal and "sleep"ing for a short time if
|
||||
the transfer was an output transfer ("dat" contains the DMA channel number
|
||||
and direction flag for EDT signals).
|
||||
*/
|
||||
|
||||
int32 iplio (UNIT *uptr, int32 inst, int32 IR, int32 dat)
|
||||
{
|
||||
uint32 u, dev, odev;
|
||||
int32 sta;
|
||||
char msg[2];
|
||||
char msg[2], uc;
|
||||
DEVICE *dbdev; /* device ptr for debug */
|
||||
static const char *iotype[] = { "Status", "Command" };
|
||||
|
||||
uc = (uptr == &ipli_unit) ? 'I' : 'O'; /* identify unit for debug */
|
||||
dbdev = (uptr == &ipli_unit) ? &ipli_dev : &iplo_dev; /* identify device for debug */
|
||||
|
||||
u = (uptr - ipl_unit); /* get unit number */
|
||||
dev = IR & I_DEVMASK; /* get device no */
|
||||
switch (inst) { /* case on opcode */
|
||||
|
||||
|
@ -192,25 +275,42 @@ switch (inst) { /* case on opcode */
|
|||
|
||||
case ioOTX: /* output */
|
||||
uptr->OBUF = dat;
|
||||
|
||||
if (DEBUG_PRJ (dbdev, DEB_CPU))
|
||||
fprintf (sim_deb, ">>IPL%c OTx: %s = %06o\n", uc, iotype[u], dat);
|
||||
break;
|
||||
|
||||
case ioLIX: /* load */
|
||||
dat = uptr->IBUF; /* return val */
|
||||
break;
|
||||
dat = 0;
|
||||
|
||||
case ioMIX: /* merge */
|
||||
dat = dat | uptr->IBUF; /* get return data */
|
||||
|
||||
if (DEBUG_PRJ (dbdev, DEB_CPU))
|
||||
fprintf (sim_deb, ">>IPL%c LIx: %s = %06o\n", uc, iotype[u ^ 1], dat);
|
||||
break;
|
||||
|
||||
case ioCRS: /* control reset */
|
||||
clrCMD (dev); /* clear ctl, cmd */
|
||||
clrCTL (dev);
|
||||
break;
|
||||
|
||||
case ioCRS: /* control reset (action unverif) */
|
||||
case ioCTL: /* control clear/set */
|
||||
if (IR & I_CTL) { /* CLC */
|
||||
clrCMD (dev); /* clear ctl, cmd */
|
||||
clrCTL (dev);
|
||||
|
||||
if (DEBUG_PRJ (dbdev, DEB_CMDS))
|
||||
fprintf (sim_deb, ">>IPL%c CLC: Command cleared\n", uc);
|
||||
}
|
||||
|
||||
else { /* STC */
|
||||
setCMD (dev); /* set ctl, cmd */
|
||||
setCTL (dev);
|
||||
|
||||
if (DEBUG_PRJ (dbdev, DEB_CMDS))
|
||||
fprintf (sim_deb, ">>IPL%c STC: Command set\n", uc);
|
||||
|
||||
if (uptr->flags & UNIT_ATT) { /* attached? */
|
||||
if ((uptr->flags & UNIT_ESTB) == 0) { /* established? */
|
||||
if (!ipl_check_conn (uptr)) /* not established? */
|
||||
|
@ -220,6 +320,12 @@ switch (inst) { /* case on opcode */
|
|||
msg[0] = (uptr->OBUF >> 8) & 0377;
|
||||
msg[1] = uptr->OBUF & 0377;
|
||||
sta = sim_write_sock (uptr->DSOCKET, msg, 2);
|
||||
|
||||
if (DEBUG_PRJ (dbdev, DEB_XFER))
|
||||
fprintf (sim_deb,
|
||||
">>IPL%c STC: Socket write = %06o, status = %d\n",
|
||||
uc, uptr->OBUF, sta);
|
||||
|
||||
if (sta == SOCKET_ERROR) {
|
||||
printf ("IPL: socket write error\n");
|
||||
return SCPE_IOERR;
|
||||
|
@ -236,6 +342,16 @@ switch (inst) { /* case on opcode */
|
|||
}
|
||||
break;
|
||||
|
||||
case ioEDT: /* End of DMA data transfer */
|
||||
if ((dat & DMA2_OI) == 0) { /* output transfer? */
|
||||
if (DEBUG_PRJ (dbdev, DEB_CMDS))
|
||||
fprintf (sim_deb,
|
||||
">>IPL%c EDT: Delaying DMA completion interrupt for %d msec\n",
|
||||
uc, ipl_edtdelay);
|
||||
sim_os_ms_sleep (ipl_edtdelay); /* delay completion */
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -249,7 +365,8 @@ return dat;
|
|||
t_stat ipl_svc (UNIT *uptr)
|
||||
{
|
||||
int32 u, nb, dev;
|
||||
char msg[2];
|
||||
char msg[2], uc;
|
||||
DEVICE *dbdev; /* device ptr for debug */
|
||||
|
||||
u = uptr - ipl_unit; /* get link number */
|
||||
if ((uptr->flags & UNIT_ATT) == 0) return SCPE_OK; /* not attached? */
|
||||
|
@ -277,6 +394,14 @@ else uptr->IBUF = ((((int32) msg[0]) & 0377) << 8) |
|
|||
dev = ipl_dib[u].devno; /* get device number */
|
||||
clrCMD (dev); /* clr cmd, set flag */
|
||||
setFSR (dev);
|
||||
|
||||
uc = (uptr == &ipli_unit) ? 'I' : 'O'; /* identify unit for debug */
|
||||
dbdev = (uptr == &ipli_unit) ? &ipli_dev : &iplo_dev; /* identify device for debug */
|
||||
|
||||
if (DEBUG_PRJ (dbdev, DEB_XFER))
|
||||
fprintf (sim_deb, ">>IPL%c svc: Socket read = %06o, status = %d\n",
|
||||
uc, uptr->IBUF, nb);
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
@ -524,4 +649,3 @@ M[PC + IPL_DEVA] = devi;
|
|||
M[PC + PTR_DEVA] = devp;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
lps 12653A 2767 line printer
|
||||
12566B microcircuit interface with loopback diagnostic connector
|
||||
|
||||
10-May-07 RMS Added UNIT_TEXT flag
|
||||
11-Jan-07 JDB CLC cancels I/O event if DIAG (jumper W9 in "A" pos)
|
||||
Added ioCRS state to I/O decoders
|
||||
19-Nov-04 JDB Added restart when set online, etc.
|
||||
|
@ -207,7 +208,7 @@ t_stat lps_show_timing (FILE *st, UNIT *uptr, int32 val, void *desc);
|
|||
DIB lps_dib = { LPS, 0, 0, 0, 0, 0, &lpsio };
|
||||
|
||||
UNIT lps_unit = {
|
||||
UDATA (&lps_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_DISABLE, 0)
|
||||
UDATA (&lps_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_DISABLE+UNIT_TEXT, 0)
|
||||
};
|
||||
|
||||
REG lps_reg[] = {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* hp2100_lpt.c: HP 2100 12845B line printer simulator
|
||||
|
||||
Copyright (c) 1993-2006, Robert M. Supnik
|
||||
Copyright (c) 1993-2007, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
lpt 12845B 2607 line printer
|
||||
|
||||
22-Jan-07 RMS Added UNIT_TEXT flag
|
||||
28-Dec-06 JDB Added ioCRS state to I/O decoders (action unverified)
|
||||
19-Nov-04 JDB Added restart when set online, etc.
|
||||
29-Sep-04 JDB Added SET OFFLINE/ONLINE, POWEROFF/POWERON
|
||||
|
@ -113,7 +114,7 @@ t_stat lpt_attach (UNIT *uptr, char *cptr);
|
|||
DIB lpt_dib = { LPT, 0, 0, 0, 0, 0, &lptio };
|
||||
|
||||
UNIT lpt_unit = {
|
||||
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_DISABLE, 0)
|
||||
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_DISABLE+UNIT_TEXT, 0)
|
||||
};
|
||||
|
||||
REG lpt_reg[] = {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* hp2100_mux.c: HP 2100 12920A terminal multiplexor simulator
|
||||
|
||||
Copyright (c) 2002-2006, Robert M Supnik
|
||||
Copyright (c) 2002-2007, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,7 +25,19 @@
|
|||
|
||||
mux,muxl,muxc 12920A terminal multiplexor
|
||||
|
||||
28-Dec-06 JDB Added ioCRS state to I/O decoders (action unverified)
|
||||
06-Mar-07 JDB Corrected "mux_sta" size from 16 to 21 elements
|
||||
Fixed "muxc_reset" to clear lines 16-20
|
||||
26-Feb-07 JDB Added debug printouts
|
||||
Fixed control card OTx to set current channel number
|
||||
Fixed to set "muxl_ibuf" in response to a transmit interrupt
|
||||
Changed "mux_xbuf", "mux_rbuf" declarations from 8 to 16 bits
|
||||
Fixed to set "mux_rchp" when a line break is received
|
||||
Fixed incorrect "odd_par" table values
|
||||
Reversed test in "RCV_PAR" to return "LIL_PAR" on odd parity
|
||||
Fixed mux reset (ioCRS) to clear port parameters
|
||||
Fixed to use PUT_DCH instead of PUT_CCH for data channel status
|
||||
10-Feb-07 JDB Added DIAG/TERM modifiers to implement diagnostic mode
|
||||
28-Dec-06 JDB Added ioCRS state to I/O decoders
|
||||
02-Jun-06 JDB Fixed compiler warning for mux_ldsc init
|
||||
22-Nov-05 RMS Revised for new terminal processing routines
|
||||
29-Jun-05 RMS Added SET MUXLn DISCONNECT
|
||||
|
@ -60,7 +72,9 @@
|
|||
#define MUX_LINES 16 /* user lines */
|
||||
#define MUX_ILINES 5 /* diag rcv only */
|
||||
#define UNIT_V_MDM (TTUF_V_UF + 0) /* modem control */
|
||||
#define UNIT_V_DIAG (TTUF_V_UF + 1) /* loopback diagnostic */
|
||||
#define UNIT_MDM (1 << UNIT_V_MDM)
|
||||
#define UNIT_DIAG (1 << UNIT_V_DIAG)
|
||||
#define MUXU_INIT_POLL 8000
|
||||
#define MUXL_WAIT 500
|
||||
|
||||
|
@ -85,7 +99,8 @@
|
|||
#define OTL_V_BAUD 0 /* baud rate */
|
||||
#define OTL_M_BAUD 0377
|
||||
#define OTL_BAUD(x) (((x) >> OTL_V_BAUD) & OTL_M_BAUD)
|
||||
#define OTL_CHAR 01777 /* char mask */
|
||||
#define OTL_CHAR 03777 /* char mask */
|
||||
#define OTL_PAR 0200 /* char parity */
|
||||
|
||||
/* LIA, lower = received data */
|
||||
|
||||
|
@ -112,6 +127,7 @@
|
|||
#define OTC_EC1 0000100
|
||||
#define OTC_C2 0000040 /* Cn flops */
|
||||
#define OTC_C1 0000020
|
||||
#define OTC_V_C 4 /* S1 to C1 */
|
||||
#define OTC_ES2 0000010 /* enb comparison */
|
||||
#define OTC_ES1 0000004
|
||||
#define OTC_V_ES 2
|
||||
|
@ -139,14 +155,21 @@
|
|||
((muxc_ota[ch] & (OTC_ES2|OTC_ES1)) >> OTC_V_ES)) \
|
||||
<< LIC_V_I)
|
||||
|
||||
/* Debug flags */
|
||||
|
||||
#define DEB_CMDS (1 << 0) /* Command initiation and completion */
|
||||
#define DEB_CPU (1 << 1) /* CPU I/O */
|
||||
#define DEB_XFER (1 << 2) /* Socket receive and transmit */
|
||||
|
||||
extern uint32 PC;
|
||||
extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2], dev_srq[2];
|
||||
extern FILE *sim_deb;
|
||||
|
||||
uint16 mux_sta[MUX_LINES]; /* line status */
|
||||
uint16 mux_sta[MUX_LINES + MUX_ILINES]; /* line status */
|
||||
uint16 mux_rpar[MUX_LINES + MUX_ILINES]; /* rcv param */
|
||||
uint16 mux_xpar[MUX_LINES]; /* xmt param */
|
||||
uint8 mux_rbuf[MUX_LINES + MUX_ILINES]; /* rcv buf */
|
||||
uint8 mux_xbuf[MUX_LINES]; /* xmt buf */
|
||||
uint16 mux_rbuf[MUX_LINES + MUX_ILINES]; /* rcv buf */
|
||||
uint16 mux_xbuf[MUX_LINES]; /* xmt buf */
|
||||
uint8 mux_rchp[MUX_LINES + MUX_ILINES]; /* rcv chr pend */
|
||||
uint8 mux_xdon[MUX_LINES]; /* xmt done */
|
||||
uint8 muxc_ota[MUX_LINES]; /* ctrl: Cn,ESn,SSn */
|
||||
|
@ -171,6 +194,7 @@ t_stat muxo_svc (UNIT *uptr);
|
|||
t_stat muxc_reset (DEVICE *dptr);
|
||||
t_stat mux_attach (UNIT *uptr, char *cptr);
|
||||
t_stat mux_detach (UNIT *uptr);
|
||||
t_stat mux_setdiag (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
t_stat mux_summ (FILE *st, UNIT *uptr, int32 val, void *desc);
|
||||
t_stat mux_show (FILE *st, UNIT *uptr, int32 val, void *desc);
|
||||
void mux_data_int (void);
|
||||
|
@ -179,24 +203,33 @@ void mux_diag (int32 c);
|
|||
|
||||
static uint8 odd_par[256] = {
|
||||
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 000-017 */
|
||||
0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, /* 020-037 */
|
||||
0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, /* 040-067 */
|
||||
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, /* 020-037 */
|
||||
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, /* 040-067 */
|
||||
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 060-077 */
|
||||
0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, /* 100-117 */
|
||||
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, /* 100-117 */
|
||||
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 120-137 */
|
||||
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 140-157 */
|
||||
0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, /* 160-177 */
|
||||
0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, /* 200-217 */
|
||||
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, /* 160-177 */
|
||||
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, /* 200-217 */
|
||||
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 220-237 */
|
||||
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 240-257 */
|
||||
0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, /* 260-277 */
|
||||
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 240-267 */
|
||||
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, /* 260-277 */
|
||||
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 300-317 */
|
||||
0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, /* 320-337 */
|
||||
0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, /* 340-367 */
|
||||
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, /* 320-337 */
|
||||
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, /* 340-357 */
|
||||
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1 /* 360-377 */
|
||||
};
|
||||
|
||||
#define RCV_PAR(x) (odd_par[(x) & 0377]? LIL_PAR: 0)
|
||||
#define RCV_PAR(x) (odd_par[(x) & 0377] ? 0 : LIL_PAR)
|
||||
#define XMT_PAR(x) (odd_par[(x) & 0377] ? 0 : OTL_PAR)
|
||||
|
||||
/* Debug flags table */
|
||||
|
||||
DEBTAB mux_deb[] = {
|
||||
{ "CMDS", DEB_CMDS },
|
||||
{ "CPU", DEB_CPU },
|
||||
{ "XFER", DEB_XFER },
|
||||
{ NULL, 0 } };
|
||||
|
||||
DIB mux_dib[] = {
|
||||
{ MUXL, 0, 0, 0, 0, 0, &muxlio },
|
||||
|
@ -229,6 +262,8 @@ REG muxu_reg[] = {
|
|||
};
|
||||
|
||||
MTAB muxu_mod[] = {
|
||||
{ UNIT_DIAG, UNIT_DIAG, "diagnostic mode", "DIAG", &mux_setdiag },
|
||||
{ UNIT_DIAG, 0, "terminal mode", "TERM", &mux_setdiag },
|
||||
{ UNIT_ATT, UNIT_ATT, "connections", NULL, NULL, &mux_summ },
|
||||
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 1, "CONNECTIONS", NULL,
|
||||
NULL, &mux_show, NULL },
|
||||
|
@ -246,7 +281,8 @@ DEVICE muxu_dev = {
|
|||
1, 10, 31, 1, 8, 8,
|
||||
&tmxr_ex, &tmxr_dep, &muxc_reset,
|
||||
NULL, &mux_attach, &mux_detach,
|
||||
&muxu_dib, DEV_NET | DEV_DISABLE
|
||||
&muxu_dib, DEV_NET | DEV_DISABLE | DEV_DEBUG,
|
||||
0, mux_deb, NULL, NULL
|
||||
};
|
||||
|
||||
/* MUXL data structures
|
||||
|
@ -301,11 +337,11 @@ REG muxl_reg[] = {
|
|||
{ FLDATA (FLG, muxl_dib.flg, 0) },
|
||||
{ FLDATA (FBF, muxl_dib.fbf, 0) },
|
||||
{ FLDATA (SRQ, muxl_dib.srq, 0) },
|
||||
{ BRDATA (STA, mux_sta, 8, 16, MUX_LINES) },
|
||||
{ BRDATA (STA, mux_sta, 8, 16, MUX_LINES + MUX_ILINES) },
|
||||
{ BRDATA (RPAR, mux_rpar, 8, 16, MUX_LINES + MUX_ILINES) },
|
||||
{ BRDATA (XPAR, mux_xpar, 8, 16, MUX_LINES) },
|
||||
{ BRDATA (RBUF, mux_rbuf, 8, 8, MUX_LINES + MUX_ILINES) },
|
||||
{ BRDATA (XBUF, mux_xbuf, 8, 8, MUX_LINES) },
|
||||
{ BRDATA (RBUF, mux_rbuf, 8, 16, MUX_LINES + MUX_ILINES) },
|
||||
{ BRDATA (XBUF, mux_xbuf, 8, 16, MUX_LINES) },
|
||||
{ BRDATA (RCHP, mux_rchp, 8, 1, MUX_LINES + MUX_ILINES) },
|
||||
{ BRDATA (XDON, mux_xdon, 8, 1, MUX_LINES) },
|
||||
{ URDATA (TIME, muxl_unit[0].wait, 10, 24, 0,
|
||||
|
@ -362,13 +398,25 @@ DEVICE muxc_dev = {
|
|||
&muxc_dib, DEV_DISABLE
|
||||
};
|
||||
|
||||
/* IO instructions: data cards */
|
||||
/* IO instructions: data cards
|
||||
|
||||
Implementation note: the operating manual says that "at least 100
|
||||
milliseconds of CLC 0s must be programmed" by systems employing the
|
||||
multiplexer to ensure that the multiplexer resets. In practice, such systems
|
||||
issue 128K CLC 0 instructions. As we provide debug logging of multiplexer
|
||||
resets, a CRS counter is used to ensure that only one debug line is printed
|
||||
in response to these 128K CRS invocations.
|
||||
*/
|
||||
|
||||
int32 muxlio (int32 inst, int32 IR, int32 dat)
|
||||
{
|
||||
int32 dev, ln;
|
||||
t_bool is_crs;
|
||||
static uint32 crs_count = 0; /* cntr for crs repeat */
|
||||
|
||||
dev = IR & I_DEVMASK; /* get device no */
|
||||
is_crs = FALSE;
|
||||
|
||||
switch (inst) { /* case on opcode */
|
||||
|
||||
case ioFLG: /* flag clear/set */
|
||||
|
@ -385,37 +433,107 @@ switch (inst) { /* case on opcode */
|
|||
|
||||
case ioOTX: /* output */
|
||||
muxl_obuf = dat; /* store data */
|
||||
break;
|
||||
|
||||
case ioMIX: /* merge */
|
||||
dat = dat | muxl_ibuf;
|
||||
if (DEBUG_PRI (muxu_dev, DEB_CPU))
|
||||
if (dat & OTL_P)
|
||||
fprintf (sim_deb, ">>MUXl OTx: Parameter = %06o\n", dat);
|
||||
else
|
||||
fprintf (sim_deb, ">>MUXl OTx: Data = %06o\n", dat);
|
||||
break;
|
||||
|
||||
case ioLIX: /* load */
|
||||
dat = muxl_ibuf;
|
||||
dat = 0;
|
||||
|
||||
case ioMIX: /* merge */
|
||||
dat = dat | muxl_ibuf;
|
||||
|
||||
if (DEBUG_PRI (muxu_dev, DEB_CPU))
|
||||
fprintf (sim_deb, ">>MUXl LIx: Data = %06o\n", dat);
|
||||
break;
|
||||
|
||||
case ioCRS: /* control reset (action unverif) */
|
||||
case ioCRS: /* control reset */
|
||||
is_crs = TRUE;
|
||||
|
||||
if (crs_count) /* already reset? */
|
||||
break; /* skip redundant clear */
|
||||
|
||||
for (ln = 0; ln < MUX_LINES; ln++) { /* clear transmit info */
|
||||
mux_xbuf[ln] = mux_xpar[ln] = 0;
|
||||
muxc_ota[ln] = muxc_lia[ln] = mux_xdon[ln] = 0;
|
||||
}
|
||||
|
||||
for (ln = 0; ln < (MUX_LINES + MUX_ILINES); ln++) {
|
||||
mux_rbuf[ln] = mux_rpar[ln] = 0; /* clear receive info */
|
||||
mux_sta[ln] = mux_rchp[ln] = 0;
|
||||
} /* fall into CLC SC */
|
||||
|
||||
case ioCTL: /* control clear/set */
|
||||
if (IR & I_CTL) { clrCTL (dev); } /* CLC */
|
||||
if (IR & I_CTL) { /* CLC */
|
||||
clrCTL (dev);
|
||||
|
||||
if (DEBUG_PRI (muxu_dev, DEB_CMDS))
|
||||
fprintf (sim_deb, ">>MUXl CLC: Data interrupt inhibited\n");
|
||||
}
|
||||
else { /* STC */
|
||||
setCTL (dev); /* set ctl */
|
||||
ln = MUX_CHAN (muxu_obuf); /* get chan # */
|
||||
if (muxl_obuf & OTL_P) { /* parameter set? */
|
||||
|
||||
if (muxl_obuf & OTL_TX) { /* transmit? */
|
||||
if (ln < MUX_LINES) /* to valid line? */
|
||||
mux_xpar[ln] = muxl_obuf;
|
||||
if (ln < MUX_LINES) { /* line valid? */
|
||||
if (muxl_obuf & OTL_P) { /* parameter? */
|
||||
mux_xpar[ln] = muxl_obuf; /* store param value */
|
||||
if (DEBUG_PRI (muxu_dev, DEB_CMDS))
|
||||
fprintf (sim_deb,
|
||||
">>MUXl STC: Transmit channel %d parameter %06o stored\n",
|
||||
ln, muxl_obuf);
|
||||
}
|
||||
else 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? */
|
||||
(ln < MUX_LINES)) { /* to valid line? */
|
||||
if (sim_is_active (&muxl_unit[ln])) /* still working? */
|
||||
mux_sta[ln] = mux_sta[ln] | LIU_LOST;
|
||||
else sim_activate (&muxl_unit[ln], muxl_unit[ln].wait);
|
||||
mux_xbuf[ln] = muxl_obuf & OTL_CHAR; /* load buffer */
|
||||
else {
|
||||
if (muxu_unit.flags & UNIT_DIAG) /* loopback? */
|
||||
mux_ldsc[ln].conn = 1; /* connect this line */
|
||||
sim_activate (&muxl_unit[ln], muxl_unit[ln].wait);
|
||||
if (DEBUG_PRI (muxu_dev, DEB_CMDS))
|
||||
fprintf (sim_deb,
|
||||
">>MUXl STC: Transmit channel %d data %06o scheduled\n",
|
||||
ln, muxl_obuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (DEBUG_PRI (muxu_dev, DEB_CMDS)) /* line invalid */
|
||||
fprintf (sim_deb, ">>MUXl STC: Transmit channel %d invalid\n", ln);
|
||||
}
|
||||
|
||||
else /* receive */
|
||||
if (ln < (MUX_LINES + MUX_ILINES)) { /* line valid? */
|
||||
if (muxl_obuf & OTL_P) { /* parameter? */
|
||||
mux_rpar[ln] = muxl_obuf; /* store param value */
|
||||
if (DEBUG_PRI (muxu_dev, DEB_CMDS))
|
||||
fprintf (sim_deb,
|
||||
">>MUXl STC: Receive channel %d parameter %06o stored\n",
|
||||
ln, muxl_obuf);
|
||||
}
|
||||
|
||||
else if (DEBUG_PRI (muxu_dev, DEB_CMDS)) /* data (invalid action) */
|
||||
fprintf (sim_deb,
|
||||
">>MUXl STC: Receive channel %d parameter %06o invalid action\n",
|
||||
ln, muxl_obuf);
|
||||
}
|
||||
|
||||
else if (DEBUG_PRI (muxu_dev, DEB_CMDS)) /* line invalid */
|
||||
fprintf (sim_deb, ">>MUXl STC: Receive channel %d invalid\n", ln);
|
||||
} /* end STC */
|
||||
break;
|
||||
|
||||
|
@ -423,6 +541,16 @@ switch (inst) { /* case on opcode */
|
|||
break;
|
||||
}
|
||||
|
||||
if (is_crs) /* control reset? */
|
||||
crs_count = crs_count + 1; /* increment count */
|
||||
|
||||
else if (crs_count) { /* something else */
|
||||
if (DEBUG_PRI (muxu_dev, DEB_CMDS)) /* report reset count */
|
||||
fprintf (sim_deb,
|
||||
">>MUXl CRS: Multiplexer reset %d times\n", crs_count);
|
||||
crs_count = 0; /* clear counter */
|
||||
}
|
||||
|
||||
if (IR & I_HC) { /* H/C option */
|
||||
clrFSR (dev); /* clear flag */
|
||||
mux_data_int (); /* look for new int */
|
||||
|
@ -436,14 +564,19 @@ switch (inst) { /* case on opcode */
|
|||
|
||||
case ioOTX: /* output */
|
||||
muxu_obuf = dat; /* store data */
|
||||
break;
|
||||
|
||||
case ioMIX: /* merge */
|
||||
dat = dat | muxu_ibuf;
|
||||
if (DEBUG_PRI (muxu_dev, DEB_CPU))
|
||||
fprintf (sim_deb, ">>MUXu OTx: Data channel = %d\n", MUX_CHAN(dat));
|
||||
break;
|
||||
|
||||
case ioLIX: /* load */
|
||||
dat = muxu_ibuf;
|
||||
dat = 0;
|
||||
|
||||
case ioMIX: /* merge */
|
||||
dat = dat | muxu_ibuf;
|
||||
|
||||
if (DEBUG_PRI (muxu_dev, DEB_CPU))
|
||||
fprintf (sim_deb, ">>MUXu LIx: Status = %06o, channel = %d\n", dat, MUX_CHAN(dat));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -453,7 +586,12 @@ switch (inst) { /* case on opcode */
|
|||
return dat;
|
||||
}
|
||||
|
||||
/* IO instructions: control card */
|
||||
/* IO instructions: control card
|
||||
|
||||
In diagnostic mode, the control signals C1 and C2 are looped back to status
|
||||
signals S1 and S2. Changing the control signals may cause an interrupt, so a
|
||||
test is performed after OTx processing.
|
||||
*/
|
||||
|
||||
int32 muxcio (int32 inst, int32 IR, int32 dat)
|
||||
{
|
||||
|
@ -475,38 +613,65 @@ switch (inst) { /* case on opcode */
|
|||
break;
|
||||
|
||||
case ioOTX: /* output */
|
||||
ln = muxc_chan = OTC_CHAN (dat); /* set channel */
|
||||
|
||||
if (dat & OTC_SCAN) muxc_scan = 1; /* set scan flag */
|
||||
else muxc_scan = 0;
|
||||
|
||||
if (dat & OTC_UPD) { /* update? */
|
||||
ln = OTC_CHAN (dat); /* get channel */
|
||||
old = muxc_ota[ln]; /* save prior val */
|
||||
muxc_ota[ln] = (muxc_ota[ln] & ~OTC_RW) | /* save ESn,SSn */
|
||||
(dat & OTC_RW);
|
||||
if (dat & OTC_EC2) muxc_ota[ln] = /* if EC2, upd C2 */
|
||||
muxc_ota[ln] = /* save ESn,SSn */
|
||||
(muxc_ota[ln] & ~OTC_RW) | (dat & OTC_RW);
|
||||
|
||||
if (dat & OTC_EC2) /* if EC2, upd C2 */
|
||||
muxc_ota[ln] =
|
||||
(muxc_ota[ln] & ~OTC_C2) | (dat & OTC_C2);
|
||||
if (dat & OTC_EC1) 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);
|
||||
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_reset_ln (&mux_ldsc[ln]); /* reset line */
|
||||
muxc_lia[ln] = 0; /* dataset off */
|
||||
}
|
||||
} /* end update */
|
||||
|
||||
if (DEBUG_PRI (muxu_dev, DEB_CPU))
|
||||
fprintf (sim_deb, ">>MUXc OTx: Parameter = %06o, channel = %d\n",
|
||||
dat, ln);
|
||||
|
||||
if ((muxu_unit.flags & UNIT_DIAG) && /* loopback? */
|
||||
(!FLG(muxc_dib.devno))) /* flag clear? */
|
||||
mux_ctrl_int (); /* status chg may interrupt */
|
||||
break;
|
||||
|
||||
case ioLIX: /* load */
|
||||
dat = 0;
|
||||
|
||||
case ioMIX: /* merge */
|
||||
t = LIC_MBO | PUT_CCH (muxc_chan) | /* mbo, chan num */
|
||||
LIC_TSTI (muxc_chan) | /* I2, I1 */
|
||||
(muxc_ota[muxc_chan] & (OTC_ES2 | OTC_ES1)) | /* ES2, ES1 */
|
||||
(muxc_lia[muxc_chan] & (LIC_S2 | LIC_S1)); /* S2, S1 */
|
||||
dat = dat | t; /* return status */
|
||||
|
||||
if (DEBUG_PRI (muxu_dev, DEB_CPU))
|
||||
fprintf (sim_deb, ">>MUXc LIx: Status = %06o, channel = %d\n",
|
||||
dat, muxc_chan);
|
||||
|
||||
muxc_chan = (muxc_chan + 1) & LIC_M_CHAN; /* incr channel */
|
||||
break;
|
||||
|
||||
case ioCRS: /* control reset (action unverif) */
|
||||
case ioCRS: /* control reset */
|
||||
case ioCTL: /* ctrl clear/set */
|
||||
if (IR & I_CTL) { clrCTL (dev); } /* CLC */
|
||||
else { setCTL (dev); } /* STC */
|
||||
|
@ -532,7 +697,11 @@ return dat;
|
|||
t_stat muxi_svc (UNIT *uptr)
|
||||
{
|
||||
int32 ln, c, t;
|
||||
t_bool loopback;
|
||||
|
||||
loopback = ((muxu_unit.flags & UNIT_DIAG) != 0); /* diagnostic mode? */
|
||||
|
||||
if (!loopback) { /* terminal mode? */
|
||||
if ((uptr->flags & UNIT_ATT) == 0) return SCPE_OK; /* attached? */
|
||||
t = sim_rtcn_calb (mux_tps, TMR_MUX); /* calibrate */
|
||||
sim_activate (uptr, t); /* continue poll */
|
||||
|
@ -545,28 +714,53 @@ if (ln >= 0) { /* got one? */
|
|||
mux_ldsc[ln].rcve = 1; /* rcv enabled */
|
||||
}
|
||||
tmxr_poll_rx (&mux_desc); /* poll for input */
|
||||
}
|
||||
|
||||
for (ln = 0; ln < MUX_LINES; ln++) { /* loop thru lines */
|
||||
if (mux_ldsc[ln].conn) { /* connected? */
|
||||
if (c = tmxr_getc_ln (&mux_ldsc[ln])) { /* get char */
|
||||
if (loopback) { /* diagnostic mode? */
|
||||
c = mux_xbuf[ln ^ 1] & OTL_CHAR; /* get char from xmit line */
|
||||
if (c == 0) /* all char bits = 0? */
|
||||
c = c | SCPE_BREAK; /* set break flag */
|
||||
mux_ldsc[ln].conn = 0; /* clear connection */
|
||||
}
|
||||
|
||||
else
|
||||
c = tmxr_getc_ln (&mux_ldsc[ln]); /* get char from Telnet */
|
||||
|
||||
if (c) { /* valid char? */
|
||||
if (c & SCPE_BREAK) { /* break? */
|
||||
mux_sta[ln] = mux_sta[ln] | LIU_BRK;
|
||||
mux_rbuf[ln] = 0; /* no char */
|
||||
}
|
||||
else { /* normal */
|
||||
if (mux_rchp[ln]) mux_sta[ln] = mux_sta[ln] | LIU_LOST;
|
||||
if (mux_rchp[ln]) /* char already pending? */
|
||||
mux_sta[ln] = mux_sta[ln] | LIU_LOST;
|
||||
|
||||
if (!loopback) { /* terminal mode? */
|
||||
c = sim_tt_inpcvt (c, TT_GET_MODE (muxl_unit[ln].flags));
|
||||
if (mux_rpar[ln] & OTL_ECHO) { /* echo? */
|
||||
TMLN *lp = &mux_ldsc[ln]; /* get line */
|
||||
tmxr_putc_ln (lp, c); /* output char */
|
||||
tmxr_poll_tx (&mux_desc); /* poll xmt */
|
||||
}
|
||||
mux_rbuf[ln] = c; /* save char */
|
||||
mux_rchp[ln] = 1; /* char pending */
|
||||
}
|
||||
mux_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? */
|
||||
} /* end if char */
|
||||
} /* end if connected */
|
||||
else muxc_lia[ln] = 0; /* disconnected */
|
||||
|
||||
else /* not connected */
|
||||
if (!loopback) /* terminal mode? */
|
||||
muxc_lia[ln] = 0; /* line disconnected */
|
||||
} /* end for */
|
||||
if (!FLG (muxl_dib.devno)) mux_data_int (); /* scan for data int */
|
||||
if (!FLG (muxc_dib.devno)) mux_ctrl_int (); /* scan modem */
|
||||
|
@ -577,33 +771,55 @@ return SCPE_OK;
|
|||
|
||||
t_stat muxo_svc (UNIT *uptr)
|
||||
{
|
||||
int32 c, ln = uptr - muxl_unit; /* line # */
|
||||
int32 c, fc, ln, altln;
|
||||
t_bool loopback;
|
||||
|
||||
ln = uptr - muxl_unit; /* line # */
|
||||
altln = ln ^ 1; /* alt. line for diag mode */
|
||||
|
||||
fc = mux_xbuf[ln] & OTL_CHAR; /* full character data */
|
||||
c = fc & 0377; /* Telnet character data */
|
||||
|
||||
loopback = ((muxu_unit.flags & UNIT_DIAG) != 0); /* diagnostic mode? */
|
||||
|
||||
if (mux_ldsc[ln].conn) { /* connected? */
|
||||
if (mux_ldsc[ln].xmte) { /* xmt enabled? */
|
||||
if (loopback) /* diagnostic mode? */
|
||||
mux_ldsc[ln].conn = 0; /* clear connection */
|
||||
|
||||
if ((mux_xbuf[ln] & OTL_SYNC) == 0) { /* start bit 0? */
|
||||
TMLN *lp = &mux_ldsc[ln]; /* get line */
|
||||
c = mux_xbuf[ln]; /* get char */
|
||||
c = sim_tt_outcvt (c, TT_GET_MODE (muxl_unit[ln].flags));
|
||||
if (mux_xpar[ln] & OTL_DIAG) /* xmt diag? */
|
||||
mux_diag (mux_xbuf[ln]); /* before munge */
|
||||
mux_xdon[ln] = 1; /* set done */
|
||||
|
||||
/* In (default) UC or (new) 7P, all these chars are suppressed automatically */
|
||||
/* if ((TT_GET_MODE (muxl_unit[ln].flags) != TT_MODE_8B) &&
|
||||
/* (c != 0x7f) && (c != 0x13) && /* not del, ^S? */
|
||||
/* (c != 0x11) && (c != 0x5)) /* not ^Q, ^E? */
|
||||
if (mux_xpar[ln] & OTL_DIAG) /* xmt diagnose? */
|
||||
mux_diag (fc); /* before munge */
|
||||
|
||||
if (loopback) { /* diagnostic mode? */
|
||||
mux_ldsc[altln].conn = 1; /* set recv connection */
|
||||
sim_activate (&muxu_unit, 1); /* schedule receive */
|
||||
}
|
||||
|
||||
else { /* no loopback */
|
||||
if (c >= 0) /* valid? */
|
||||
tmxr_putc_ln (lp, c); /* output char */
|
||||
tmxr_poll_tx (&mux_desc); /* poll xmt */
|
||||
}
|
||||
}
|
||||
|
||||
mux_xdon[ln] = 1; /* set for xmit irq */
|
||||
|
||||
if (DEBUG_PRI (muxu_dev, DEB_XFER) && (loopback | (c >= 0)))
|
||||
fprintf (sim_deb, ">>MUXo svc: Line %d character %06o sent\n",
|
||||
ln, (loopback ? fc : c));
|
||||
}
|
||||
|
||||
else { /* buf full */
|
||||
tmxr_poll_tx (&mux_desc); /* poll xmt */
|
||||
sim_activate (uptr, muxl_unit[ln].wait); /* wait */
|
||||
return SCPE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (!FLG (muxl_dib.devno)) mux_data_int (); /* scan for int */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
@ -616,31 +832,48 @@ int32 i;
|
|||
|
||||
for (i = 0; i < MUX_LINES; i++) { /* rcv lines */
|
||||
if ((mux_rpar[i] & OTL_ENB) && mux_rchp[i]) { /* enabled, char? */
|
||||
muxl_ibuf = PUT_CCH (i) | mux_rbuf[i] | /* lo buf = char */
|
||||
muxl_ibuf = PUT_DCH (i) | /* lo buf = char */
|
||||
mux_rbuf[i] & LIL_CHAR |
|
||||
RCV_PAR (mux_rbuf[i]);
|
||||
muxu_ibuf = PUT_CCH (i) | mux_sta[i]; /* hi buf = stat */
|
||||
muxu_ibuf = PUT_DCH (i) | mux_sta[i]; /* hi buf = stat */
|
||||
mux_rchp[i] = 0; /* clr char, stat */
|
||||
mux_sta[i] = 0;
|
||||
|
||||
if (DEBUG_PRI (muxu_dev, DEB_CMDS))
|
||||
fprintf (sim_deb, ">>MUXd irq: Receive channel %d interrupt requested\n", i);
|
||||
|
||||
setFSR (muxl_dib.devno); /* interrupt */
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < MUX_LINES; i++) { /* xmt lines */
|
||||
if ((mux_xpar[i] & OTL_ENB) && mux_xdon[i]) { /* enabled, done? */
|
||||
muxu_ibuf = PUT_CCH (i) | mux_sta[i] | LIU_TR; /* hi buf = stat */
|
||||
muxl_ibuf = PUT_DCH (i) | /* lo buf = last rcv char */
|
||||
mux_rbuf[i] & LIL_CHAR |
|
||||
RCV_PAR (mux_rbuf[i]);
|
||||
muxu_ibuf = PUT_DCH (i) | mux_sta[i] | LIU_TR; /* hi buf = stat */
|
||||
mux_xdon[i] = 0; /* clr done, stat */
|
||||
mux_sta[i] = 0;
|
||||
|
||||
if (DEBUG_PRI (muxu_dev, DEB_CMDS))
|
||||
fprintf (sim_deb, ">>MUXd irq: Transmit channel %d interrupt requested\n", i);
|
||||
|
||||
setFSR (muxl_dib.devno); /* interrupt */
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (i = MUX_LINES; i < (MUX_LINES + MUX_ILINES); i++) { /* diag lines */
|
||||
if ((mux_rpar[i] & OTL_ENB) && mux_rchp[i]) { /* enabled, char? */
|
||||
muxl_ibuf = PUT_CCH (i) | mux_rbuf[i] | /* lo buf = char */
|
||||
muxl_ibuf = PUT_DCH (i) | /* lo buf = char */
|
||||
mux_rbuf[i] & LIL_CHAR |
|
||||
RCV_PAR (mux_rbuf[i]);
|
||||
muxu_ibuf = PUT_CCH (i) | mux_sta[i] | LIU_DG; /* hi buf = stat */
|
||||
muxu_ibuf = PUT_DCH (i) | mux_sta[i] | LIU_DG; /* hi buf = stat */
|
||||
mux_rchp[i] = 0; /* clr char, stat */
|
||||
mux_sta[i] = 0;
|
||||
|
||||
if (DEBUG_PRI (muxu_dev, DEB_CMDS))
|
||||
fprintf (sim_deb, ">>MUXd irq: Receive channel %d interrupt requested\n", i);
|
||||
|
||||
setFSR (muxl_dib.devno);
|
||||
return;
|
||||
}
|
||||
|
@ -648,16 +881,31 @@ for (i = MUX_LINES; i < (MUX_LINES + MUX_ILINES); i++) { /* diag lines */
|
|||
return;
|
||||
}
|
||||
|
||||
/* Look for control interrupt */
|
||||
/* Look for control interrupt
|
||||
|
||||
If either of the incoming status bits does not match the stored status, and
|
||||
the corresponding mismatch is enabled, a control interrupt request is
|
||||
generated. Depending on the scan flag, we check either all 16 lines or just
|
||||
the current line. If an interrupt is requested, the channel counter
|
||||
indicates the interrupting channel.
|
||||
*/
|
||||
|
||||
void mux_ctrl_int (void)
|
||||
{
|
||||
int32 i;
|
||||
int32 i, line_count;
|
||||
|
||||
if (muxc_scan == 0) return;
|
||||
for (i = 0; i < MUX_LINES; i++) {
|
||||
line_count = (muxc_scan ? MUX_LINES : 1); /* check one or all lines */
|
||||
|
||||
for (i = 0; i < line_count; i++) {
|
||||
if (muxc_scan) /* scanning? */
|
||||
muxc_chan = (muxc_chan + 1) & LIC_M_CHAN; /* step channel */
|
||||
if (LIC_TSTI (muxc_chan)) { /* status change? */
|
||||
|
||||
if (DEBUG_PRI (muxu_dev, DEB_CMDS))
|
||||
fprintf (sim_deb,
|
||||
">>MUXc irq: Control channel %d interrupt requested (poll = %d)\n",
|
||||
muxc_chan, i + 1);
|
||||
|
||||
setFSR (muxc_dib.devno); /* set flag */
|
||||
break;
|
||||
}
|
||||
|
@ -694,7 +942,8 @@ mux_rpar[i] = mux_xpar[i] = 0;
|
|||
mux_rchp[i] = mux_xdon[i] = 0;
|
||||
mux_sta[i] = 0;
|
||||
muxc_ota[i] = muxc_lia[i] = 0; /* clear modem */
|
||||
if (mux_ldsc[i].conn) /* connected? */
|
||||
if (mux_ldsc[i].conn && /* connected? */
|
||||
((muxu_unit.flags & UNIT_DIAG) == 0)) /* term mode? */
|
||||
muxc_lia[i] = muxc_lia[i] | DSR | /* cdet, dsr */
|
||||
(muxl_unit[i].flags & UNIT_MDM? CDET: 0);
|
||||
sim_cancel (&muxl_unit[i]);
|
||||
|
@ -733,7 +982,9 @@ if (muxu_unit.flags & UNIT_ATT) { /* master att? */
|
|||
}
|
||||
}
|
||||
else sim_cancel (&muxu_unit); /* else stop */
|
||||
for (i = 0; i < MUX_LINES; i++) mux_reset_ln (i);
|
||||
for (i = 0; i < MUX_LINES; i++) mux_reset_ln (i); /* reset lines 0-15 */
|
||||
for (i = MUX_LINES; i < (MUX_LINES + MUX_ILINES); i++) /* reset lines 16-20 */
|
||||
mux_rbuf[i] = mux_rpar[i] = mux_sta[i] = mux_rchp[i] = 0;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
@ -744,6 +995,9 @@ t_stat mux_attach (UNIT *uptr, char *cptr)
|
|||
t_stat r;
|
||||
int32 t;
|
||||
|
||||
if (muxu_unit.flags & UNIT_DIAG) /* diag mode? */
|
||||
return SCPE_NOFNC; /* command not allowed */
|
||||
|
||||
r = tmxr_attach (&mux_desc, uptr, cptr); /* attach */
|
||||
if (r != SCPE_OK) return r; /* error */
|
||||
t = sim_rtcn_init (muxu_unit.wait, TMR_MUX);
|
||||
|
@ -764,12 +1018,50 @@ sim_cancel (uptr); /* stop poll */
|
|||
return r;
|
||||
}
|
||||
|
||||
/* Diagnostic/normal mode routine
|
||||
|
||||
Diagnostic testing wants to exercise as much of the regular simulation code
|
||||
as possible to ensure good test coverage. Normally, input polling and output
|
||||
transmission only occurs on connected lines. In diagnostic mode, line
|
||||
connection flags are set selectively to enable processing on the lines under
|
||||
test. The alternative to this would require duplicating the send/receive
|
||||
code; the diagnostic would then test the copy but not the actual code used
|
||||
for normal character transfers, which is undesirable.
|
||||
|
||||
Therefore, to enable diagnostic mode, we must force a disconnect of the
|
||||
master socket and any connected Telnet lines, which clears the connection
|
||||
flags on all lines. Then we set the "transmission enabled" flags on all
|
||||
lines to enable output character processing for the diagnostic. (Normally,
|
||||
all of the flags are set when the multiplexer is first attached. Until then,
|
||||
the enable flags default to "not enabled," so we enable them explicitly
|
||||
here.)
|
||||
*/
|
||||
|
||||
t_stat mux_setdiag (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
{
|
||||
int32 ln;
|
||||
|
||||
if (val) { /* set diag? */
|
||||
mux_detach (uptr); /* detach lines */
|
||||
for (ln = 0; ln < MUX_LINES; ln++) /* enable transmission */
|
||||
mux_ldsc[ln].xmte = 1; /* on all lines */
|
||||
}
|
||||
else { /* set term */
|
||||
for (ln = 0; ln < MUX_LINES; ln++) /* clear connections */
|
||||
mux_ldsc[ln].conn = 0; /* on all lines */
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Show summary processor */
|
||||
|
||||
t_stat mux_summ (FILE *st, UNIT *uptr, int32 val, void *desc)
|
||||
{
|
||||
int32 i, t;
|
||||
|
||||
if (muxu_unit.flags & UNIT_DIAG) /* diag mode? */
|
||||
return SCPE_NOFNC; /* command not allowed */
|
||||
|
||||
for (i = t = 0; i < MUX_LINES; i++) t = t + (mux_ldsc[i].conn != 0);
|
||||
if (t == 1) fprintf (st, "1 connection");
|
||||
else fprintf (st, "%d connections", t);
|
||||
|
@ -782,6 +1074,9 @@ t_stat mux_show (FILE *st, UNIT *uptr, int32 val, void *desc)
|
|||
{
|
||||
int32 i, t;
|
||||
|
||||
if (muxu_unit.flags & UNIT_DIAG) /* diag mode? */
|
||||
return SCPE_NOFNC; /* command not allowed */
|
||||
|
||||
for (i = t = 0; i < MUX_LINES; i++) t = t + (mux_ldsc[i].conn != 0);
|
||||
if (t) {
|
||||
for (i = 0; i < MUX_LINES; i++) {
|
||||
|
@ -794,4 +1089,3 @@ if (t) {
|
|||
else fprintf (st, "all disconnected\n");
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* i1401_cd.c: IBM 1402 card reader/punch
|
||||
|
||||
Copyright (c) 1993-2005, Robert M. Supnik
|
||||
Copyright (c) 1993-2007, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -35,6 +35,7 @@
|
|||
Cards are represented as ASCII text streams terminated by newlines.
|
||||
This allows cards to be created and edited as normal files.
|
||||
|
||||
19-Jan-07 RMS Added UNIT_TEXT flag
|
||||
20-Sep-05 RMS Revised for new code tables, compatible colbinary treatment
|
||||
30-Aug-05 RMS Fixed read, punch to ignore modifier on 1,4 char inst
|
||||
(reported by Van Snyder)
|
||||
|
@ -73,7 +74,7 @@ char colbin_to_bcd (uint32 cb);
|
|||
*/
|
||||
|
||||
UNIT cdr_unit = {
|
||||
UDATA (&cdr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0), 100
|
||||
UDATA (&cdr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE+UNIT_TEXT, 0), 100
|
||||
};
|
||||
|
||||
REG cdr_reg[] = {
|
||||
|
@ -102,7 +103,7 @@ DEVICE cdr_dev = {
|
|||
*/
|
||||
|
||||
UNIT cdp_unit = {
|
||||
UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0)
|
||||
UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0)
|
||||
};
|
||||
|
||||
REG cdp_reg[] = {
|
||||
|
@ -134,11 +135,11 @@ DEVICE cdp_dev = {
|
|||
*/
|
||||
|
||||
UNIT stack_unit[] = {
|
||||
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) },
|
||||
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) },
|
||||
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) },
|
||||
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0) },
|
||||
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0) },
|
||||
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0) },
|
||||
{ UDATA (NULL, UNIT_DIS, 0) }, /* unused */
|
||||
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) }
|
||||
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0) }
|
||||
};
|
||||
|
||||
REG stack_reg[] = {
|
||||
|
@ -179,10 +180,10 @@ fgets (rbuf, (cbn)? 2 * CBUFSIZE: CBUFSIZE, /* rd bin/char card */
|
|||
cdr_unit.fileref);
|
||||
if (feof (cdr_unit.fileref)) return STOP_NOCD; /* eof? */
|
||||
if (ferror (cdr_unit.fileref)) { /* error? */
|
||||
ind[IN_READ] = 1;
|
||||
perror ("Card reader I/O error");
|
||||
clearerr (cdr_unit.fileref);
|
||||
if (iochk) return SCPE_IOERR;
|
||||
ind[IN_READ] = 1;
|
||||
return SCPE_OK;
|
||||
}
|
||||
cdr_unit.pos = ftell (cdr_unit.fileref); /* update position */
|
||||
|
@ -236,12 +237,12 @@ for (i = CDR_WIDTH - 1; (i >= 0) && (rbuf[i] == ' '); i--) rbuf[i] = 0;
|
|||
rbuf[CDR_WIDTH] = 0; /* null at end */
|
||||
fputs (rbuf, uptr->fileref); /* write card */
|
||||
fputc ('\n', uptr->fileref); /* plus new line */
|
||||
uptr->pos = ftell (uptr->fileref); /* update position */
|
||||
if (ferror (uptr->fileref)) { /* error? */
|
||||
perror ("Card stacker I/O error");
|
||||
clearerr (uptr->fileref);
|
||||
if (iochk) return SCPE_IOERR;
|
||||
}
|
||||
uptr->pos = ftell (uptr->fileref); /* update position */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
@ -293,13 +294,13 @@ else { /* normal */
|
|||
}
|
||||
fputs (pbuf, uptr->fileref); /* output card */
|
||||
fputc ('\n', uptr->fileref); /* plus new line */
|
||||
uptr->pos = ftell (uptr->fileref); /* update position */
|
||||
if (ferror (uptr->fileref)) { /* error? */
|
||||
perror ("Card punch I/O error");
|
||||
clearerr (uptr->fileref);
|
||||
if (iochk) return SCPE_IOERR;
|
||||
ind[IN_PNCH] = 1;
|
||||
}
|
||||
uptr->pos = ftell (uptr->fileref); /* update position */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* i1401_lp.c: IBM 1403 line printer simulator
|
||||
|
||||
Copyright (c) 1993-2005, Robert M. Supnik
|
||||
Copyright (c) 1993-2007, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
lpt 1403 line printer
|
||||
|
||||
19-Jan-07 RMS Added UNIT_TEXT flag
|
||||
07-Mar-05 RMS Fixed bug in write_line (reported by Van Snyder)
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
30-May-02 RMS Widened POS to 32b
|
||||
|
@ -69,7 +70,7 @@ char *pch_table[4] = {
|
|||
*/
|
||||
|
||||
UNIT lpt_unit = {
|
||||
UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0)
|
||||
UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0)
|
||||
};
|
||||
|
||||
REG lpt_reg[] = {
|
||||
|
@ -136,10 +137,10 @@ else {
|
|||
}
|
||||
lines = lflag = 0; /* clear cc action */
|
||||
if (ferror (lpt_unit.fileref)) { /* error? */
|
||||
ind[IN_LPT] = 1;
|
||||
perror ("Line printer I/O error");
|
||||
clearerr (lpt_unit.fileref);
|
||||
if (iochk) return SCPE_IOERR;
|
||||
ind[IN_LPT] = 1;
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* i1620_cd.c: IBM 1622 card reader/punch
|
||||
|
||||
Copyright (c) 2002-2006, Robert M. Supnik
|
||||
Copyright (c) 2002-2007, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -26,6 +26,7 @@
|
|||
cdr 1622 card reader
|
||||
cdp 1622 card punch
|
||||
|
||||
19-Jan-07 RMS Set UNIT_TEXT flag
|
||||
13-Jul-06 RMS Fixed card reader fgets call (from Tom McBride)
|
||||
Fixed card reader boot sequence (from Tom McBride)
|
||||
21-Sep-05 RMS Revised translation tables for 7094/1401 compatibility
|
||||
|
@ -63,7 +64,7 @@ t_stat cdp_num (uint32 pa, uint32 ndig, t_bool dump);
|
|||
*/
|
||||
|
||||
UNIT cdr_unit = {
|
||||
UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0)
|
||||
UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE+UNIT_TEXT, 0)
|
||||
};
|
||||
|
||||
REG cdr_reg[] = {
|
||||
|
@ -87,7 +88,7 @@ DEVICE cdr_dev = {
|
|||
*/
|
||||
|
||||
UNIT cdp_unit = {
|
||||
UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0)
|
||||
UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0)
|
||||
};
|
||||
|
||||
REG cdp_reg[] = {
|
||||
|
@ -421,13 +422,14 @@ while ((len > 0) && (cdp_buf[len - 1] == ' ')) --len; /* trim spaces */
|
|||
cdp_buf[len] = '\n'; /* newline, null */
|
||||
cdp_buf[len + 1] = 0;
|
||||
|
||||
if (fputs (cdp_buf, cdp_unit.fileref) == EOF) { /* write card */
|
||||
ind[IN_WRCHK] = 1; /* error? */
|
||||
fputs (cdp_buf, cdp_unit.fileref); /* write card */
|
||||
cdp_unit.pos = ftell (cdp_unit.fileref); /* count char */
|
||||
if (ferror (cdp_unit.fileref)) { /* error? */
|
||||
ind[IN_WRCHK] = 1;
|
||||
perror ("CDP I/O error");
|
||||
clearerr (cdp_unit.fileref);
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
cdp_unit.pos = ftell (cdp_unit.fileref); /* count char */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* i1620_lp.c: IBM 1443 line printer simulator
|
||||
|
||||
Copyright (c) 2002-2005, Robert M. Supnik
|
||||
Copyright (c) 2002-2007, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
lpt 1443 line printer
|
||||
|
||||
19-Jan-07 RMS Added UNIT_TEXT flag
|
||||
21-Sep-05 RMS Revised translation tables for 7094/1401 compatibility
|
||||
29-Dec-03 RMS Fixed bug in scheduling
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
|
@ -69,7 +70,7 @@ t_stat lpt_space (int32 lines, int32 lflag);
|
|||
*/
|
||||
|
||||
UNIT lpt_unit = {
|
||||
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE, 50)
|
||||
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 50)
|
||||
};
|
||||
|
||||
REG lpt_reg[] = {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* i7094_cd.c: IBM 711/721 card reader/punch
|
||||
|
||||
Copyright (c) 2003-2006, Robert M. Supnik
|
||||
Copyright (c) 2003-2007, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -26,6 +26,7 @@
|
|||
cdr 711 card reader
|
||||
cdp 721 card punch
|
||||
|
||||
19-Jan-07 RMS Added UNIT_TEXT
|
||||
13-Jul-06 RMS Fixed problem with 80 column full cards
|
||||
|
||||
Cards are represented as ASCII text streams terminated by newlines.
|
||||
|
@ -106,7 +107,7 @@ extern uint32 col_masks[12];
|
|||
DIB cdr_dib = { &cdr_chsel, NULL };
|
||||
|
||||
UNIT cdr_unit = {
|
||||
UDATA (&cdr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0)
|
||||
UDATA (&cdr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE+UNIT_TEXT, 0)
|
||||
};
|
||||
|
||||
REG cdr_reg[] = {
|
||||
|
@ -144,7 +145,7 @@ DEVICE cdr_dev = {
|
|||
DIB cdp_dib = { &cdp_chsel, &cdp_chwr };
|
||||
|
||||
UNIT cdp_unit = {
|
||||
UDATA (&cdp_svc, UNIT_SEQ+UNIT_ATTABLE, 0)
|
||||
UDATA (&cdp_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0)
|
||||
};
|
||||
|
||||
REG cdp_reg[] = {
|
||||
|
@ -443,12 +444,12 @@ for (i = ((2 * CD_CHRLNT) + 1); (i > 0) &&
|
|||
cdp_cbuf[i++] = '\n'; /* append nl */
|
||||
cdp_cbuf[i++] = 0; /* append nul */
|
||||
fputs (cdp_cbuf, uptr->fileref); /* write card */
|
||||
uptr->pos = ftell (uptr->fileref); /* update position */
|
||||
if (ferror (uptr->fileref)) { /* error? */
|
||||
perror ("CDP I/O error");
|
||||
clearerr (uptr->fileref);
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
uptr->pos = ftell (uptr->fileref); /* update position */
|
||||
cdp_sta = CDS_END; /* end state */
|
||||
sim_cancel (uptr); /* cancel current */
|
||||
sim_activate (uptr, cdp_tstop); /* long timer */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* i7094_cpu.c: IBM 7094 CPU simulator
|
||||
|
||||
Copyright (c) 2003-2006, Robert M. Supnik
|
||||
Copyright (c) 2003-2007, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
cpu 7094 central processor
|
||||
|
||||
28-Apr-07 RMS Removed clock initialization
|
||||
29-Oct-06 RMS Added additional expanded core instructions
|
||||
17-Oct-06 RMS Fixed the fix in halt IO wait loop
|
||||
16-Jun-06 RMS Fixed bug in halt IO wait loop
|
||||
|
@ -198,7 +199,6 @@ extern uint32 ch_sta[NUM_CHAN];
|
|||
extern uint32 ch_flags[NUM_CHAN];
|
||||
extern DEVICE mt_dev[NUM_CHAN];
|
||||
extern DEVICE ch_dev[NUM_CHAN];
|
||||
extern UNIT clk_unit;
|
||||
extern FILE *sim_deb;
|
||||
extern int32 sim_int_char;
|
||||
extern int32 sim_interval;
|
||||
|
@ -625,7 +625,6 @@ ind_reloc = ind_reloc & VA_BLK; /* canonical form */
|
|||
ind_start = ind_start & VA_BLK;
|
||||
ind_limit = (ind_limit & VA_BLK) | VA_OFF;
|
||||
chtr_pend = chtr_eval (NULL); /* eval chan traps */
|
||||
sim_rtcn_init (clk_unit.wait, TMR_CLK); /* init clock */
|
||||
tracing = ((hst_lnt != 0) || DEBUG_PRS (cpu_dev));
|
||||
|
||||
if (ht_pend) { /* HTR pending? */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* i7094_lp.c: IBM 716 line printer simulator
|
||||
|
||||
Copyright (c) 2003-2006, Robert M. Supnik
|
||||
Copyright (c) 2003-2007, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,8 @@
|
|||
|
||||
lpt 716 line printer
|
||||
|
||||
19-Jan-07 RMS Added UNIT_TEXT flag
|
||||
|
||||
Internally, the 7094 works only with column binary and is limited to
|
||||
72 columns of data. Each row of the printed line is represented by
|
||||
72b of data (two 36b words). A complete print line consists of 12 rows
|
||||
|
@ -142,7 +144,7 @@ extern char colbin_to_bcd (uint32 colbin);
|
|||
DIB lpt_dib = { &lpt_chsel, &lpt_chwr };
|
||||
|
||||
UNIT lpt_unit = {
|
||||
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_CONS, 0)
|
||||
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_CONS+UNIT_TEXT, 0)
|
||||
};
|
||||
|
||||
REG lpt_reg[] = {
|
||||
|
@ -306,7 +308,7 @@ return SCPE_OK;
|
|||
|
||||
t_stat lpt_end_line (UNIT *uptr)
|
||||
{
|
||||
uint32 i, j, col, row, bufw, colbin;
|
||||
uint32 i, col, row, bufw, colbin;
|
||||
char *pch, bcd, lpt_cbuf[LPT_CHRLNT + 1];
|
||||
t_uint64 dat;
|
||||
|
||||
|
@ -325,22 +327,23 @@ for (col = 0; col < 72; col++) { /* proc 72 columns */
|
|||
}
|
||||
for (i = LPT_CHRLNT; (i > 0) &&
|
||||
(lpt_cbuf[i - 1] == ' '); --i) ; /* trim spaces */
|
||||
lpt_cbuf[i++] = '\n'; /* append nl */
|
||||
lpt_cbuf[i] = 0; /* append nul */
|
||||
if (uptr->flags & UNIT_ATT) { /* file? */
|
||||
fxwrite (lpt_cbuf, 1, i, uptr->fileref); /* write line */
|
||||
fputs (lpt_cbuf, uptr->fileref); /* write line */
|
||||
fputc ('\n', uptr->fileref); /* append nl */
|
||||
uptr->pos = ftell (uptr->fileref); /* update position */
|
||||
if (ferror (uptr->fileref)) { /* error? */
|
||||
perror ("LPT I/O error");
|
||||
clearerr (uptr->fileref);
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
uptr->pos = ftell (uptr->fileref); /* update position */
|
||||
}
|
||||
else if (uptr->flags & UNIT_CONS) { /* print to console? */
|
||||
for (j = 0; j < i; j++) sim_putchar (lpt_cbuf[j]);
|
||||
for (i = 0; lpt_cbuf[i] != 0; i++) sim_putchar (lpt_cbuf[i]);
|
||||
sim_putchar ('\r');
|
||||
sim_putchar ('\n');
|
||||
}
|
||||
else return SCPE_UNATT; /* otherwise error */
|
||||
uptr->pos = uptr->pos + strlen (lpt_cbuf); /* count char */
|
||||
lpt_sta = LPS_END; /* end line state */
|
||||
sim_cancel (uptr); /* cancel current */
|
||||
sim_activate (uptr, lpt_tstop); /* long timer */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* id16_cpu.c: Interdata 16b CPU simulator
|
||||
|
||||
Copyright (c) 2000-2006, Robert M. Supnik
|
||||
Copyright (c) 2000-2007, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
cpu Interdata 16b CPU
|
||||
|
||||
28-Apr-07 RMS Removed clock initialization
|
||||
27-Oct-06 RMS Added idle support
|
||||
Removed separate PASLA clock
|
||||
06-Feb-06 RMS Fixed bug in DH (found by Mark Hittinger)
|
||||
|
@ -222,7 +223,6 @@ extern int32 sim_interval;
|
|||
extern int32 sim_int_char;
|
||||
extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
|
||||
extern t_bool sim_idle_enab;
|
||||
extern UNIT pic_unit, lfc_unit; /* timers */
|
||||
|
||||
uint32 ReadB (uint32 loc);
|
||||
uint32 ReadH (uint32 loc);
|
||||
|
@ -587,8 +587,6 @@ else {
|
|||
}
|
||||
int_eval (); /* eval interrupts */
|
||||
cc = newPSW (PSW & psw_mask); /* split PSW, eval wait */
|
||||
sim_rtcn_init (lfc_unit.wait, TMR_LFC); /* init clock */
|
||||
sim_rtcn_init (pic_unit.wait, TMR_PIC); /* init timer */
|
||||
reason = 0;
|
||||
|
||||
/* Process events */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* id32_cpu.c: Interdata 32b CPU simulator
|
||||
|
||||
Copyright (c) 2000-2006, Robert M. Supnik
|
||||
Copyright (c) 2000-2007, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
cpu Interdata 32b CPU
|
||||
|
||||
28-Apr-07 RMS Removed clock initialization
|
||||
27-Oct-06 RMS Added idle support
|
||||
Removed separate PASLA clock
|
||||
09-Mar-06 RMS Added 8 register bank support for 8/32
|
||||
|
@ -252,7 +253,6 @@ extern int32 sim_interval;
|
|||
extern int32 sim_int_char;
|
||||
extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
|
||||
extern t_bool sim_idle_enab;
|
||||
extern UNIT pic_unit, lfc_unit; /* timers */
|
||||
extern FILE *sim_deb;
|
||||
|
||||
uint32 ReadB (uint32 loc, uint32 rel);
|
||||
|
@ -627,8 +627,6 @@ if (cpu_unit.flags & UNIT_8RS) psw_reg_mask = 7; /* 8 register sets */
|
|||
else psw_reg_mask = 1; /* 2 register sets */
|
||||
int_eval (); /* eval interrupts */
|
||||
cc = newPSW (PSW & PSW_MASK); /* split PSW, eval wait */
|
||||
sim_rtcn_init (lfc_unit.wait, TMR_LFC); /* init clock */
|
||||
sim_rtcn_init (pic_unit.wait, TMR_PIC); /* init timer */
|
||||
reason = 0;
|
||||
|
||||
/* Abort handling
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* id_lp.c: Interdata line printer
|
||||
|
||||
Copyright (c) 2001-2005, Robert M. Supnik
|
||||
Copyright (c) 2001-2007, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
lpt M46-206 line printer
|
||||
|
||||
19-Jan-07 RMS Added UNIT_TEXT flag
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
*/
|
||||
|
||||
|
@ -83,7 +84,7 @@ t_stat lpt_spc (UNIT *uptr, int32 cnt);
|
|||
|
||||
DIB lpt_dib = { d_LPT, -1, v_LPT, NULL, &lpt, NULL };
|
||||
|
||||
UNIT lpt_unit = { UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_UC, 0) };
|
||||
UNIT lpt_unit = { UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_UC+UNIT_TEXT, 0) };
|
||||
|
||||
REG lpt_reg[] = {
|
||||
{ HRDATA (STA, lpt_sta, 8) },
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* nova_cpu.c: NOVA CPU simulator
|
||||
|
||||
Copyright (c) 1993-2006, Robert M. Supnik
|
||||
Copyright (c) 1993-2007, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
cpu Nova central processor
|
||||
|
||||
28-Apr-07 RMS Removed clock initialization
|
||||
06-Feb-06 RMS Fixed bug in DIVS (found by Mark Hittinger)
|
||||
22-Sep-05 RMS Fixed declarations (from Sterling Garwood)
|
||||
25-Aug-05 RMS Fixed DIVS case 2^31 / - 1
|
||||
|
@ -332,7 +333,6 @@ extern int32 sim_interval;
|
|||
int32 PC, IR, i;
|
||||
t_stat reason;
|
||||
void mask_out (int32 mask);
|
||||
extern int32 clk_sel, clk_time[4];
|
||||
|
||||
/* Restore register state */
|
||||
|
||||
|
@ -341,7 +341,6 @@ PC = saved_PC & AMASK; /* load local PC */
|
|||
C = C & CBIT;
|
||||
mask_out (pimask); /* reset int system */
|
||||
reason = 0;
|
||||
sim_rtc_init (clk_time[clk_sel]); /* init calibration */
|
||||
|
||||
/* Main instruction fetch/decode loop */
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* nova_lp.c: NOVA line printer simulator
|
||||
|
||||
Copyright (c) 1993-2005, Robert M. Supnik
|
||||
Copyright (c) 1993-2007, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
lpt line printer
|
||||
|
||||
19-Jan-07 RMS Added UNIT_TEXT
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
30-May-02 RMS Widened POS to 32b
|
||||
*/
|
||||
|
@ -49,7 +50,7 @@ t_stat lpt_reset (DEVICE *dptr);
|
|||
DIB lpt_dib = { DEV_LPT, INT_LPT, PI_LPT, &lpt };
|
||||
|
||||
UNIT lpt_unit = {
|
||||
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT
|
||||
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0), SERIAL_OUT_WAIT
|
||||
};
|
||||
|
||||
REG lpt_reg[] = {
|
||||
|
@ -110,12 +111,13 @@ dev_done = dev_done | INT_LPT; /* set done */
|
|||
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable);
|
||||
if ((lpt_unit.flags & UNIT_ATT) == 0) /* attached? */
|
||||
return IORETURN (lpt_stopioe, SCPE_UNATT);
|
||||
if (putc (lpt_unit.buf, lpt_unit.fileref) == EOF) {
|
||||
fputc (uptr->buf, uptr->fileref);
|
||||
uptr->pos = ftell (uptr->fileref);
|
||||
if (ferror (uptr->fileref)) {
|
||||
perror ("LPT I/O error");
|
||||
clearerr (lpt_unit.fileref);
|
||||
clearerr (uptr->fileref);
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
lpt_unit.pos = lpt_unit.pos + 1;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* pdp1_lp.c: PDP-1 line printer simulator
|
||||
|
||||
Copyright (c) 1993-2006, Robert M. Supnik
|
||||
Copyright (c) 1993-2007, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
lpt Type 62 line printer for the PDP-1
|
||||
|
||||
19-Jan-07 RMS Added UNIT_TEXT flag
|
||||
21-Dec-06 RMS Added 16-channel SBS support
|
||||
07-Sep-03 RMS Changed ioc to ios
|
||||
23-Jul-03 RMS Fixed bugs in instruction decoding, overprinting
|
||||
|
@ -67,7 +68,7 @@ t_stat lpt_reset (DEVICE *dptr);
|
|||
*/
|
||||
|
||||
UNIT lpt_unit = {
|
||||
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT
|
||||
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0), SERIAL_OUT_WAIT
|
||||
};
|
||||
|
||||
REG lpt_reg[] = {
|
||||
|
@ -166,6 +167,7 @@ if (lpt_spc) { /* space? */
|
|||
if ((uptr->flags & UNIT_ATT) == 0) /* attached? */
|
||||
return IORETURN (lpt_stopioe, SCPE_UNATT);
|
||||
fputs (lpt_cc[lpt_spc & 07], uptr->fileref); /* print cctl */
|
||||
uptr->pos = ftell (uptr->fileref); /* update position */
|
||||
if (ferror (uptr->fileref)) { /* error? */
|
||||
perror ("LPT I/O error");
|
||||
clearerr (uptr->fileref);
|
||||
|
@ -179,6 +181,7 @@ else {
|
|||
return IORETURN (lpt_stopioe, SCPE_UNATT);
|
||||
if (lpt_ovrpr) fputc ('\r', uptr->fileref); /* overprint? */
|
||||
fputs (lpt_buf, uptr->fileref); /* print buffer */
|
||||
uptr->pos = ftell (uptr->fileref); /* update position */
|
||||
if (ferror (uptr->fileref)) { /* test error */
|
||||
perror ("LPT I/O error");
|
||||
clearerr (uptr->fileref);
|
||||
|
@ -188,7 +191,6 @@ else {
|
|||
for (i = 0; i <= LPT_BSIZE; i++) lpt_buf[i] = 0; /* clear buffer */
|
||||
lpt_ovrpr = 1; /* set overprint */
|
||||
}
|
||||
lpt_unit.pos = ftell (uptr->fileref); /* update position */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* pdp10_cpu.c: PDP-10 CPU simulator
|
||||
|
||||
Copyright (c) 1993-2005, Robert M. Supnik
|
||||
Copyright (c) 1993-2007, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
cpu KS10 central processor
|
||||
|
||||
28-Apr-07 RMS Removed clock initialization
|
||||
22-Sep-05 RMS Fixed declarations (from Sterling Garwood)
|
||||
Fixed warning in MOVNI
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
|
@ -198,7 +199,6 @@ InstHistory *hst = NULL; /* instruction history *
|
|||
extern int32 sim_int_char;
|
||||
extern int32 sim_interval;
|
||||
extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
|
||||
extern UNIT tim_unit;
|
||||
|
||||
/* Forward and external declarations */
|
||||
|
||||
|
@ -633,7 +633,6 @@ pager_tc = FALSE; /* not in trap cycle */
|
|||
pager_pi = FALSE; /* not in pi sequence */
|
||||
rlog = 0; /* not in extend */
|
||||
pi_eval (); /* eval pi system */
|
||||
sim_rtc_init (tim_unit.wait); /* init calibration */
|
||||
if (!Q_ITS) its_1pr = 0; /* ~ITS, clr 1-proc */
|
||||
t20_idlelock = 0; /* clr T20 idle lock */
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* pdp10_lp20.c: PDP-10 LP20 line printer simulator
|
||||
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
Copyright (c) 1993-2007, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
lp20 line printer
|
||||
|
||||
19-Jan-07 RMS Added UNIT_TEXT flag
|
||||
04-Sep-05 RMS Fixed missing return (found by Peter Schorn)
|
||||
07-Jul-05 RMS Removed extraneous externs
|
||||
18-Mar-05 RMS Added attached test to detach routine
|
||||
|
@ -185,7 +186,7 @@ DIB lp20_dib = {
|
|||
};
|
||||
|
||||
UNIT lp20_unit = {
|
||||
UDATA (&lp20_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT
|
||||
UDATA (&lp20_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0), SERIAL_OUT_WAIT
|
||||
};
|
||||
|
||||
REG lp20_reg[] = {
|
||||
|
@ -527,8 +528,9 @@ else {
|
|||
if (lpcolc >= LP_WIDTH) /* line full? */
|
||||
r = lp20_adv (1, TRUE); /* adv carriage */
|
||||
}
|
||||
for (i = 0; i < rpt; i++) putc (lppdat, lp20_unit.fileref);
|
||||
lp20_unit.pos = lp20_unit.pos + rpt;
|
||||
for (i = 0; i < rpt; i++)
|
||||
fputc (lppdat, lp20_unit.fileref);
|
||||
lp20_unit.pos = ftell (lp20_unit.fileref);
|
||||
lpcolc = lpcolc + rpt;
|
||||
return r;
|
||||
}
|
||||
|
@ -539,8 +541,9 @@ int32 i;
|
|||
|
||||
if (cnt == 0) return TRUE;
|
||||
lpcolc = 0; /* reset col cntr */
|
||||
for (i = 0; i < cnt; i++) putc ('\n', lp20_unit.fileref);
|
||||
lp20_unit.pos = lp20_unit.pos + cnt; /* print 'n' newlines */
|
||||
for (i = 0; i < cnt; i++)
|
||||
fputc ('\n', lp20_unit.fileref);
|
||||
lp20_unit.pos = ftell (lp20_unit.fileref); /* print 'n' newlines */
|
||||
if (dvuadv) dvptr = (dvptr + cnt) % dvlnt; /* update DAVFU ptr */
|
||||
if (davfu[dvptr] & (1 << DV_TOF)) { /* at top of form? */
|
||||
if (lppagc = (lppagc - 1) & PAGC_MASK) { /* decr page cntr */
|
||||
|
@ -566,8 +569,8 @@ for (i = 0; i < dvlnt; i++) { /* search DAVFU */
|
|||
if (davfu[dvptr] & (1 << cnt)) { /* channel stop set? */
|
||||
if (cnt) return lp20_adv (i + 1, FALSE); /* ~TOF, adv */
|
||||
if (lpcolc) lp20_adv (1, FALSE); /* TOF, need newline? */
|
||||
putc ('\f', lp20_unit.fileref); /* print form feed */
|
||||
lp20_unit.pos = lp20_unit.pos + 1;
|
||||
fputc ('\f', lp20_unit.fileref); /* print form feed */
|
||||
lp20_unit.pos = ftell (lp20_unit.fileref);
|
||||
if (lppagc = (lppagc - 1) & PAGC_MASK) { /* decr page cntr */
|
||||
lpcsa = lpcsa & ~CSA_PZRO; /* update status */
|
||||
return TRUE;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* pdp10_tu.c - PDP-10 RH11/TM03/TU45 magnetic tape simulator
|
||||
|
||||
Copyright (c) 1993-2006, Robert M Supnik
|
||||
Copyright (c) 1993-2007, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
tu RH11/TM03/TU45 magtape
|
||||
|
||||
29-Apr-07 RMS Fixed bug in setting FCE on TMK (found by Naoki Hamada)
|
||||
16-Feb-06 RMS Added tape capacity checking
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
07-Jul-05 RMS Removed extraneous externs
|
||||
|
@ -871,6 +872,7 @@ switch (fnc) { /* case on function */
|
|||
tufs = tufs | FS_ID; /* PE BOT? ID burst */
|
||||
TXFR (ba, wc, 0); /* validate transfer */
|
||||
if (st = sim_tape_rdrecf (uptr, xbuf, &tbc, MT_MAXFR)) { /* read fwd */
|
||||
if (st == MTSE_TMK) set_tuer (ER_FCE); /* TMK also sets FCE */
|
||||
r = tu_map_err (uptr, st, 1); /* map error */
|
||||
break; /* done */
|
||||
}
|
||||
|
@ -924,6 +926,7 @@ switch (fnc) { /* case on function */
|
|||
tufc = 0; /* clear frame count */
|
||||
TXFR (ba, wc, 1); /* validate xfer rev */
|
||||
if (st = sim_tape_rdrecr (uptr, xbuf + 4, &tbc, MT_MAXFR)) { /* read rev */
|
||||
if (st == MTSE_TMK) set_tuer (ER_FCE); /* TMK also sets FCE */
|
||||
r = tu_map_err (uptr, st, 1); /* map error */
|
||||
break; /* done */
|
||||
}
|
||||
|
@ -1032,7 +1035,6 @@ switch (st) {
|
|||
return SCPE_IERR;
|
||||
|
||||
case MTSE_TMK: /* end of file */
|
||||
set_tuer (ER_FCE); /* also sets FCE */
|
||||
tufs = tufs | FS_TMK;
|
||||
break;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* pdp11_cpu.c: PDP-11 CPU simulator
|
||||
|
||||
Copyright (c) 1993-2006, Robert M Supnik
|
||||
Copyright (c) 1993-2007, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
cpu PDP-11 CPU
|
||||
|
||||
28-Apr-07 RMS Removed clock initialization
|
||||
27-Oct-06 RMS Added idle support
|
||||
18-Oct-06 RMS Fixed bug in ASH -32 C value
|
||||
24-May-06 RMS Added instruction history
|
||||
|
@ -298,7 +299,6 @@ int32 dsmask[4] = { MMR3_KDS, MMR3_SDS, 0, MMR3_UDS }; /* dspace enables */
|
|||
|
||||
extern int32 CPUERR, MAINT;
|
||||
extern int32 sim_interval;
|
||||
extern UNIT clk_unit, pclk_unit;
|
||||
extern int32 sim_int_char;
|
||||
extern uint32 sim_switches;
|
||||
extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
|
||||
|
@ -661,8 +661,6 @@ MMR0 = MMR0 | MMR0_IC; /* usually on */
|
|||
trap_req = calc_ints (ipl, trap_req); /* upd int req */
|
||||
trapea = 0;
|
||||
reason = 0;
|
||||
sim_rtcn_init (clk_unit.wait, TMR_CLK); /* init line clock */
|
||||
sim_rtcn_init (pclk_unit.wait, TMR_PCLK); /* init prog clock */
|
||||
|
||||
/* Abort handling
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* pdp11_cpumod.c: PDP-11 CPU model-specific features
|
||||
|
||||
Copyright (c) 2004-2005, Robert M Supnik
|
||||
Copyright (c) 2004-2007, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
system PDP-11 model-specific registers
|
||||
|
||||
29-Apr-07 RMS Don't run bus setup routine during RESTORE
|
||||
30-Aug-05 RMS Added additional 11/60 registers
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
15-Feb-05 RMS Fixed bug in SHOW MODEL (from Sergey Okhapkin)
|
||||
|
@ -83,6 +84,7 @@ extern FILE *sim_log;
|
|||
extern int32 STKLIM, PIRQ;
|
||||
extern uint32 cpu_model, cpu_type, cpu_opt;
|
||||
extern int32 clk_fie, clk_fnxm, clk_tps, clk_default;
|
||||
extern int32 sim_switches;
|
||||
|
||||
t_stat CPU24_rd (int32 *data, int32 addr, int32 access);
|
||||
t_stat CPU24_wr (int32 data, int32 addr, int32 access);
|
||||
|
@ -1100,7 +1102,8 @@ for (i = 0; i < clim; i = i + 2) nM[i >> 1] = M[i >> 1];
|
|||
free (M);
|
||||
M = nM;
|
||||
MEMSIZE = val;
|
||||
cpu_set_bus (cpu_opt);
|
||||
if (!(sim_switches & SIM_SW_REST)) /* unless restore, */
|
||||
cpu_set_bus (cpu_opt); /* alter periph config */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* pdp11_hk.c - RK611/RK06/RK07 disk controller
|
||||
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
Copyright (c) 1993-2007, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,8 @@
|
|||
|
||||
hk RK611/RK06/RK07 disk
|
||||
|
||||
29-Apr-07 RMS NOP and DCLR (at least) do not check drive type
|
||||
MR2 and MR3 only updated on NOP
|
||||
17-Nov-05 RMS Removed unused variable
|
||||
13-Nov-05 RMS Fixed overlapped seek interaction with NOP, DCLR, PACK
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
|
@ -314,6 +316,12 @@ extern uint16 *M;
|
|||
#define RDH2_V_DHA 5 /* decoded head */
|
||||
#define RDH2_GOOD 0140000 /* good sector flags */
|
||||
|
||||
/* Debug detail levels */
|
||||
|
||||
#define HKDEB_OPS 001 /* transactions */
|
||||
#define HKDEB_RRD 002 /* reg reads */
|
||||
#define HKDEB_RWR 004 /* reg writes */
|
||||
|
||||
extern int32 int_req[IPL_HLVL];
|
||||
extern FILE *sim_deb;
|
||||
|
||||
|
@ -338,7 +346,7 @@ int32 hk_min2wait = 300; /* min time to 2nd int *
|
|||
int16 hkdb[3] = { 0 }; /* data buffer silo */
|
||||
int16 hk_off[HK_NUMDR] = { 0 }; /* saved offset */
|
||||
int16 hk_dif[HK_NUMDR] = { 0 }; /* cylinder diff */
|
||||
static int32 reg_in_drive[16] = {
|
||||
static uint8 reg_in_drive[16] = {
|
||||
0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
DEVICE hk_dev;
|
||||
|
@ -453,12 +461,20 @@ MTAB hk_mod[] = {
|
|||
{ 0 }
|
||||
};
|
||||
|
||||
DEBTAB hk_deb[] = {
|
||||
{ "OPS", HKDEB_OPS },
|
||||
{ "RRD", HKDEB_RRD },
|
||||
{ "RWR", HKDEB_RWR },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
DEVICE hk_dev = {
|
||||
"HK", hk_unit, hk_reg, hk_mod,
|
||||
HK_NUMDR, DEV_RDX, 24, 1, DEV_RDX, 16,
|
||||
NULL, NULL, &hk_reset,
|
||||
&hk_boot, &hk_attach, &hk_detach,
|
||||
&hk_dib, DEV_DISABLE | DEV_UBUS | DEV_Q18 | DEV_DEBUG
|
||||
&hk_dib, DEV_DISABLE | DEV_UBUS | DEV_Q18 | DEV_DEBUG, 0,
|
||||
hk_deb, NULL, 0
|
||||
};
|
||||
|
||||
/* I/O dispatch routines, I/O addresses 17777440 - 17777476 */
|
||||
|
@ -538,14 +554,16 @@ switch (j) { /* decode PA<4:1> */
|
|||
break;
|
||||
|
||||
case 016: /* HKMR2 */
|
||||
*data = hkmr2 = hk_rdmr2 (GET_MS (hkmr));
|
||||
*data = hkmr2;
|
||||
break;
|
||||
|
||||
case 017: /* HKMR3 */
|
||||
*data = hkmr3 = hk_rdmr3 (GET_MS (hkmr));
|
||||
*data = hkmr3;
|
||||
break;
|
||||
}
|
||||
|
||||
if (DEBUG_PRI (hk_dev, HKDEB_RRD))
|
||||
fprintf (sim_deb, ">>HK%d read: reg%d=%o\n", drv, j, *data);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
@ -565,6 +583,8 @@ if ((hkcs1 & CS1_GO) && /* busy? */
|
|||
return SCPE_OK;
|
||||
}
|
||||
|
||||
if (DEBUG_PRI (hk_dev, HKDEB_RWR))
|
||||
fprintf (sim_deb, ">>HK%d write: reg%d=%o\n", drv, j, data);
|
||||
switch (j) { /* decode PA<4:1> */
|
||||
|
||||
case 000: /* HKCS1 */
|
||||
|
@ -648,23 +668,27 @@ void hk_go (int32 drv)
|
|||
int32 fnc, t;
|
||||
UNIT *uptr;
|
||||
|
||||
static int32 fnc_nxf[16] = {
|
||||
static uint8 fnc_cdt[16] = {
|
||||
0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
|
||||
};
|
||||
|
||||
static uint8 fnc_nxf[16] = {
|
||||
0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0
|
||||
};
|
||||
static int32 fnc_att[16] = {
|
||||
static uint8 fnc_att[16] = {
|
||||
0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0
|
||||
};
|
||||
static int32 fnc_rdy[16] = {
|
||||
static uint8 fnc_rdy[16] = {
|
||||
0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0
|
||||
};
|
||||
static int32 fnc_cyl[16] = {
|
||||
static uint8 fnc_cyl[16] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0
|
||||
};
|
||||
|
||||
fnc = GET_FNC (hkcs1);
|
||||
if (DEBUG_PRS (hk_dev)) fprintf (sim_deb,
|
||||
">>HK%d go: fnc=%o, ds=%o, cyl=%o, da=%o, ba=%o, wc=%o\n",
|
||||
drv, fnc, hkds[drv], hkdc, hkda, hkba, hkwc);
|
||||
if (DEBUG_PRI (hk_dev, HKDEB_OPS)) fprintf (sim_deb,
|
||||
">>HK%d strt: fnc=%o, cs1=%o, cs2=%o, ds=%o, er=%o, cyl=%o, da=%o, ba=%o, wc=%o\n",
|
||||
drv, fnc, hkcs1, hkcs2, hkds[drv], hker[drv], hkdc, hkda, hkba, hkwc);
|
||||
uptr = hk_dev.units + drv; /* get unit */
|
||||
if (fnc != FNC_NOP) hkmr = hkmr & ~MR_MS; /* !nop, clr msg sel */
|
||||
if (uptr->flags & UNIT_DIS) { /* nx unit? */
|
||||
|
@ -672,8 +696,9 @@ if (uptr->flags & UNIT_DIS) { /* nx unit? */
|
|||
update_hkcs (CS1_DONE, drv); /* done */
|
||||
return;
|
||||
}
|
||||
if (((hkcs1 & CS1_DT) != 0) != /* dtype mismatch? */
|
||||
((uptr->flags & UNIT_DTYPE) != 0)) {
|
||||
if (fnc_cdt[fnc] &&
|
||||
(((hkcs1 & CS1_DT) != 0) != /* need dtype match? */
|
||||
((uptr->flags & UNIT_DTYPE) != 0))) {
|
||||
hk_cmderr (ER_DTY, drv); /* type error */
|
||||
return;
|
||||
}
|
||||
|
@ -699,10 +724,15 @@ switch (fnc) { /* case on function */
|
|||
|
||||
/* Instantaneous functions (unit may be busy, can't schedule thread) */
|
||||
|
||||
case FNC_NOP: /* no operation */
|
||||
hkmr2 = hk_rdmr2 (GET_MS (hkmr)); /* get serial msgs */
|
||||
hkmr3 = hk_rdmr3 (GET_MS (hkmr));
|
||||
update_hkcs (CS1_DONE, drv); /* done */
|
||||
break;
|
||||
|
||||
case FNC_DCLR: /* drive clear */
|
||||
hkds[drv] &= ~DS_ATA; /* clr ATA */
|
||||
hker[drv] = 0; /* clear errors */
|
||||
case FNC_NOP: /* no operation */
|
||||
update_hkcs (CS1_DONE, drv); /* done */
|
||||
break;
|
||||
|
||||
|
@ -929,9 +959,6 @@ switch (fnc) { /* case on function */
|
|||
break;
|
||||
} /* end case func */
|
||||
|
||||
if (DEBUG_PRS (hk_dev)) fprintf (sim_deb,
|
||||
">>HK%d done: fnc=%o, cs1 = %o, cs2 = %o, ds=%o, cyl=%o, da=%o, ba=%o, wc=%o\n",
|
||||
drv, fnc, hkcs1, hkcs2, hkds[drv], hkdc, hkda, hkba, hkwc);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
@ -961,6 +988,11 @@ for (i = 0; i < HK_NUMDR; i++) { /* if ATA, set DI */
|
|||
}
|
||||
if (hker[drv] | (hkcs1 & (CS1_PAR | CS1_CTO)) | /* if err, set ERR */
|
||||
(hkcs2 & CS2_ERR)) hkcs1 = hkcs1 | CS1_ERR;
|
||||
if ((flag & CS1_DONE) && /* set done && debug? */
|
||||
(DEBUG_PRI (hk_dev, HKDEB_OPS)))
|
||||
fprintf (sim_deb,
|
||||
">>HK%d done: fnc=%o, cs1=%o, cs2=%o, ds=%o, er=%o, cyl=%o, da=%o, ba=%o, wc=%o\n",
|
||||
drv, GET_FNC (hkcs1), hkcs1, hkcs2, hkds[drv], hker[drv], hkdc, hkda, hkba, hkwc);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* pdp11_lp.c: PDP-11 line printer simulator
|
||||
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
Copyright (c) 1993-2007, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
lpt LP11 line printer
|
||||
|
||||
19-Jan-07 RMS Added UNIT_TEXT flag
|
||||
07-Jul-05 RMS Removed extraneous externs
|
||||
19-May-03 RMS Revised for new conditional compilation scheme
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
|
@ -76,7 +77,7 @@ DIB lpt_dib = {
|
|||
};
|
||||
|
||||
UNIT lpt_unit = {
|
||||
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT
|
||||
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0), SERIAL_OUT_WAIT
|
||||
};
|
||||
|
||||
REG lpt_reg[] = {
|
||||
|
@ -151,15 +152,16 @@ t_stat lpt_svc (UNIT *uptr)
|
|||
{
|
||||
lpt_csr = lpt_csr | CSR_ERR | CSR_DONE;
|
||||
if (lpt_csr & CSR_IE) SET_INT (LPT);
|
||||
if ((lpt_unit.flags & UNIT_ATT) == 0)
|
||||
if ((uptr->flags & UNIT_ATT) == 0)
|
||||
return IORETURN (lpt_stopioe, SCPE_UNATT);
|
||||
if (putc (lpt_unit.buf & 0177, lpt_unit.fileref) == EOF) {
|
||||
fputc (uptr->buf & 0177, uptr->fileref);
|
||||
uptr->pos = ftell (uptr->fileref);
|
||||
if (ferror (uptr->fileref)) {
|
||||
perror ("LPT I/O error");
|
||||
clearerr (lpt_unit.fileref);
|
||||
clearerr (uptr->fileref);
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
lpt_csr = lpt_csr & ~CSR_ERR;
|
||||
lpt_unit.pos = lpt_unit.pos + 1;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
tu TM02/TM03 magtape
|
||||
|
||||
29-Apr-07 RMS Fixed bug in setting FCE on TMK (found by Naoki Hamada)
|
||||
16-Feb-06 RMS Added tape capacity checking
|
||||
12-Nov-05 RMS Changed default formatter to TM03 (for VMS)
|
||||
31-Oct-05 RMS Fixed address width for large files
|
||||
|
@ -671,6 +672,7 @@ switch (fnc) { /* case on function */
|
|||
if ((uptr->UDENS == TC_1600) && sim_tape_bot (uptr))
|
||||
tufs = tufs | FS_ID; /* PE BOT? ID burst */
|
||||
if (st = sim_tape_rdrecf (uptr, xbuf, &tbc, MT_MAXFR)) { /* read fwd */
|
||||
if (st == MTSE_TMK) tu_set_er (ER_FCE); /* tmk also sets FCE */
|
||||
r = tu_map_err (drv, st, 1); /* map error */
|
||||
break; /* done */
|
||||
}
|
||||
|
@ -729,6 +731,7 @@ switch (fnc) { /* case on function */
|
|||
case FNC_WCHKR: /* wcheck = read */
|
||||
tufc = 0; /* clear frame count */
|
||||
if (st = sim_tape_rdrecr (uptr, xbuf + 4, &tbc, MT_MAXFR)) { /* read rev */
|
||||
if (st == MTSE_TMK) tu_set_er (ER_FCE); /* tmk also sets FCE */
|
||||
r = tu_map_err (drv, st, 1); /* map error */
|
||||
break; /* done */
|
||||
}
|
||||
|
@ -826,7 +829,6 @@ switch (st) {
|
|||
|
||||
case MTSE_TMK: /* end of file */
|
||||
tufs = tufs | FS_TMK;
|
||||
tu_set_er (ER_FCE); /* also sets FCE */
|
||||
break;
|
||||
|
||||
case MTSE_IOERR: /* IO error */
|
||||
|
|
|
@ -32,31 +32,37 @@
|
|||
These manuals can be found online at:
|
||||
http://www.spies.com/~aek/pdf/dec/unibus
|
||||
|
||||
|
||||
What this BETA version contains:
|
||||
1) Basic Transmit/Receive packet functionality.
|
||||
2) Promiscuous/All_Multicast/Multicast/MAC support
|
||||
|
||||
Testing performed:
|
||||
1) Receives/Transmits single packet under custom RSX driver
|
||||
2) Passes RSTS 10.1 controller diagnostics during boot
|
||||
3) VMS 7.2 on VAX780 summary:
|
||||
LAT - Runs properly both in and out
|
||||
DECNET - Starts without error, but will not do anything
|
||||
TCP/IP - Starts with errors, will ping in/out but nothing else
|
||||
Clustering - Not tested
|
||||
(May/2007: WinXP x64 host; MS VC++ 2005; SIMH v3.7-0 base; WinPcap 4.0)
|
||||
LAT - SET HOST/LAT in/out
|
||||
DECNET - SET HOST in/out, COPY in/out
|
||||
TCP/IP - PING in/out; SET HOST/TELNET out, COPY/FTP out
|
||||
- can't seem to connect in
|
||||
- possible TCPIP v5.0 misconfiguration?
|
||||
- issues with host WinXP firewall or Domain policy?
|
||||
Clustering - Successfully clustered with AlphaVMS 8.2
|
||||
- no hangs or offlines, some odd delays and jerkiness
|
||||
- out-of-order ring messages causing retransmits?
|
||||
- caused by ping times (min/avg/max) of 2/7/16 ms?
|
||||
4) Runs VAX EVDWA diagnostic tests 1-10; tests 11-19 (M68000/ROM/RAM) fail
|
||||
|
||||
Known issues:
|
||||
1) Transmit/Receive rings have not been thoroughly tested,
|
||||
particularly when and where the ring pointers get reset.
|
||||
2) Most auxiliary commands are not implemented yet.
|
||||
3) System_ID broadcast is not implemented
|
||||
4) Error/Interrupt signalling is still iffy from merge of FvK and sim_ether
|
||||
3) System_ID broadcast is not implemented.
|
||||
4) Error/Interrupt signalling is still iffy from merge of FvK and sim_ether.
|
||||
5) There are residual Map_ReadB and Map_WriteB from the FvK version that
|
||||
probably need to be converted to Map_ReadW and Map_WriteW calls.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Modification history:
|
||||
|
||||
03-May-07 DTH Added missing FC_RMAL command; cleared multicast on write
|
||||
29-Oct-06 RMS Synced poll and clock
|
||||
08-Dec-05 DTH Implemented ancilliary functions 022/023/024/025
|
||||
18-Nov-05 DTH Corrected time between system ID packets
|
||||
|
@ -598,7 +604,7 @@ t_stat xu_reset(DEVICE* dptr)
|
|||
int32 xu_command(CTLR* xu)
|
||||
{
|
||||
uint32 udbb;
|
||||
int fnc, mtlen;
|
||||
int fnc, mtlen, i, j;
|
||||
uint16 value, pltlen;
|
||||
t_stat status, rstatus, wstatus, wstatus2, wstatus3;
|
||||
struct xu_stats* stats = &xu->var->stats;
|
||||
|
@ -666,12 +672,24 @@ int32 xu_command(CTLR* xu)
|
|||
return PCSR0_PCEI;
|
||||
break;
|
||||
|
||||
case FC_RMAL: /* read multicast address list */
|
||||
mtlen = (xu->var->pcb[2] & 0xFF00) >> 8;
|
||||
udbb = xu->var->pcb[1] | ((xu->var->pcb[2] & 03) << 16);
|
||||
wstatus = Map_WriteB(udbb, mtlen * 3, (uint8*) &xu->var->setup.macs[1]);
|
||||
break;
|
||||
|
||||
case FC_WMAL: /* write multicast address list */
|
||||
mtlen = (xu->var->pcb[2] & 0xFF00) >> 8;
|
||||
sim_debug(DBG_TRC, xu->dev, "FC_WAL: mtlen=%d\n", mtlen);
|
||||
if (mtlen > 10)
|
||||
return PCSR0_PCEI;
|
||||
udbb = xu->var->pcb[1] | ((xu->var->pcb[2] & 03) << 16);
|
||||
/* clear existing multicast list */
|
||||
for (i=1; i<XU_FILTER_MAX; i++) {
|
||||
for (j=0; j<6; j++)
|
||||
xu->var->setup.macs[i][j] = 0;
|
||||
}
|
||||
/* get multicast list from host */
|
||||
rstatus = Map_ReadB(udbb, mtlen * 6, (uint8*) &xu->var->setup.macs[1]);
|
||||
if (rstatus == 0) {
|
||||
xu->var->setup.mac_count = mtlen + 1;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* pdp18b_cpu.c: 18b PDP CPU simulator
|
||||
|
||||
Copyright (c) 1993-2006, Robert M Supnik
|
||||
Copyright (c) 1993-2007, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
cpu PDP-4/7/9/15 central processor
|
||||
|
||||
28-Apr-07 RMS Removed clock initialization
|
||||
26-Dec-06 RMS Fixed boundary test in KT15/XVM (reported by Andrew Warkentin)
|
||||
30-Oct-06 RMS Added idle and infinite loop detection
|
||||
08-Oct-06 RMS Added RDCLK instruction
|
||||
|
@ -581,7 +582,6 @@ int32 api_int, api_usmd, skp;
|
|||
int32 iot_data, device, pulse;
|
||||
int32 last_IR;
|
||||
t_stat reason;
|
||||
extern UNIT clk_unit;
|
||||
|
||||
if (build_dev_tab ()) return SCPE_STOP; /* build, chk tables */
|
||||
PC = PC & AMASK; /* clean variables */
|
||||
|
@ -589,8 +589,8 @@ LAC = LAC & LACMASK;
|
|||
MQ = MQ & DMASK;
|
||||
reason = 0;
|
||||
last_IR = -1;
|
||||
sim_rtc_init (clk_unit.wait); /* init calibration */
|
||||
if (cpu_unit.flags & UNIT_NOAPI) api_enb = api_req = api_act = 0;
|
||||
if (cpu_unit.flags & UNIT_NOAPI) /* no API? */
|
||||
api_enb = api_req = api_act = 0;
|
||||
api_int = api_eval (&int_pend); /* eval API */
|
||||
api_usmd = 0; /* not API user cycle */
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* pdp18b_lp.c: 18b PDP's line printer simulator
|
||||
|
||||
Copyright (c) 1993-2006, Robert M Supnik
|
||||
Copyright (c) 1993-2007, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -28,6 +28,7 @@
|
|||
lp09 (PDP-9,15) LP09 line printer
|
||||
lp15 (PDP-15) LP15 line printer
|
||||
|
||||
19-Jan-07 RMS Added UNIT_TEXT flag
|
||||
11-Jun-06 RMS Made character translation table global scope
|
||||
14-Jan-04 RMS Revised IO device call interface
|
||||
23-Jul-03 RMS Fixed overprint bug in Type 62
|
||||
|
@ -95,7 +96,7 @@ t_stat lp62_reset (DEVICE *dptr);
|
|||
DIB lp62_dib = { DEV_LPT, 2, &lp62_iors, { &lp62_65, &lp62_66 } };
|
||||
|
||||
UNIT lp62_unit = {
|
||||
UDATA (&lp62_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT
|
||||
UDATA (&lp62_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0), SERIAL_OUT_WAIT
|
||||
};
|
||||
|
||||
REG lp62_reg[] = {
|
||||
|
@ -179,6 +180,7 @@ if (lp62_spc) { /* space? */
|
|||
if ((uptr->flags & UNIT_ATT) == 0) /* attached? */
|
||||
return IORETURN (lp62_stopioe, SCPE_UNATT);
|
||||
fputs (lp62_cc[lp62_spc & 07], uptr->fileref); /* print cctl */
|
||||
uptr->pos = ftell (uptr->fileref); /* update position */
|
||||
if (ferror (uptr->fileref)) { /* error? */
|
||||
perror ("LPT I/O error");
|
||||
clearerr (uptr->fileref);
|
||||
|
@ -192,6 +194,7 @@ else {
|
|||
return IORETURN (lp62_stopioe, SCPE_UNATT);
|
||||
if (lp62_ovrpr) fputc ('\r', uptr->fileref); /* overprint? */
|
||||
fputs (lp62_buf, uptr->fileref); /* print buffer */
|
||||
uptr->pos = ftell (uptr->fileref); /* update position */
|
||||
if (ferror (uptr->fileref)) { /* test error */
|
||||
perror ("LPT I/O error");
|
||||
clearerr (uptr->fileref);
|
||||
|
@ -201,7 +204,6 @@ else {
|
|||
for (i = 0; i <= LP62_BSIZE; i++) lp62_buf[i] = 0; /* clear buffer */
|
||||
lp62_ovrpr = 1; /* set overprint */
|
||||
}
|
||||
uptr->pos = ftell (uptr->fileref); /* update position */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
@ -274,7 +276,7 @@ t_stat lp647_detach (UNIT *uptr);
|
|||
DIB lp647_dib = { DEV_LPT, 2, &lp647_iors, { &lp647_65, &lp647_66 } };
|
||||
|
||||
UNIT lp647_unit = {
|
||||
UDATA (&lp647_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT
|
||||
UDATA (&lp647_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0), SERIAL_OUT_WAIT
|
||||
};
|
||||
|
||||
REG lp647_reg[] = {
|
||||
|
@ -393,7 +395,7 @@ return dat;
|
|||
t_stat lp647_svc (UNIT *uptr)
|
||||
{
|
||||
int32 i;
|
||||
char pbuf[LP647_BSIZE + 1];
|
||||
char pbuf[LP647_BSIZE + 2];
|
||||
|
||||
lp647_don = 1;
|
||||
if (lp647_ie) SET_INT (LPT); /* set flag */
|
||||
|
@ -405,8 +407,10 @@ if ((lp647_iot & 020) == 0) { /* print? */
|
|||
for (i = 0; i < lp647_bp; i++) /* translate buffer */
|
||||
pbuf[i] = lp647_buf[i] | ((lp647_buf[i] >= 040)? 0: 0100);
|
||||
if ((lp647_iot & 060) == 0) pbuf[lp647_bp++] = '\r';
|
||||
pbuf[lp647_bp++] = 0; /* append nul */
|
||||
for (i = 0; i < LP647_BSIZE; i++) lp647_buf[i] = 0; /* clear buffer */
|
||||
fwrite (pbuf, 1, lp647_bp, uptr->fileref); /* print buffer */
|
||||
fputs (pbuf, uptr->fileref); /* print buffer */
|
||||
uptr->pos = ftell (uptr->fileref); /* update position */
|
||||
if (ferror (uptr->fileref)) { /* error? */
|
||||
perror ("LPT I/O error");
|
||||
clearerr (uptr->fileref);
|
||||
|
@ -417,13 +421,13 @@ if ((lp647_iot & 020) == 0) { /* print? */
|
|||
}
|
||||
if (lp647_iot & 060) { /* space? */
|
||||
fputs (lp647_cc[lp647_iot & 07], uptr->fileref); /* write cctl */
|
||||
uptr->pos = ftell (uptr->fileref); /* update position */
|
||||
if (ferror (uptr->fileref)) { /* error? */
|
||||
perror ("LPT I/O error");
|
||||
clearerr (uptr->fileref);
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
}
|
||||
uptr->pos = ftell (uptr->fileref); /* update position */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
@ -501,7 +505,7 @@ t_stat lp09_detach (UNIT *uptr);
|
|||
DIB lp09_dib = { DEV_LPT, 2, &lp09_iors, { NULL, &lp09_66 } };
|
||||
|
||||
UNIT lp09_unit = {
|
||||
UDATA (&lp09_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT
|
||||
UDATA (&lp09_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0), SERIAL_OUT_WAIT
|
||||
};
|
||||
|
||||
REG lp09_reg[] = {
|
||||
|
@ -582,12 +586,13 @@ if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
|
|||
}
|
||||
c = uptr->buf & 0177; /* get char */
|
||||
if ((c == 0) || (c == 0177)) return SCPE_OK; /* skip NULL, DEL */
|
||||
if (fputc (c, uptr->fileref) == EOF) { /* print char */
|
||||
fputc (c, uptr->fileref); /* print char */
|
||||
uptr->pos = ftell (uptr->fileref); /* update position */
|
||||
if (ferror (uptr->fileref)) { /* error? */
|
||||
perror ("LPT I/O error");
|
||||
clearerr (uptr->fileref);
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
uptr->pos = uptr->pos + 1; /* update position */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
@ -657,7 +662,7 @@ int32 lp15_stopioe = 0;
|
|||
int32 lp15_mode = 0;
|
||||
int32 lp15_lc = 0;
|
||||
int32 lp15_bp = 0;
|
||||
char lp15_buf[LP15_BSIZE] = { 0 };
|
||||
char lp15_buf[LP15_BSIZE + 1] = { 0 };
|
||||
|
||||
DEVICE lp15_dev;
|
||||
int32 lp15_65 (int32 dev, int32 pulse, int32 dat);
|
||||
|
@ -678,7 +683,7 @@ int32 lp15_updsta (int32 new);
|
|||
DIB lp15_dib = { DEV_LPT, 2, &lp15_iors, { &lp15_65, &lp15_66 } };
|
||||
|
||||
UNIT lp15_unit = {
|
||||
UDATA (&lp15_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT
|
||||
UDATA (&lp15_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0), SERIAL_OUT_WAIT
|
||||
};
|
||||
|
||||
REG lp15_reg[] = {
|
||||
|
@ -786,8 +791,10 @@ for (more = 1; more != 0; ) { /* loop until ctrl */
|
|||
}
|
||||
for (i = 0; i < ccnt; i++) { /* loop through */
|
||||
if ((c[i] <= 037) && ctrl[c[i]]) { /* control char? */
|
||||
fwrite (lp15_buf, 1, lp15_bp, uptr->fileref);
|
||||
fputs (ctrl[c[i]], uptr->fileref);
|
||||
lp15_buf[lp15_bp] = 0; /* append nul */
|
||||
fputs (lp15_buf, uptr->fileref); /* print line */
|
||||
fputs (ctrl[c[i]], uptr->fileref); /* space */
|
||||
uptr->pos = ftell (uptr->fileref);
|
||||
if (ferror (uptr->fileref)) { /* error? */
|
||||
perror ("LPT I/O error");
|
||||
clearerr (uptr->fileref);
|
||||
|
@ -795,7 +802,6 @@ for (more = 1; more != 0; ) { /* loop until ctrl */
|
|||
lp15_updsta (STA_DON | STA_ALM);
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
uptr->pos = ftell (uptr->fileref);
|
||||
lp15_bp = more = 0;
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* pdp8_cpu.c: PDP-8 CPU simulator
|
||||
|
||||
Copyright (c) 1993-2006, Robert M Supnik
|
||||
Copyright (c) 1993-2007, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
cpu central processor
|
||||
|
||||
28-Apr-07 RMS Removed clock initialization
|
||||
30-Oct-06 RMS Added idle and infinite loop detection
|
||||
30-Sep-06 RMS Fixed SC value after DVI overflow (found by Don North)
|
||||
22-Sep-05 RMS Fixed declarations (from Sterling Garwood)
|
||||
|
@ -244,7 +245,6 @@ extern int32 sim_int_char;
|
|||
extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
|
||||
extern DEVICE *sim_devices[];
|
||||
extern FILE *sim_log;
|
||||
extern UNIT clk_unit, ttix_unit;
|
||||
extern t_bool sim_idle_enab;
|
||||
|
||||
t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw);
|
||||
|
@ -338,8 +338,6 @@ LAC = saved_LAC & 017777;
|
|||
MQ = saved_MQ & 07777;
|
||||
int_req = INT_UPDATE;
|
||||
reason = 0;
|
||||
sim_rtcn_init (clk_unit.wait, TMR_CLK); /* init clk calib */
|
||||
sim_rtcn_init (ttix_unit.wait, TMR_TTX); /* init ttx calib */
|
||||
|
||||
/* Main instruction fetch/decode loop */
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* pdp8_lp.c: PDP-8 line printer simulator
|
||||
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
Copyright (c) 1993-2007, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
lpt LP8E line printer
|
||||
|
||||
19-Jan-07 RMS Added UNIT_TEXT
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
04-Oct-02 RMS Added DIB, enable/disable, device number support
|
||||
30-May-02 RMS Widened POS to 32b
|
||||
|
@ -54,7 +55,7 @@ t_stat lpt_detach (UNIT *uptr);
|
|||
DIB lpt_dib = { DEV_LPT, 1, { &lpt } };
|
||||
|
||||
UNIT lpt_unit = {
|
||||
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT
|
||||
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0), SERIAL_OUT_WAIT
|
||||
};
|
||||
|
||||
REG lpt_reg[] = {
|
||||
|
@ -135,16 +136,17 @@ t_stat lpt_svc (UNIT *uptr)
|
|||
{
|
||||
dev_done = dev_done | INT_LPT; /* set done */
|
||||
int_req = INT_UPDATE; /* update interrupts */
|
||||
if ((lpt_unit.flags & UNIT_ATT) == 0) {
|
||||
if ((uptr->flags & UNIT_ATT) == 0) {
|
||||
lpt_err = 1;
|
||||
return IORETURN (lpt_stopioe, SCPE_UNATT);
|
||||
}
|
||||
if (putc (lpt_unit.buf, lpt_unit.fileref) == EOF) {
|
||||
fputc (uptr->buf, uptr->fileref); /* print char */
|
||||
uptr->pos = ftell (uptr->fileref);
|
||||
if (ferror (uptr->fileref)) { /* error? */
|
||||
perror ("LPT I/O error");
|
||||
clearerr (lpt_unit.fileref);
|
||||
clearerr (uptr->fileref);
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
lpt_unit.pos = lpt_unit.pos + 1;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* sds_cpu.c: SDS 940 CPU simulator
|
||||
|
||||
Copyright (c) 2001-2006, Robert M. Supnik
|
||||
Copyright (c) 2001-2007, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -26,6 +26,7 @@
|
|||
cpu central processor
|
||||
rtc real time clock
|
||||
|
||||
28-Apr-07 RMS Removed clock initialization
|
||||
29-Dec-06 RMS Fixed breakpoint variable declarations
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
07-Nov-04 RMS Added instruction history
|
||||
|
@ -195,7 +196,6 @@ int32 rtc_tps = 60; /* rtc ticks/sec */
|
|||
|
||||
extern int32 sim_int_char;
|
||||
extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
|
||||
extern UNIT mux_unit;
|
||||
|
||||
t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw);
|
||||
t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw);
|
||||
|
@ -373,8 +373,6 @@ api_lvl = api_lvl & ~1; /* <0> reserved */
|
|||
set_dyn_map (); /* set up mapping */
|
||||
int_reqhi = api_findreq (); /* recalc int req */
|
||||
chan_req = chan_testact (); /* recalc chan act */
|
||||
sim_rtcn_init (rtc_unit.wait, TMR_RTC); /* init calibration */
|
||||
sim_rtcn_init (mux_unit.wait, TMR_MUX); /* init calibration */
|
||||
|
||||
/* Main instruction fetch/decode loop */
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* sds_lp.c: SDS 940 line printer simulator
|
||||
|
||||
Copyright (c) 2001-2005, Robert M. Supnik
|
||||
Copyright (c) 2001-2007, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
lpt line printer
|
||||
|
||||
19-Jan-07 RMS Added UNIT_TEXT flag
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
*/
|
||||
|
||||
|
@ -77,7 +78,7 @@ t_stat lpt (uint32 fnc, uint32 inst, uint32 *dat);
|
|||
DIB lpt_dib = { CHAN_W, DEV_LPT, XFR_LPT, lpt_tplt, &lpt };
|
||||
|
||||
UNIT lpt_unit = {
|
||||
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE, 0)
|
||||
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_TEXT, 0)
|
||||
};
|
||||
|
||||
REG lpt_reg[] = {
|
||||
|
|
|
@ -51,6 +51,10 @@
|
|||
50. LDPCTX: 11/780 implements mbz tests on PCB fields.
|
||||
51. LDPCTX/MTPR: 11/780 validity checks PCBB, SCBB, SBR, SLR, P0BR, P0LR, P1BR, P1LR.
|
||||
52. TMR: tmr_inc not updated in standard (100Hz) mode.
|
||||
53. MTPR SBR/PCBB/SCBB: 11/780 only checks that bits<1:0> == 0.
|
||||
54. MTPR xLR: 11/780 excludes bits<31:24> from mbz test.
|
||||
55. MTPR PxBR: 11/780 only checks bits<31,1:0> == 1,00.
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* vax780_defs.h: VAX 780 model-specific definitions file
|
||||
|
||||
Copyright (c) 2004-2006, Robert M Supnik
|
||||
Copyright (c) 2004-2007, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -23,9 +23,11 @@
|
|||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
29-Oct-2006 RMS Added clock coscheduler function
|
||||
17-May-2006 RMS Added CR11/CD11 support (from John Dundas)
|
||||
10-May-2006 RMS Added model-specific reserved operand check macros
|
||||
29-Apr-07 RMS Modified model-specific reserved operand check macros
|
||||
to reflect 780 microcode patches (found by Naoki Hamada)
|
||||
29-Oct-06 RMS Added clock coscheduler function
|
||||
17-May-06 RMS Added CR11/CD11 support (from John Dundas)
|
||||
10-May-06 RMS Added model-specific reserved operand check macros
|
||||
|
||||
This file covers the VAX 11/780, the first VAX.
|
||||
|
||||
|
@ -119,10 +121,20 @@
|
|||
|
||||
/* Machine specific reserved operand tests */
|
||||
|
||||
#define ML_PA_TEST(r) if ((r) & 0xC0000003) RSVD_OPND_FAULT
|
||||
#define ML_LR_TEST(r) if ((uint32)(r) > 0x200000) RSVD_OPND_FAULT
|
||||
#define ML_BR_TEST(r) if ((((r) & 0xC0000000) != 0x80000000) || \
|
||||
/* 780 microcode patch 37 - only test LR<23:0> for appropriate length */
|
||||
|
||||
#define ML_LR_TEST(r) if ((uint32)((r) & 0xFFFFFF) > 0x200000) RSVD_OPND_FAULT
|
||||
|
||||
/* 780 microcode patch 38 - only test PxBR<31>=1 and xBR<1:0> = 0 */
|
||||
|
||||
#define ML_PXBR_TEST(r) if ((((r) & 0x80000000) == 0) || \
|
||||
((r) & 0x00000003)) RSVD_OPND_FAULT
|
||||
#define ML_SBR_TEST(r) if ((r) & 0x00000003) RSVD_OPND_FAULT
|
||||
|
||||
/* 780 microcode patch 78 - only test xCBB<1:0> = 0 */
|
||||
|
||||
#define ML_PA_TEST(r) if ((r) & 0x00000003) RSVD_OPND_FAULT
|
||||
|
||||
#define LP_AST_TEST(r) if ((r) > AST_MAX) RSVD_OPND_FAULT
|
||||
#define LP_MBZ84_TEST(r) if ((r) & 0xF8C00000) RSVD_OPND_FAULT
|
||||
#define LP_MBZ92_TEST(r) if ((r) & 0x7FC00000) RSVD_OPND_FAULT
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* vax_cpu.c: VAX CPU
|
||||
|
||||
Copyright (c) 1998-2006, Robert M Supnik
|
||||
Copyright (c) 1998-2007, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
cpu VAX central processor
|
||||
|
||||
28-Apr-07 RMS Removed clock initialization
|
||||
29-Oct-06 RMS Added idle support
|
||||
22-May-06 RMS Fixed format error in CPU history (found by Peter Schorn)
|
||||
10-May-06 RMS Added -kesu switches for virtual addressing modes
|
||||
|
@ -284,7 +285,6 @@ extern int32 sim_int_char;
|
|||
extern int32 sim_switches;
|
||||
extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
|
||||
extern t_bool sim_idle_enab;
|
||||
extern UNIT clk_unit;
|
||||
|
||||
extern t_stat build_dib_tab (void);
|
||||
extern UNIT rom_unit, nvr_unit;
|
||||
|
@ -501,7 +501,6 @@ set_map_reg (); /* set map reg */
|
|||
GET_CUR; /* set access mask */
|
||||
SET_IRQL; /* eval interrupts */
|
||||
FLUSH_ISTR; /* clear prefetch */
|
||||
sim_rtcn_init (clk_unit.wait, TMR_CLK); /* init clock */
|
||||
|
||||
abortval = setjmp (save_env); /* set abort hdlr */
|
||||
if (abortval > 0) { /* sim stop? */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* vax_cpu1.c: VAX complex instructions
|
||||
|
||||
Copyright (c) 1998-2006, Robert M Supnik
|
||||
Copyright (c) 1998-2007, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -23,6 +23,7 @@
|
|||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
29-Apr-07 RMS Separated base register access checks for 11/780
|
||||
10-May-06 RMS Added access check on system PTE for 11/780
|
||||
Added mbz check in LDPCTX for 11/780
|
||||
22-Sep-06 RMS Fixed declarations (from Sterling Garwood)
|
||||
|
@ -1230,7 +1231,7 @@ newpc = ReadLP (pcbpa + 72); /* get PC, PSL */
|
|||
newpsl = ReadLP (pcbpa + 76);
|
||||
|
||||
t = ReadLP (pcbpa + 80);
|
||||
ML_BR_TEST (t); /* validate P0BR */
|
||||
ML_PXBR_TEST (t); /* validate P0BR */
|
||||
P0BR = t & BR_MASK; /* restore P0BR */
|
||||
t = ReadLP (pcbpa + 84);
|
||||
LP_MBZ84_TEST (t); /* test mbz */
|
||||
|
@ -1240,7 +1241,7 @@ t = (t >> 24) & AST_MASK;
|
|||
LP_AST_TEST (t); /* validate AST */
|
||||
ASTLVL = t; /* restore AST */
|
||||
t = ReadLP (pcbpa + 88);
|
||||
ML_BR_TEST (t + 0x800000); /* validate P1BR */
|
||||
ML_PXBR_TEST (t + 0x800000); /* validate P1BR */
|
||||
P1BR = t & BR_MASK; /* restore P1BR */
|
||||
t = ReadLP (pcbpa + 92);
|
||||
LP_MBZ92_TEST (t); /* test MBZ */
|
||||
|
@ -1387,7 +1388,7 @@ switch (prn) { /* case on reg # */
|
|||
break;
|
||||
|
||||
case MT_P0BR: /* P0BR */
|
||||
ML_BR_TEST (val); /* validate */
|
||||
ML_PXBR_TEST (val); /* validate */
|
||||
P0BR = val & BR_MASK; /* lw aligned */
|
||||
zap_tb (0); /* clr proc TLB */
|
||||
set_map_reg ();
|
||||
|
@ -1401,7 +1402,7 @@ switch (prn) { /* case on reg # */
|
|||
break;
|
||||
|
||||
case MT_P1BR: /* P1BR */
|
||||
ML_BR_TEST (val + 0x800000); /* validate */
|
||||
ML_PXBR_TEST (val + 0x800000); /* validate */
|
||||
P1BR = val & BR_MASK; /* lw aligned */
|
||||
zap_tb (0); /* clr proc TLB */
|
||||
set_map_reg ();
|
||||
|
@ -1415,7 +1416,7 @@ switch (prn) { /* case on reg # */
|
|||
break;
|
||||
|
||||
case MT_SBR: /* SBR */
|
||||
ML_PA_TEST (val); /* validate */
|
||||
ML_SBR_TEST (val); /* validate */
|
||||
SBR = val & BR_MASK; /* lw aligned */
|
||||
zap_tb (1); /* clr entire TLB */
|
||||
set_map_reg ();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* vax_mmu.c - VAX memory management
|
||||
|
||||
Copyright (c) 1998-2005, Robert M Supnik
|
||||
Copyright (c) 1998-2007, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -23,6 +23,7 @@
|
|||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
29-Apr-07 RMS Added address masking for system page table reads
|
||||
22-Sep-05 RMS Fixed declarations (from Sterling Garwood)
|
||||
30-Sep-04 RMS Comment and formating changes
|
||||
19-Sep-03 RMS Fixed upper/lower case linkage problems on VMS
|
||||
|
@ -444,7 +445,7 @@ static TLBENT zero_pte = { 0, 0 };
|
|||
if (va & VA_S0) { /* system space? */
|
||||
if (ptidx >= d_slr) /* system */
|
||||
MM_ERR (PR_LNV);
|
||||
ptead = d_sbr + ptidx;
|
||||
ptead = (d_sbr + ptidx) & PAMASK;
|
||||
}
|
||||
else {
|
||||
if (va & VA_P1) { /* P1? */
|
||||
|
@ -463,7 +464,7 @@ else {
|
|||
ptidx = ((uint32) ptead) >> 7; /* xlate like sys */
|
||||
if (ptidx >= d_slr)
|
||||
MM_ERR (PR_PLNV);
|
||||
pte = ReadLP (d_sbr + ptidx); /* get system pte */
|
||||
pte = ReadLP ((d_sbr + ptidx) & PAMASK); /* get system pte */
|
||||
#if defined (VAX_780)
|
||||
if ((pte & PTE_ACC) == 0) MM_ERR (PR_PACV); /* spte ACV? */
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* vaxmod_defs.h: VAX model-specific definitions file
|
||||
|
||||
Copyright (c) 1998-2006, Robert M Supnik
|
||||
Copyright (c) 1998-2007, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -23,6 +23,7 @@
|
|||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
29-Apr-07 RMS Separated checks for PxBR and SBR
|
||||
17-May-06 RMS Added CR11/CD11 support
|
||||
10-May-06 RMS Added NOP'd reserved operand checking macros
|
||||
05-Oct-05 RMS Added XU definitions for autoconfigure
|
||||
|
@ -204,7 +205,8 @@
|
|||
|
||||
#define ML_PA_TEST(r)
|
||||
#define ML_LR_TEST(r)
|
||||
#define ML_BR_TEST(r)
|
||||
#define ML_SBR_TEST(r)
|
||||
#define ML_PXBR_TEST(r)
|
||||
#define LP_AST_TEST(r)
|
||||
#define LP_MBZ84_TEST(r)
|
||||
#define LP_MBZ92_TEST(r)
|
||||
|
|
4
makefile
4
makefile
|
@ -10,7 +10,11 @@ OS_CCDEFS = -lsocket -lnsl -lpthread -D_GNU_SOURCE
|
|||
else
|
||||
OS_CCDEFS = -D_GNU_SOURCE
|
||||
endif
|
||||
ifeq ($(OSTYPE),macos)
|
||||
CC = gcc -std=c99 -O2 -U__STRICT_ANSI__ -g -lm -lrt $(OS_CCDEFS) -I .
|
||||
else
|
||||
CC = gcc -std=c99 -O2 -U__STRICT_ANSI__ -g -lm $(OS_CCDEFS) -I .
|
||||
endif
|
||||
ifeq ($(USE_NETWORK),)
|
||||
else
|
||||
NETWORK_OPT = -DUSE_NETWORK -isystem /usr/local/include /usr/local/lib/libpcap.a
|
||||
|
|
22
scp.c
22
scp.c
|
@ -23,6 +23,10 @@
|
|||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
28-Apr-07 RMS Modified sim_instr invocation to call sim_rtcn_init_all
|
||||
Fixed bug in get_sim_opt
|
||||
Fixed bug in restoration with changed memory size
|
||||
08-Mar-07 JDB Fixed breakpoint actions in DO command file processing
|
||||
30-Jan-07 RMS Fixed bugs in get_ipaddr
|
||||
17-Oct-06 RMS Added idle support
|
||||
04-Oct-06 JDB DO cmd failure now echoes cmd unless -q
|
||||
|
@ -832,8 +836,10 @@ if ((fpin = fopen (do_arg[0], "r")) == NULL) { /* file failed to open?
|
|||
if (flag < 1) flag = 1; /* start at level 1 */
|
||||
|
||||
do {
|
||||
ocptr = cptr = sim_brk_getact (cbuf, CBUFSIZE); /* get bkpt action */
|
||||
if (!ocptr) /* no pending action? */
|
||||
ocptr = cptr = read_line (cbuf, CBUFSIZE, fpin); /* get cmd line */
|
||||
sub_args (cbuf, gbuf, CBUFSIZE, nargs, do_arg);
|
||||
sub_args (cbuf, gbuf, CBUFSIZE, nargs, do_arg); /* substitute args */
|
||||
if (cptr == NULL) { /* EOF? */
|
||||
stat = SCPE_OK; /* set good return */
|
||||
break;
|
||||
|
@ -2169,6 +2175,7 @@ if (v32) { /* [V3.2+] time as strin
|
|||
else READ_I (sim_time); /* sim time */
|
||||
READ_I (sim_rtime); /* [V2.6+] sim rel time */
|
||||
|
||||
sim_switches = SIM_SW_REST; /* flag restore */
|
||||
for ( ;; ) { /* device loop */
|
||||
READ_S (buf); /* read device name */
|
||||
if (buf[0] == 0) break; /* last? */
|
||||
|
@ -2214,7 +2221,6 @@ for ( ;; ) { /* device loop */
|
|||
(!(dptr->flags & DEV_NET) || /* not net dev or */
|
||||
!(uptr->flags & UNIT_ATT) || /* not currently att */
|
||||
(buf[0] == 0))) { /* or will not be att */
|
||||
sim_switches = SIM_SW_REST; /* att-det/rest */
|
||||
r = scp_detach_unit (dptr, uptr); /* detach old */
|
||||
if (r != SCPE_OK) return r;
|
||||
if (buf[0] != 0) { /* any file? */
|
||||
|
@ -2232,16 +2238,16 @@ for ( ;; ) { /* device loop */
|
|||
printf ("Can't restore memory: %s%d\n", sim_dname (dptr), unitno);
|
||||
return SCPE_INCOMP;
|
||||
}
|
||||
if (high != old_capac) {
|
||||
if (high != old_capac) { /* size change? */
|
||||
uptr->capac = old_capac; /* temp restore old */
|
||||
if ((dptr->flags & DEV_DYNM) &&
|
||||
((dptr->msize == NULL) ||
|
||||
(dptr->msize (uptr, (int32) high, NULL, NULL) != SCPE_OK))) {
|
||||
printf ("Can't change memory size: %s%d\n",
|
||||
sim_dname (dptr), unitno);
|
||||
uptr->capac = old_capac;
|
||||
return SCPE_INCOMP;
|
||||
}
|
||||
uptr->capac = high;
|
||||
uptr->capac = high; /* new memory size */
|
||||
printf ("Memory size changed: %s%d = ", sim_dname (dptr), unitno);
|
||||
fprint_capac (stdout, dptr, uptr);
|
||||
printf ("\n");
|
||||
|
@ -2382,6 +2388,7 @@ if (sim_step) sim_activate (&sim_step_unit, sim_step); /* set step timer */
|
|||
sim_throt_sched (); /* set throttle */
|
||||
sim_is_running = 1; /* flag running */
|
||||
sim_brk_clract (); /* defang actions */
|
||||
sim_rtcn_init_all (); /* re-init clocks */
|
||||
r = sim_instr();
|
||||
|
||||
sim_is_running = 0; /* flag idle */
|
||||
|
@ -3495,6 +3502,7 @@ return cptr;
|
|||
char *get_sim_opt (int32 opt, char *cptr, t_stat *st)
|
||||
{
|
||||
int32 t;
|
||||
t_bool dfdu;
|
||||
char *svptr, gbuf[CBUFSIZE];
|
||||
DEVICE *tdptr;
|
||||
UNIT *tuptr;
|
||||
|
@ -3508,6 +3516,7 @@ sim_stab.mask = 0;
|
|||
sim_stab.comp = 0;
|
||||
sim_dfdev = sim_dflt_dev;
|
||||
sim_dfunit = sim_dfdev->units;
|
||||
dfdu = FALSE; /* no default yet */
|
||||
*st = SCPE_OK;
|
||||
while (*cptr) { /* loop through modifiers */
|
||||
svptr = cptr; /* save current position */
|
||||
|
@ -3534,11 +3543,12 @@ while (*cptr) { /* loop through modifier
|
|||
else if ((opt & CMD_OPT_SCH) && /* if allowed, */
|
||||
get_search (gbuf, sim_dfdev->dradix, &sim_stab)) /* try for search */
|
||||
sim_schptr = &sim_stab; /* set search */
|
||||
else if ((opt & CMD_OPT_DFT) && /* if allowed, */
|
||||
else if ((opt & CMD_OPT_DFT) && !dfdu && /* if allowed, none yet*/
|
||||
(tdptr = find_unit (gbuf, &tuptr)) && /* try for default */
|
||||
(tuptr != NULL)) {
|
||||
sim_dfdev = tdptr; /* set as default */
|
||||
sim_dfunit = tuptr;
|
||||
dfdu = TRUE; /* indicate dflt seen */
|
||||
}
|
||||
else return svptr; /* not rec, break out */
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* sim_defs.h: simulator definitions
|
||||
|
||||
Copyright (c) 1993-2006, Robert M Supnik
|
||||
Copyright (c) 1993-2007, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -23,6 +23,8 @@
|
|||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
18-Mar-07 RMS Added UNIT_TEXT flag
|
||||
07-Mar-07 JDB Added DEBUG_PRJ macro
|
||||
18-Oct-06 RMS Added limit check for clock synchronized keyboard waits
|
||||
13-Jul-06 RMS Guarantee CBUFSIZE is at least 256
|
||||
07-Jan-06 RMS Added support for breakpoint spaces
|
||||
|
@ -363,6 +365,7 @@ struct sim_unit {
|
|||
#define UNIT_DISABLE 002000 /* disable-able */
|
||||
#define UNIT_DIS 004000 /* disabled */
|
||||
#define UNIT_RAW 010000 /* raw mode */
|
||||
#define UNIT_TEXT 020000 /* text mode */
|
||||
|
||||
#define UNIT_UFMASK_31 (((1u << UNIT_V_RSV) - 1) & ~((1u << UNIT_V_UF_31) - 1))
|
||||
#define UNIT_UFMASK (((1u << UNIT_V_RSV) - 1) & ~((1u << UNIT_V_UF) - 1))
|
||||
|
@ -470,6 +473,7 @@ struct sim_debtab {
|
|||
#define DEBUG_PRS(d) (sim_deb && d.dctrl)
|
||||
#define DEBUG_PRD(d) (sim_deb && d->dctrl)
|
||||
#define DEBUG_PRI(d,m) (sim_deb && (d.dctrl & (m)))
|
||||
#define DEBUG_PRJ(d,m) (sim_deb && (d->dctrl & (m)))
|
||||
|
||||
/* The following macros define structure contents */
|
||||
|
||||
|
|
59
sim_rev.h
59
sim_rev.h
|
@ -1,6 +1,6 @@
|
|||
/* sim_rev.h: simulator revisions and current rev level
|
||||
|
||||
Copyright (c) 1993-2006, Robert M Supnik
|
||||
Copyright (c) 1993-2007, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -29,12 +29,67 @@
|
|||
|
||||
#define SIM_MAJOR 3
|
||||
#define SIM_MINOR 7
|
||||
#define SIM_PATCH 0
|
||||
#define SIM_PATCH 1
|
||||
|
||||
/* V3.7 revision history
|
||||
|
||||
patch date module(s) and fix(es)
|
||||
|
||||
1 tbd scp.c:
|
||||
- modified sim_instr invocation to call sim_rtcn_init_all
|
||||
- fixed bug in get_sim_opt (reported by Don North)
|
||||
- fixed bug in RESTORE with changed memory size
|
||||
- added global 'RESTORE in progress' flag
|
||||
- fixed breakpoint actions in DO command file processing
|
||||
(from Dave Bryan)
|
||||
|
||||
all CPU's with clocks:
|
||||
- removed clock initialization (now done in SCP)
|
||||
|
||||
hp2100_cpu.c (from Dave Bryan):
|
||||
- EDT passes input flag and DMA channel in dat parameter
|
||||
|
||||
hp2100_ipl.c (from Dave Bryan):
|
||||
- IPLI EDT delays DMA completion interrupt for TSB
|
||||
|
||||
hp2100_mux.c (from Dave Bryan):
|
||||
- corrected "mux_sta" size from 16 to 21 elements
|
||||
- fixed "muxc_reset" to clear lines 16-20
|
||||
- fixed control card OTx to set current channel number
|
||||
- fixed to set "muxl_ibuf" in response to a transmit interrupt
|
||||
- changed "mux_xbuf", "mux_rbuf" declarations from 8 to 16 bits
|
||||
- fixed to set "mux_rchp" when a line break is received
|
||||
- fixed incorrect "odd_par" table values
|
||||
- reversed test in "RCV_PAR" to return "LIL_PAR" on odd parity
|
||||
- rixed mux reset (ioCRS) to clear port parameters
|
||||
- fixed to use PUT_DCH instead of PUT_CCH for data channel status
|
||||
- added DIAG/TERM modifiers to implement diagnostic mode
|
||||
|
||||
pdp11_cpumod.c:
|
||||
- changed memory size routine to work with RESTORE
|
||||
|
||||
pdp11_hk.c:
|
||||
- NOP and DCLR (at least) do not check drive type
|
||||
- MR2 and MR3 only updated on NOP
|
||||
|
||||
pdp10_tu.c, pdp11_tu.c:
|
||||
- TMK sets FCE only on read (found by Naoki Hamada)
|
||||
|
||||
pdp11_xu.c:
|
||||
- added missing FC_RMAL command
|
||||
- cleared multicast on write
|
||||
|
||||
vax_moddefs.h, vax_cpu1.c:
|
||||
- separated PxBR and SBR mbz checks
|
||||
|
||||
vax780_defs.h
|
||||
- separated PxBR and SBR mbz checks
|
||||
- modified mbz checks to reflect 780 microcode patches
|
||||
(found by Naoki Hamada)
|
||||
|
||||
vax_mmu.c:
|
||||
- added address masking to all SBR-based memory reads
|
||||
|
||||
0 30-Jan-07 scp.c:
|
||||
- implemented throttle commands
|
||||
- added -e to control error processing in DO command files
|
||||
|
|
14
sim_timer.c
14
sim_timer.c
|
@ -1,6 +1,6 @@
|
|||
/* sim_timer.c: simulator timer library
|
||||
|
||||
Copyright (c) 1993-2006, Robert M Supnik
|
||||
Copyright (c) 1993-2007, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -23,9 +23,9 @@
|
|||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
22-Aug-07 RMS Added sim_rtcn_init_all
|
||||
17-Oct-06 RMS Added idle support (based on work by Mark Pizzolato)
|
||||
Added throttle support
|
||||
21-Aug-05 RMS Added sim_rtcn_init_all
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
02-Jan-04 RMS Split out from SCP
|
||||
|
||||
|
@ -344,6 +344,16 @@ static int32 rtc_based[SIM_NTIMERS] = { 0 }; /* base delay */
|
|||
static int32 rtc_currd[SIM_NTIMERS] = { 0 }; /* current delay */
|
||||
static int32 rtc_initd[SIM_NTIMERS] = { 0 }; /* initial delay */
|
||||
|
||||
void sim_rtcn_init_all (void)
|
||||
{
|
||||
uint32 i;
|
||||
|
||||
for (i = 0; i < SIM_NTIMERS; i++) {
|
||||
if (rtc_initd[i] != 0) sim_rtcn_init (rtc_initd[i], i);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int32 sim_rtcn_init (int32 time, int32 tmr)
|
||||
{
|
||||
if (time == 0) time = 1;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* sim_timer.h: simulator timer library headers
|
||||
|
||||
Copyright (c) 1993-2006, Robert M Supnik
|
||||
Copyright (c) 1993-2007, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -23,6 +23,7 @@
|
|||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
28-Apr-07 RMS Added sim_rtc_init_all
|
||||
17-Oct-06 RMS Added idle support
|
||||
02-Jan-04 RMS Split out from SCP
|
||||
*/
|
||||
|
@ -48,6 +49,7 @@
|
|||
|
||||
t_bool sim_timer_init (void);
|
||||
int32 sim_rtcn_init (int32 time, int32 tmr);
|
||||
void sim_rtcn_init_all (void);
|
||||
int32 sim_rtcn_calb (int32 ticksper, int32 tmr);
|
||||
int32 sim_rtc_init (int32 time);
|
||||
int32 sim_rtc_calb (int32 ticksper);
|
||||
|
|
Loading…
Add table
Reference in a new issue