Notes For V3.0-1
RESTRICTION: The FP15 and XVM features of the PDP-15 are only partially debugged. Do NOT enable these features for normal operations. 1. New Features in 3.0-1 1.1 PDP-1 - Added block loader format support to LOAD. - Changed BOOT PTR to allow loading of all of the first bank of memory. 1.2 PDP-18b Family - Added PDP-4 EAE support. - Added PDP-15 FP15 support. - Added PDP-15 XVM support. - Added PDP-15 "re-entrancy ECO". - Added PDP-7, PDP-9, PDP-15 hardware RIM loader support in BOOT PTR. 2. Bugs Fixed in 3.0-1 2.1 PDP-11/VAX - Fixed bug in user disk size (found by Chaskiel M Grundman). 2.2 PDP-1 - Updated CPU, line printer, standard devices to detect indefinite I/O wait. - Fixed incorrect logical, missing activate, break in drum simulator. - Fixed bugs in instruction decoding, overprinting for line printer. 2.3 PDP-10 - Fixed bug in RP read header. 2.4 PDP-18b Family - Fixed bug in PDP-4 line printer overprinting. - Fixed bug in PDP-15 memory protect/skip interaction. - Fixed bug in RF set size routine. - Increased PTP TIME for PDP-15 operating systems. 2.5 PDP-8 - Fixed bug in DF, RF set size routine. 2.6 Nova - Fixed bug in DSK set size routine. 2.7 1401 - Revised fetch to model hardware more closely. 2.8 Ibm1130 - Fixed bugs found by APL 1130. 2.9 Altairz80 - Fixed bug in real-time clock on Windows host. 2.10 HP2100 -- Fixed DR drum sizes. -- Fixed DR variable capacity interaction with SAVE/RESTORE. 3. New Features in 3.0 vs prior releases 3.1 SCP and Libraries - Added ASSIGN/DEASSIGN (logical name) commands. - Changed RESTORE to unconditionally detach files. - Added E11 and TPC format support to magtape library. - Fixed bug in SHOW CONNECTIONS. - Added USE_ADDR64 support 3.2 All magtapes - Magtapes support SIMH format, E11 format, and TPC format (read only). - SET <tape_unit> FORMAT=format sets the specified tape unit's format. - SHOW <tape_unit> FORMAT displays the specified tape unit's format. - Tape format can also be set as part of the ATTACH command, using the -F switch. 3.3 VAX - VAX can be compiled without USE_INT64. - If compiled with USE_INT64 and USE_ADDR64, RQ and TQ controllers support files > 2GB. - VAX ROM has speed control (SET ROM DELAY/NODELAY). 4. Bugs Fixed in 3.0 vs prior releases 4.1 VAX - Fixed CVTfi bug: integer overflow not set if exponent out of range - Fixed EMODx bugs: o First and second operands reversed o Separated fraction received wrong exponent o Overflow calculation on separated integer incorrect o Fraction not set to zero if exponent out of range - Fixed interval timer and ROM access to pass power-up self-test even on very fast host processors (fixes from Mark Pizzolato). 4.2 1401 - Fixed mnemonic, instruction lengths, and reverse scan length check bug for MCS. - Fixed MCE bug, BS off by 1 if zero suppress. - Fixed chaining bug, D lost if return to SCP. - Fixed H branch, branch occurs after continue. - Added check for invalid 8 character MCW, LCA. - Fixed magtape load-mode end of record response. 4.3 Nova - Fixed DSK variable size interaction with restore. 4.4 PDP-1 - Fixed DT variable size interaction with restore. 4.5 PDP-11 - Fixed DT variable size interaction with restore. - Fixed bug in MMR1 update (found by Tim Stark). - Added XQ features and fixed bugs: o Corrected XQ interrupts on IE state transition (code by Tom Evans). o Added XQ interrupt clear on soft reset. o Removed XQ interrupt when setting XL or RL (multiple people). o Added SET/SHOW XQ STATS. o Added SHOW XQ FILTERS. o Added ability to split received packet into multiple buffers. o Added explicit runt and giant packet processing. 4.6 PDP-18B - Fixed DT, RF variable size interaction with restore. - Fixed MT bug in MTTR. 4.7 PDP-8 - Fixed DT, DF, RF, RX variable size interaction with restore. - Fixed MT bug in SKTR. 4.8 HP2100 - Fixed bug in DP (13210A controller only), DQ read status. - Fixed bug in DP, DQ seek complete. 4.9 GRI - Fixed bug in SC queue pointer management.
This commit is contained in:
parent
4ffd3be790
commit
f9564b81b9
74 changed files with 6938 additions and 2812 deletions
117
0readme_30.txt
117
0readme_30.txt
|
@ -1,11 +1,75 @@
|
||||||
Notes For V3.0-0
|
Notes For V3.0-1
|
||||||
|
|
||||||
Because some key files have changed, V3.0 should be unzipped to a
|
RESTRICTION: The FP15 and XVM features of the PDP-15 are only partially
|
||||||
clean directory.
|
debugged. Do NOT enable these features for normal operations.
|
||||||
|
|
||||||
1. New Features in 3.0-0
|
1. New Features in 3.0-1
|
||||||
|
|
||||||
1.1 SCP and Libraries
|
1.1 PDP-1
|
||||||
|
|
||||||
|
- Added block loader format support to LOAD.
|
||||||
|
- Changed BOOT PTR to allow loading of all of the first bank of memory.
|
||||||
|
|
||||||
|
1.2 PDP-18b Family
|
||||||
|
|
||||||
|
- Added PDP-4 EAE support.
|
||||||
|
- Added PDP-15 FP15 support.
|
||||||
|
- Added PDP-15 XVM support.
|
||||||
|
- Added PDP-15 "re-entrancy ECO".
|
||||||
|
- Added PDP-7, PDP-9, PDP-15 hardware RIM loader support in BOOT PTR.
|
||||||
|
|
||||||
|
2. Bugs Fixed in 3.0-1
|
||||||
|
|
||||||
|
2.1 PDP-11/VAX
|
||||||
|
|
||||||
|
- Fixed bug in user disk size (found by Chaskiel M Grundman).
|
||||||
|
|
||||||
|
2.2 PDP-1
|
||||||
|
|
||||||
|
- Updated CPU, line printer, standard devices to detect indefinite I/O wait.
|
||||||
|
- Fixed incorrect logical, missing activate, break in drum simulator.
|
||||||
|
- Fixed bugs in instruction decoding, overprinting for line printer.
|
||||||
|
|
||||||
|
2.3 PDP-10
|
||||||
|
|
||||||
|
- Fixed bug in RP read header.
|
||||||
|
|
||||||
|
2.4 PDP-18b Family
|
||||||
|
|
||||||
|
- Fixed bug in PDP-4 line printer overprinting.
|
||||||
|
- Fixed bug in PDP-15 memory protect/skip interaction.
|
||||||
|
- Fixed bug in RF set size routine.
|
||||||
|
- Increased PTP TIME for PDP-15 operating systems.
|
||||||
|
|
||||||
|
2.5 PDP-8
|
||||||
|
|
||||||
|
- Fixed bug in DF, RF set size routine.
|
||||||
|
|
||||||
|
2.6 Nova
|
||||||
|
|
||||||
|
- Fixed bug in DSK set size routine.
|
||||||
|
|
||||||
|
2.7 1401
|
||||||
|
|
||||||
|
- Revised fetch to model hardware more closely.
|
||||||
|
|
||||||
|
2.8 Ibm1130
|
||||||
|
|
||||||
|
- Fixed bugs found by APL 1130.
|
||||||
|
|
||||||
|
2.9 Altairz80
|
||||||
|
|
||||||
|
- Fixed bug in real-time clock on Windows host.
|
||||||
|
|
||||||
|
2.10 HP2100
|
||||||
|
|
||||||
|
-- Fixed DR drum sizes.
|
||||||
|
-- Fixed DR variable capacity interaction with SAVE/RESTORE.
|
||||||
|
|
||||||
|
|
||||||
|
3. New Features in 3.0 vs prior releases
|
||||||
|
|
||||||
|
3.1 SCP and Libraries
|
||||||
|
|
||||||
- Added ASSIGN/DEASSIGN (logical name) commands.
|
- Added ASSIGN/DEASSIGN (logical name) commands.
|
||||||
- Changed RESTORE to unconditionally detach files.
|
- Changed RESTORE to unconditionally detach files.
|
||||||
|
@ -13,7 +77,7 @@ clean directory.
|
||||||
- Fixed bug in SHOW CONNECTIONS.
|
- Fixed bug in SHOW CONNECTIONS.
|
||||||
- Added USE_ADDR64 support
|
- Added USE_ADDR64 support
|
||||||
|
|
||||||
1.2 All magtapes
|
3.2 All magtapes
|
||||||
|
|
||||||
- Magtapes support SIMH format, E11 format, and TPC format (read only).
|
- Magtapes support SIMH format, E11 format, and TPC format (read only).
|
||||||
- SET <tape_unit> FORMAT=format sets the specified tape unit's format.
|
- SET <tape_unit> FORMAT=format sets the specified tape unit's format.
|
||||||
|
@ -21,16 +85,16 @@ clean directory.
|
||||||
- Tape format can also be set as part of the ATTACH command, using
|
- Tape format can also be set as part of the ATTACH command, using
|
||||||
the -F switch.
|
the -F switch.
|
||||||
|
|
||||||
1.3 VAX
|
3.3 VAX
|
||||||
|
|
||||||
- VAX can be compiled without USE_INT64.
|
- VAX can be compiled without USE_INT64.
|
||||||
- If compiled with USE_INT64 and USE_ADDR64, RQ and TQ controllers support
|
- If compiled with USE_INT64 and USE_ADDR64, RQ and TQ controllers support
|
||||||
files > 2GB.
|
files > 2GB.
|
||||||
- VAX ROM has speed control (SET ROM DELAY/NODELAY).
|
- VAX ROM has speed control (SET ROM DELAY/NODELAY).
|
||||||
|
|
||||||
2. Bugs Fixed in 3.01-0
|
4. Bugs Fixed in 3.0 vs prior releases
|
||||||
|
|
||||||
2.1 VAX
|
4.1 VAX
|
||||||
|
|
||||||
- Fixed CVTfi bug: integer overflow not set if exponent out of range
|
- Fixed CVTfi bug: integer overflow not set if exponent out of range
|
||||||
- Fixed EMODx bugs:
|
- Fixed EMODx bugs:
|
||||||
|
@ -41,7 +105,7 @@ clean directory.
|
||||||
- Fixed interval timer and ROM access to pass power-up self-test even on very
|
- Fixed interval timer and ROM access to pass power-up self-test even on very
|
||||||
fast host processors (fixes from Mark Pizzolato).
|
fast host processors (fixes from Mark Pizzolato).
|
||||||
|
|
||||||
2.2 1401
|
4.2 1401
|
||||||
|
|
||||||
- Fixed mnemonic, instruction lengths, and reverse scan length check bug for MCS.
|
- Fixed mnemonic, instruction lengths, and reverse scan length check bug for MCS.
|
||||||
- Fixed MCE bug, BS off by 1 if zero suppress.
|
- Fixed MCE bug, BS off by 1 if zero suppress.
|
||||||
|
@ -50,15 +114,15 @@ clean directory.
|
||||||
- Added check for invalid 8 character MCW, LCA.
|
- Added check for invalid 8 character MCW, LCA.
|
||||||
- Fixed magtape load-mode end of record response.
|
- Fixed magtape load-mode end of record response.
|
||||||
|
|
||||||
2.3 Nova
|
4.3 Nova
|
||||||
|
|
||||||
- Fixed DSK variable size interaction with restore.
|
- Fixed DSK variable size interaction with restore.
|
||||||
|
|
||||||
2.4 PDP-1
|
4.4 PDP-1
|
||||||
|
|
||||||
- Fixed DT variable size interaction with restore.
|
- Fixed DT variable size interaction with restore.
|
||||||
|
|
||||||
2.5 PDP-11
|
4.5 PDP-11
|
||||||
|
|
||||||
- Fixed DT variable size interaction with restore.
|
- Fixed DT variable size interaction with restore.
|
||||||
- Fixed bug in MMR1 update (found by Tim Stark).
|
- Fixed bug in MMR1 update (found by Tim Stark).
|
||||||
|
@ -71,40 +135,21 @@ clean directory.
|
||||||
o Added ability to split received packet into multiple buffers.
|
o Added ability to split received packet into multiple buffers.
|
||||||
o Added explicit runt and giant packet processing.
|
o Added explicit runt and giant packet processing.
|
||||||
|
|
||||||
2.6 PDP-18B
|
4.6 PDP-18B
|
||||||
|
|
||||||
- Fixed DT, RF variable size interaction with restore.
|
- Fixed DT, RF variable size interaction with restore.
|
||||||
- Fixed MT bug in MTTR.
|
- Fixed MT bug in MTTR.
|
||||||
|
|
||||||
2.7 PDP-8
|
4.7 PDP-8
|
||||||
|
|
||||||
- Fixed DT, DF, RF, RX variable size interaction with restore.
|
- Fixed DT, DF, RF, RX variable size interaction with restore.
|
||||||
- Fixed MT bug in SKTR.
|
- Fixed MT bug in SKTR.
|
||||||
|
|
||||||
2.8 HP2100
|
4.8 HP2100
|
||||||
|
|
||||||
- Fixed bug in DP (13210A controller only), DQ read status.
|
- Fixed bug in DP (13210A controller only), DQ read status.
|
||||||
- Fixed bug in DP, DQ seek complete.
|
- Fixed bug in DP, DQ seek complete.
|
||||||
|
|
||||||
2.9 GRI
|
4.9 GRI
|
||||||
|
|
||||||
- Fixed bug in SC queue pointer management.
|
- Fixed bug in SC queue pointer management.
|
||||||
|
|
||||||
3. New Features in 3.0 vs prior releases
|
|
||||||
|
|
||||||
N/A
|
|
||||||
|
|
||||||
4. Bugs Fixed in 3.0 vs prior releases
|
|
||||||
|
|
||||||
N/A
|
|
||||||
|
|
||||||
5. General Notes
|
|
||||||
|
|
||||||
WARNING: The RESTORE command has changed. RESTORE will now
|
|
||||||
detach an attached file on a unit, if that unit did not have
|
|
||||||
an attached file in the saved configuration. This is required
|
|
||||||
to assure that the unit flags and the file state are consistent.
|
|
||||||
|
|
||||||
WARNING: The compilation scheme for the PDP-10, PDP-11, and VAX
|
|
||||||
has changed. Use one of the supplied build files, or read the
|
|
||||||
documentation carefully, before compiling any of these simulators.
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* altairz80_defs.h: MITS Altair simulator definitions
|
/* altairz80_defs.h: MITS Altair simulator definitions
|
||||||
|
|
||||||
Copyright (c) 2002, Peter Schorn
|
Copyright (c) 2002-2003, Peter Schorn
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -126,13 +126,13 @@ extern UNIT cpu_unit;
|
||||||
|
|
||||||
/* SIMH pseudo device status registers */
|
/* SIMH pseudo device status registers */
|
||||||
/* ZSDOS clock definitions */
|
/* ZSDOS clock definitions */
|
||||||
static int32 ClockZSDOSDelta = 0; /* delta between real clock and Altair clock */
|
static time_t ClockZSDOSDelta = 0; /* delta between real clock and Altair clock */
|
||||||
static int32 setClockZSDOSPos = 0; /* determines state for receiving address of parameter block */
|
static int32 setClockZSDOSPos = 0; /* determines state for receiving address of parameter block */
|
||||||
static int32 setClockZSDOSAdr = 0; /* address in M of 6 byte parameter block for setting time */
|
static int32 setClockZSDOSAdr = 0; /* address in M of 6 byte parameter block for setting time */
|
||||||
static int32 getClockZSDOSPos = 0; /* determines state for sending clock information */
|
static int32 getClockZSDOSPos = 0; /* determines state for sending clock information */
|
||||||
|
|
||||||
/* CPM3 clock definitions */
|
/* CPM3 clock definitions */
|
||||||
static int32 ClockCPM3Delta = 0; /* delta between real clock and Altair clock */
|
static time_t ClockCPM3Delta = 0; /* delta between real clock and Altair clock */
|
||||||
static int32 setClockCPM3Pos = 0; /* determines state for receiving address of parameter block */
|
static int32 setClockCPM3Pos = 0; /* determines state for receiving address of parameter block */
|
||||||
static int32 setClockCPM3Adr = 0; /* address in M of 5 byte parameter block for setting time */
|
static int32 setClockCPM3Adr = 0; /* address in M of 5 byte parameter block for setting time */
|
||||||
static int32 getClockCPM3Pos = 0; /* determines state for sending clock information */
|
static int32 getClockCPM3Pos = 0; /* determines state for sending clock information */
|
||||||
|
@ -658,11 +658,12 @@ enum simhPseudoDeviceCommands { /* do not change order or remove commands, add o
|
||||||
#define cpmCommandLineLength 128
|
#define cpmCommandLineLength 128
|
||||||
#define splimit 10 /* stack depth of timer stack */
|
#define splimit 10 /* stack depth of timer stack */
|
||||||
static uint32 markTime[splimit]; /* timer stack */
|
static uint32 markTime[splimit]; /* timer stack */
|
||||||
static struct tm *currentTime = NULL;
|
static struct tm currentTime;
|
||||||
|
static int32 currentTimeValid = FALSE;
|
||||||
static char version[] = "SIMH002";
|
static char version[] = "SIMH002";
|
||||||
|
|
||||||
static t_stat simh_dev_reset(DEVICE *dptr) {
|
static t_stat simh_dev_reset(DEVICE *dptr) {
|
||||||
currentTime = NULL;
|
currentTimeValid = FALSE;
|
||||||
ClockZSDOSDelta = 0;
|
ClockZSDOSDelta = 0;
|
||||||
setClockZSDOSPos = 0;
|
setClockZSDOSPos = 0;
|
||||||
getClockZSDOSPos = 0;
|
getClockZSDOSPos = 0;
|
||||||
|
@ -783,7 +784,7 @@ static void setClockCPM3(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32 simh_in(const int32 port) {
|
static int32 simh_in(const int32 port) {
|
||||||
int32 result;
|
int32 result = 0;
|
||||||
switch(lastCommand) {
|
switch(lastCommand) {
|
||||||
case attachPTRCmd:
|
case attachPTRCmd:
|
||||||
case attachPTPCmd:
|
case attachPTPCmd:
|
||||||
|
@ -791,31 +792,31 @@ static int32 simh_in(const int32 port) {
|
||||||
lastCommand = 0;
|
lastCommand = 0;
|
||||||
break;
|
break;
|
||||||
case getClockZSDOSCmd:
|
case getClockZSDOSCmd:
|
||||||
if (currentTime) {
|
if (currentTimeValid) {
|
||||||
switch(getClockZSDOSPos) {
|
switch(getClockZSDOSPos) {
|
||||||
case 0:
|
case 0:
|
||||||
result = toBCD(currentTime -> tm_year > 99 ?
|
result = toBCD(currentTime.tm_year > 99 ?
|
||||||
currentTime -> tm_year - 100 : currentTime -> tm_year);
|
currentTime.tm_year - 100 : currentTime.tm_year);
|
||||||
getClockZSDOSPos = 1;
|
getClockZSDOSPos = 1;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
result = toBCD(currentTime -> tm_mon + 1);
|
result = toBCD(currentTime.tm_mon + 1);
|
||||||
getClockZSDOSPos = 2;
|
getClockZSDOSPos = 2;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
result = toBCD(currentTime -> tm_mday);
|
result = toBCD(currentTime.tm_mday);
|
||||||
getClockZSDOSPos = 3;
|
getClockZSDOSPos = 3;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
result = toBCD(currentTime -> tm_hour);
|
result = toBCD(currentTime.tm_hour);
|
||||||
getClockZSDOSPos = 4;
|
getClockZSDOSPos = 4;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
result = toBCD(currentTime -> tm_min);
|
result = toBCD(currentTime.tm_min);
|
||||||
getClockZSDOSPos = 5;
|
getClockZSDOSPos = 5;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
result = toBCD(currentTime -> tm_sec);
|
result = toBCD(currentTime.tm_sec);
|
||||||
getClockZSDOSPos = lastCommand = 0;
|
getClockZSDOSPos = lastCommand = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -825,7 +826,7 @@ static int32 simh_in(const int32 port) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case getClockCPM3Cmd:
|
case getClockCPM3Cmd:
|
||||||
if (currentTime) {
|
if (currentTimeValid) {
|
||||||
switch(getClockCPM3Pos) {
|
switch(getClockCPM3Pos) {
|
||||||
case 0:
|
case 0:
|
||||||
result = daysCPM3SinceOrg & 0xff;
|
result = daysCPM3SinceOrg & 0xff;
|
||||||
|
@ -836,15 +837,15 @@ static int32 simh_in(const int32 port) {
|
||||||
getClockCPM3Pos = 2;
|
getClockCPM3Pos = 2;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
result = toBCD(currentTime -> tm_hour);
|
result = toBCD(currentTime.tm_hour);
|
||||||
getClockCPM3Pos = 3;
|
getClockCPM3Pos = 3;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
result = toBCD(currentTime -> tm_min);
|
result = toBCD(currentTime.tm_min);
|
||||||
getClockCPM3Pos = 4;
|
getClockCPM3Pos = 4;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
result = toBCD(currentTime -> tm_sec);
|
result = toBCD(currentTime.tm_sec);
|
||||||
getClockCPM3Pos = lastCommand = 0;
|
getClockCPM3Pos = lastCommand = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1012,7 +1013,8 @@ static int32 simh_out(const int32 port, const int32 data) {
|
||||||
case getClockZSDOSCmd:
|
case getClockZSDOSCmd:
|
||||||
time(&now);
|
time(&now);
|
||||||
now += ClockZSDOSDelta;
|
now += ClockZSDOSDelta;
|
||||||
currentTime = localtime(&now);
|
currentTime = *localtime(&now);
|
||||||
|
currentTimeValid = TRUE;
|
||||||
getClockZSDOSPos = 0;
|
getClockZSDOSPos = 0;
|
||||||
break;
|
break;
|
||||||
case setClockZSDOSCmd:
|
case setClockZSDOSCmd:
|
||||||
|
@ -1021,7 +1023,8 @@ static int32 simh_out(const int32 port, const int32 data) {
|
||||||
case getClockCPM3Cmd:
|
case getClockCPM3Cmd:
|
||||||
time(&now);
|
time(&now);
|
||||||
now += ClockCPM3Delta;
|
now += ClockCPM3Delta;
|
||||||
currentTime = localtime(&now);
|
currentTime = *localtime(&now);
|
||||||
|
currentTimeValid = TRUE;
|
||||||
daysCPM3SinceOrg = (now - mkCPM3Origin()) / secondsPerDay;
|
daysCPM3SinceOrg = (now - mkCPM3Origin()) / secondsPerDay;
|
||||||
getClockCPM3Pos = 0;
|
getClockCPM3Pos = 0;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
To: Users
|
To: Users
|
||||||
From: Bob Supnik
|
From: Bob Supnik
|
||||||
Subj: H316 Simulator Usage
|
Subj: H316 Simulator Usage
|
||||||
Date: 20-Apr-2003
|
Date: 15-Jul-2003
|
||||||
|
|
||||||
COPYRIGHT NOTICE
|
COPYRIGHT NOTICE
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ sim/h316/ h316_defs.h
|
||||||
h316_cpu.c
|
h316_cpu.c
|
||||||
h316_lp.c
|
h316_lp.c
|
||||||
h316_stddev.c
|
h316_stddev.c
|
||||||
h316_cpu.c
|
h316_sys.c
|
||||||
|
|
||||||
2. H316/H516 Features
|
2. H316/H516 Features
|
||||||
|
|
||||||
|
@ -230,7 +230,7 @@ The clock implements these registers:
|
||||||
The real-time clock autocalibrates; the clock interval is adjusted up or
|
The real-time clock autocalibrates; the clock interval is adjusted up or
|
||||||
down so that the clock tracks actual elapsed time.
|
down so that the clock tracks actual elapsed time.
|
||||||
|
|
||||||
2.2.5 316/5116 Line Printer (LPT)
|
2.2.5 316/516 Line Printer (LPT)
|
||||||
|
|
||||||
The line printer (LPT) writes data to a disk file. The POS register
|
The line printer (LPT) writes data to a disk file. The POS register
|
||||||
specifies the number of the next data item to be written. Thus,
|
specifies the number of the next data item to be written. Thus,
|
||||||
|
@ -294,9 +294,8 @@ where * signifies indirect, C a current sector reference, Z a sector zero
|
||||||
reference, and 1 indexed. The address is an octal number in the range 0 -
|
reference, and 1 indexed. The address is an octal number in the range 0 -
|
||||||
077777; if C or Z is specified, the address is a page offset in the range
|
077777; if C or Z is specified, the address is a page offset in the range
|
||||||
0 - 0777. Normally, C is not needed; the simulator figures out from the
|
0 - 0777. Normally, C is not needed; the simulator figures out from the
|
||||||
address what mode to use. However, when referencing memory outside the CPU
|
address what mode to use. However, when referencing memory outside the CPU,
|
||||||
(eg, disks), there is no valid PC, and C must be used to specify current
|
there is no valid PC, and C must be used to specify current sector addressing.
|
||||||
sector addressing.
|
|
||||||
|
|
||||||
I/O instructions have the format
|
I/O instructions have the format
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
To: Users
|
To: Users
|
||||||
From: Bob Supnik
|
From: Bob Supnik
|
||||||
Subj: HP2100 Simulator Usage
|
Subj: HP2100 Simulator Usage
|
||||||
Date: 15-Nov-2002
|
Date: 15-Jul-2003
|
||||||
|
|
||||||
COPYRIGHT NOTICE
|
COPYRIGHT NOTICE
|
||||||
|
|
||||||
The following copyright notice applies to both the SIMH source and binary:
|
The following copyright notice applies to both the SIMH source and binary:
|
||||||
|
|
||||||
Original code published in 1993-2002, written by Robert M Supnik
|
Original code published in 1993-2002, written by Robert M Supnik
|
||||||
Copyright (c) 1993-2002, Robert M Supnik
|
Copyright (c) 1993-2003, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -39,10 +39,12 @@ This memorandum documents the HP 2100 simulator.
|
||||||
sim/ sim_defs.h
|
sim/ sim_defs.h
|
||||||
sim_rev.h
|
sim_rev.h
|
||||||
sim_sock.h
|
sim_sock.h
|
||||||
|
sim_tape.h
|
||||||
sim_tmxr.h
|
sim_tmxr.h
|
||||||
scp.c
|
scp.c
|
||||||
scp_tty.c
|
scp_tty.c
|
||||||
sim_sock.c
|
sim_sock.c
|
||||||
|
sim_tape.c
|
||||||
sim_tmxr.c
|
sim_tmxr.c
|
||||||
|
|
||||||
sim/hp2100/ hp2100_defs.h
|
sim/hp2100/ hp2100_defs.h
|
||||||
|
@ -563,7 +565,6 @@ Both IPLI and IPLO implement these registers:
|
||||||
TIME 24 polling interval for input
|
TIME 24 polling interval for input
|
||||||
STOP_IOE 1 stop on I/O error
|
STOP_IOE 1 stop on I/O error
|
||||||
|
|
||||||
|
|
||||||
2.5 12557A Disk Controller (DPC, DPD) with 2781 Drives
|
2.5 12557A Disk Controller (DPC, DPD) with 2781 Drives
|
||||||
13210A Disk Controller (DPC, DPD) with 7900 Drives
|
13210A Disk Controller (DPC, DPD) with 7900 Drives
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,8 @@
|
||||||
|
|
||||||
The drum control channel does not have any of the traditional flip-flops.
|
The drum control channel does not have any of the traditional flip-flops.
|
||||||
|
|
||||||
|
27-Jul-03 RMS Fixed drum sizes
|
||||||
|
Fixed variable capacity interaction with SAVE/RESTORE
|
||||||
10-Nov-02 RMS Added BOOT command
|
10-Nov-02 RMS Added BOOT command
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -48,8 +50,21 @@
|
||||||
#define DR_DNUMSC 32 /* drum sec/track */
|
#define DR_DNUMSC 32 /* drum sec/track */
|
||||||
#define DR_NUMSC ((drc_unit.flags & UNIT_DR)? DR_DNUMSC: DR_FNUMSC)
|
#define DR_NUMSC ((drc_unit.flags & UNIT_DR)? DR_DNUMSC: DR_FNUMSC)
|
||||||
#define DR_SIZE (512 * DR_DNUMSC * DR_NUMWD) /* initial size */
|
#define DR_SIZE (512 * DR_DNUMSC * DR_NUMWD) /* initial size */
|
||||||
#define UNIT_V_DR (UNIT_V_UF) /* disk vs drum */
|
#define UNIT_V_SZ (UNIT_V_UF) /* disk vs drum */
|
||||||
#define UNIT_DR (1 << UNIT_V_DR)
|
#define UNIT_M_SZ 017 /* size */
|
||||||
|
#define UNIT_SZ (UNIT_M_SZ << UNIT_V_SZ)
|
||||||
|
#define UNIT_DR (1 << UNIT_V_SZ) /* low order bit */
|
||||||
|
#define SZ_180K 000 /* disks */
|
||||||
|
#define SZ_360K 002
|
||||||
|
#define SZ_720K 004
|
||||||
|
#define SZ_1024K 001 /* drums: default size */
|
||||||
|
#define SZ_1536K 003
|
||||||
|
#define SZ_384K 005
|
||||||
|
#define SZ_512K 007
|
||||||
|
#define SZ_640K 011
|
||||||
|
#define SZ_768K 013
|
||||||
|
#define SZ_896K 015
|
||||||
|
#define DR_GETSZ(x) (((x) >> UNIT_V_SZ) & UNIT_M_SZ)
|
||||||
|
|
||||||
/* Command word */
|
/* Command word */
|
||||||
|
|
||||||
|
@ -105,11 +120,16 @@ int32 drd_ptr = 0; /* sector pointer */
|
||||||
int32 dr_stopioe = 1; /* stop on error */
|
int32 dr_stopioe = 1; /* stop on error */
|
||||||
int32 dr_time = 10; /* time per word */
|
int32 dr_time = 10; /* time per word */
|
||||||
|
|
||||||
|
static int32 sz_tab[16] = {
|
||||||
|
184320, 1048576, 368640, 1572864, 737280, 393216, 0, 524288,
|
||||||
|
0, 655360, 0, 786432, 0, 917504, 0, 0 };
|
||||||
|
|
||||||
DEVICE drd_dev, drc_dev;
|
DEVICE drd_dev, drc_dev;
|
||||||
int32 drdio (int32 inst, int32 IR, int32 dat);
|
int32 drdio (int32 inst, int32 IR, int32 dat);
|
||||||
int32 drcio (int32 inst, int32 IR, int32 dat);
|
int32 drcio (int32 inst, int32 IR, int32 dat);
|
||||||
t_stat drc_svc (UNIT *uptr);
|
t_stat drc_svc (UNIT *uptr);
|
||||||
t_stat drc_reset (DEVICE *dptr);
|
t_stat drc_reset (DEVICE *dptr);
|
||||||
|
t_stat drc_attach (UNIT *uptr, char *cptr);
|
||||||
t_stat drc_boot (int32 unitno, DEVICE *dptr);
|
t_stat drc_boot (int32 unitno, DEVICE *dptr);
|
||||||
int32 dr_incda (int32 trk, int32 sec, int32 ptr);
|
int32 dr_incda (int32 trk, int32 sec, int32 ptr);
|
||||||
t_stat dr_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
|
t_stat dr_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||||
|
@ -175,21 +195,22 @@ REG drc_reg[] = {
|
||||||
{ DRDATA (TIME, dr_time, 24), REG_NZ + PV_LEFT },
|
{ DRDATA (TIME, dr_time, 24), REG_NZ + PV_LEFT },
|
||||||
{ FLDATA (STOP_IOE, dr_stopioe, 0) },
|
{ FLDATA (STOP_IOE, dr_stopioe, 0) },
|
||||||
{ ORDATA (DEVNO, drc_dib.devno, 6), REG_HRO },
|
{ ORDATA (DEVNO, drc_dib.devno, 6), REG_HRO },
|
||||||
|
{ DRDATA (CAPAC, drc_unit.capac, 24), REG_HRO },
|
||||||
{ NULL } };
|
{ NULL } };
|
||||||
|
|
||||||
MTAB drc_mod[] = {
|
MTAB drc_mod[] = {
|
||||||
{ UNIT_DR, 0, "disk", NULL, NULL },
|
{ UNIT_DR, 0, "disk", NULL, NULL },
|
||||||
{ UNIT_DR, UNIT_DR, "drum", NULL, NULL },
|
{ UNIT_DR, UNIT_DR, "drum", NULL, NULL },
|
||||||
{ UNIT_DR, 184320, NULL, "180K", &dr_set_size },
|
{ UNIT_SZ, (SZ_180K << UNIT_V_SZ), NULL, "180K", &dr_set_size },
|
||||||
{ UNIT_DR, 368640, NULL, "360K", &dr_set_size },
|
{ UNIT_SZ, (SZ_360K << UNIT_V_SZ), NULL, "360K", &dr_set_size },
|
||||||
{ UNIT_DR, 737280, NULL, "720K", &dr_set_size },
|
{ UNIT_SZ, (SZ_720K << UNIT_V_SZ), NULL, "720K", &dr_set_size },
|
||||||
{ UNIT_DR, 368640+1, NULL, "384K", &dr_set_size },
|
{ UNIT_SZ, (SZ_384K << UNIT_V_SZ), NULL, "384K", &dr_set_size },
|
||||||
{ UNIT_DR, 524280+1, NULL, "512K", &dr_set_size },
|
{ UNIT_SZ, (SZ_512K << UNIT_V_SZ), NULL, "512K", &dr_set_size },
|
||||||
{ UNIT_DR, 655360+1, NULL, "640K", &dr_set_size },
|
{ UNIT_SZ, (SZ_640K << UNIT_V_SZ), NULL, "640K", &dr_set_size },
|
||||||
{ UNIT_DR, 786432+1, NULL, "768K", &dr_set_size },
|
{ UNIT_SZ, (SZ_768K << UNIT_V_SZ), NULL, "768K", &dr_set_size },
|
||||||
{ UNIT_DR, 917504+1, NULL, "896K", &dr_set_size },
|
{ UNIT_SZ, (SZ_896K << UNIT_V_SZ), NULL, "896K", &dr_set_size },
|
||||||
{ UNIT_DR, 1048576+1, NULL, "1024K", &dr_set_size },
|
{ UNIT_SZ, (SZ_1024K << UNIT_V_SZ), NULL, "1024K", &dr_set_size },
|
||||||
{ UNIT_DR, 1572864+1, NULL, "1536K", &dr_set_size },
|
{ UNIT_SZ, (SZ_1536K << UNIT_V_SZ), NULL, "1536K", &dr_set_size },
|
||||||
{ MTAB_XTD | MTAB_VDV, 1, "DEVNO", "DEVNO",
|
{ MTAB_XTD | MTAB_VDV, 1, "DEVNO", "DEVNO",
|
||||||
&hp_setdev, &hp_showdev, &drd_dev },
|
&hp_setdev, &hp_showdev, &drd_dev },
|
||||||
{ 0 } };
|
{ 0 } };
|
||||||
|
@ -198,7 +219,7 @@ DEVICE drc_dev = {
|
||||||
"DRC", &drc_unit, drc_reg, drc_mod,
|
"DRC", &drc_unit, drc_reg, drc_mod,
|
||||||
1, 8, 21, 1, 8, 16,
|
1, 8, 21, 1, 8, 16,
|
||||||
NULL, NULL, &drc_reset,
|
NULL, NULL, &drc_reset,
|
||||||
&drc_boot, NULL, NULL,
|
&drc_boot, &drc_attach, NULL,
|
||||||
&drc_dib, DEV_DISABLE };
|
&drc_dib, DEV_DISABLE };
|
||||||
|
|
||||||
/* IOT routines */
|
/* IOT routines */
|
||||||
|
@ -336,14 +357,26 @@ sim_cancel (&drc_unit);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Attach routine */
|
||||||
|
|
||||||
|
t_stat drc_attach (UNIT *uptr, char *cptr)
|
||||||
|
{
|
||||||
|
int32 sz = sz_tab[DR_GETSZ (uptr->flags)];
|
||||||
|
|
||||||
|
if (sz == 0) return SCPE_IERR;
|
||||||
|
uptr->capac = sz;
|
||||||
|
return attach_unit (uptr, cptr);
|
||||||
|
}
|
||||||
/* Set size routine */
|
/* Set size routine */
|
||||||
|
|
||||||
t_stat dr_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
|
t_stat dr_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||||
{
|
{
|
||||||
|
int32 sz;
|
||||||
|
|
||||||
|
if (val < 0) return SCPE_IERR;
|
||||||
|
if ((sz = sz_tab[DR_GETSZ (val)]) == 0) return SCPE_IERR;
|
||||||
if (uptr->flags & UNIT_ATT) return SCPE_ALATT;
|
if (uptr->flags & UNIT_ATT) return SCPE_ALATT;
|
||||||
if (val & 1) uptr->flags = uptr->flags | UNIT_DR;
|
uptr->capac = sz;
|
||||||
else uptr->flags = uptr->flags & ~UNIT_DR;
|
|
||||||
uptr->capac = val & ~1;
|
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* hp2100_fp.c: HP 2100 floating point instructions
|
/* hp2100_fp.c: HP 2100 floating point instructions
|
||||||
|
|
||||||
Copyright (c) 2003, Robert M. Supnik
|
Copyright (c) 2002-2003, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -23,6 +23,7 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
in this Software without prior written authorization from Robert M Supnik.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
15-Jul-03 RMS Fixed signed/unsigned warning
|
||||||
21-Oct-02 RMS Recoded for compatibility with 21MX microcode algorithms
|
21-Oct-02 RMS Recoded for compatibility with 21MX microcode algorithms
|
||||||
|
|
||||||
The HP2100 uses a unique binary floating point format:
|
The HP2100 uses a unique binary floating point format:
|
||||||
|
@ -153,7 +154,7 @@ UnpackFP (&fop1, FPAB); /* unpack A-B */
|
||||||
UnpackFP (&fop2, opnd); /* get op */
|
UnpackFP (&fop2, opnd); /* get op */
|
||||||
if (sub) { /* subtract? */
|
if (sub) { /* subtract? */
|
||||||
fop2.fr = FR_NEG (fop2.fr); /* negate frac */
|
fop2.fr = FR_NEG (fop2.fr); /* negate frac */
|
||||||
if (fop2.fr == FP_SIGN) { /* -1/2? */
|
if (fop2.fr == ((uint32) FP_SIGN)) { /* -1/2? */
|
||||||
fop2.fr = fop2.fr >> 1; /* special case */
|
fop2.fr = fop2.fr >> 1; /* special case */
|
||||||
fop2.exp = fop2.exp + 1; } }
|
fop2.exp = fop2.exp + 1; } }
|
||||||
if (fop1.fr == 0) fop1 = fop2; /* op1 = 0? res = op2 */
|
if (fop1.fr == 0) fop1 = fop2; /* op1 = 0? res = op2 */
|
||||||
|
|
|
@ -23,6 +23,9 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
in this Software without prior written authorization from Robert M Supnik.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
12-Jul-03 RMS Moved ASCII/BCD tables to included file
|
||||||
|
Revised fetch to model hardware
|
||||||
|
Removed length checking in fetch phase
|
||||||
16-Mar-03 RMS Fixed mnemonic, instruction lengths, and reverse
|
16-Mar-03 RMS Fixed mnemonic, instruction lengths, and reverse
|
||||||
scan length check bug for MCS
|
scan length check bug for MCS
|
||||||
Fixed MCE bug, BS off by 1 if zero suppress
|
Fixed MCE bug, BS off by 1 if zero suppress
|
||||||
|
@ -114,6 +117,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "i1401_defs.h"
|
#include "i1401_defs.h"
|
||||||
|
#include "i1401_dat.h"
|
||||||
|
|
||||||
#define PCQ_SIZE 64 /* must be 2**n */
|
#define PCQ_SIZE 64 /* must be 2**n */
|
||||||
#define PCQ_MASK (PCQ_SIZE - 1)
|
#define PCQ_MASK (PCQ_SIZE - 1)
|
||||||
|
@ -268,7 +272,7 @@ const int32 op_table[64] = {
|
||||||
L1, /* punch feed */
|
L1, /* punch feed */
|
||||||
0, /* illegal */
|
0, /* illegal */
|
||||||
L1 | L4 | L7 | AREQ | BREQ | MA, /* modify address */
|
L1 | L4 | L7 | AREQ | BREQ | MA, /* modify address */
|
||||||
L7 | AREQ | BREQ | MDV, /* multiply */
|
L1 | L4 | L7 | AREQ | BREQ | MDV, /* multiply */
|
||||||
0, /* illegal */
|
0, /* illegal */
|
||||||
0, /* illegal */
|
0, /* illegal */
|
||||||
0, /* illegal */
|
0, /* illegal */
|
||||||
|
@ -284,7 +288,7 @@ const int32 op_table[64] = {
|
||||||
L1 | L4 | L7 | AREQ | BREQ, /* move supress zero */
|
L1 | L4 | L7 | AREQ | BREQ, /* move supress zero */
|
||||||
0, /* illegal */
|
0, /* illegal */
|
||||||
L1 | L4 | L7 | AREQ | BREQ | NOWM, /* set word mark */
|
L1 | L4 | L7 | AREQ | BREQ | NOWM, /* set word mark */
|
||||||
L7 | AREQ | BREQ | MDV, /* divide */
|
L1 | L4 | L7 | AREQ | BREQ | MDV, /* divide */
|
||||||
0, /* illegal */
|
0, /* illegal */
|
||||||
0, /* illegal */
|
0, /* illegal */
|
||||||
0, /* illegal */
|
0, /* illegal */
|
||||||
|
@ -293,7 +297,7 @@ const int32 op_table[64] = {
|
||||||
L2 | L5, /* select stacker */
|
L2 | L5, /* select stacker */
|
||||||
L1 | L4 | L7 | L8 | BREQ | MLS | IO, /* load */
|
L1 | L4 | L7 | L8 | BREQ | MLS | IO, /* load */
|
||||||
L1 | L4 | L7 | L8 | BREQ | MLS | IO, /* move */
|
L1 | L4 | L7 | L8 | BREQ | MLS | IO, /* move */
|
||||||
HNOP | L1 | L4 | L7, /* nop */
|
HNOP | L1 | L2 | L4 | L5 | L7 | L8, /* nop */
|
||||||
0, /* illegal */
|
0, /* illegal */
|
||||||
L1 | L4 | L7 | AREQ | BREQ | MR, /* move to record */
|
L1 | L4 | L7 | AREQ | BREQ | MR, /* move to record */
|
||||||
L1 | L4 | AREQ | MLS, /* 50: store A addr */
|
L1 | L4 | AREQ | MLS, /* 50: store A addr */
|
||||||
|
@ -315,7 +319,7 @@ const int32 op_table[64] = {
|
||||||
L1 | L4 | L7 | AREQ | MLS, /* 70: store B addr */
|
L1 | L4 | L7 | AREQ | MLS, /* 70: store B addr */
|
||||||
0, /* illegal */
|
0, /* illegal */
|
||||||
L1 | L4 | L7 | AREQ | BREQ, /* zero and add */
|
L1 | L4 | L7 | AREQ | BREQ, /* zero and add */
|
||||||
HNOP | L1 | L4 | L7, /* halt */
|
HNOP | L1 | L2 | L4 | L5 | L7 | L8, /* halt */
|
||||||
L1 | L4 | L7 | AREQ | BREQ, /* clear word mark */
|
L1 | L4 | L7 | AREQ | BREQ, /* clear word mark */
|
||||||
0, /* illegal */
|
0, /* illegal */
|
||||||
0, /* illegal */
|
0, /* illegal */
|
||||||
|
@ -362,38 +366,6 @@ const int32 bin_to_bcd[16] = {
|
||||||
const int32 bcd_to_bin[16] = {
|
const int32 bcd_to_bin[16] = {
|
||||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 3, 4, 5, 6, 7 };
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 3, 4, 5, 6, 7 };
|
||||||
|
|
||||||
/* ASCII to BCD conversion */
|
|
||||||
|
|
||||||
const char ascii_to_bcd[128] = {
|
|
||||||
000, 000, 000, 000, 000, 000, 000, 000, /* 000 - 037 */
|
|
||||||
000, 000, 000, 000, 000, 000, 000, 000,
|
|
||||||
000, 000, 000, 000, 000, 000, 000, 000,
|
|
||||||
000, 000, 000, 000, 000, 000, 000, 000,
|
|
||||||
000, 052, 077, 013, 053, 034, 060, 032, /* 040 - 077 */
|
|
||||||
017, 074, 054, 037, 033, 040, 073, 021,
|
|
||||||
012, 001, 002, 003, 004, 005, 006, 007,
|
|
||||||
010, 011, 015, 056, 076, 035, 016, 072,
|
|
||||||
014, 061, 062, 063, 064, 065, 066, 067, /* 100 - 137 */
|
|
||||||
070, 071, 041, 042, 043, 044, 045, 046,
|
|
||||||
047, 050, 051, 022, 023, 024, 025, 026,
|
|
||||||
027, 030, 031, 075, 036, 055, 020, 057,
|
|
||||||
000, 061, 062, 063, 064, 065, 066, 067, /* 140 - 177 */
|
|
||||||
070, 071, 041, 042, 043, 044, 045, 046,
|
|
||||||
047, 050, 051, 022, 023, 024, 025, 026,
|
|
||||||
027, 030, 031, 000, 000, 000, 000, 000 };
|
|
||||||
|
|
||||||
/* BCD to ASCII conversion - also the "full" print chain */
|
|
||||||
|
|
||||||
char bcd_to_ascii[64] = {
|
|
||||||
' ', '1', '2', '3', '4', '5', '6', '7',
|
|
||||||
'8', '9', '0', '#', '@', ':', '>', '(',
|
|
||||||
'^', '/', 'S', 'T', 'U', 'V', 'W', 'X',
|
|
||||||
'Y', 'Z', '\'', ',', '%', '=', '\\', '+',
|
|
||||||
'-', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
|
||||||
'Q', 'R', '!', '$', '*', ']', ';', '_',
|
|
||||||
'&', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
|
|
||||||
'H', 'I', '?', '.', ')', '[', '<', '"' };
|
|
||||||
|
|
||||||
/* Indicator resets - a 1 marks an indicator that resets when tested */
|
/* Indicator resets - a 1 marks an indicator that resets when tested */
|
||||||
|
|
||||||
static const int32 ind_table[64] = {
|
static const int32 ind_table[64] = {
|
||||||
|
@ -501,9 +473,30 @@ if (sim_brk_summ && sim_brk_test (IS, SWMASK ('E'))) { /* breakpoint? */
|
||||||
|
|
||||||
sim_interval = sim_interval - 1;
|
sim_interval = sim_interval - 1;
|
||||||
|
|
||||||
/* Instruction fetch */
|
/* Instruction fetch - 1401 fetch works as follows:
|
||||||
|
|
||||||
if ((M[IS] & WM) == 0) { /* WM under op? */
|
- Each character fetched enters the B register. This register is not
|
||||||
|
visible; the variable t represents the B register.
|
||||||
|
- Except for the first and last cycles, each character fetched enters
|
||||||
|
the A register. This register is not visible; the variable D represents
|
||||||
|
the A register, because this is the instruction modifier for 2, 5, and 8
|
||||||
|
character instructions.
|
||||||
|
- At the start of the second cycle (first address character), the A-address
|
||||||
|
register and, for most instructions, the B-address register, are cleared
|
||||||
|
to blanks. The simulator represents addresses in binary and creates the
|
||||||
|
effect of blanks (address is bad) if less than three A-address characters
|
||||||
|
are found. Further, the simulator accumulates only the A-address, and
|
||||||
|
replicates it to the B-address at the appropriate point.
|
||||||
|
- At the start of the fifth cycle (fourth address character), the B-address
|
||||||
|
register is cleared to blanks. Again, the simulator creates the effect of
|
||||||
|
blanks (address is bad) if less than three B-address characters are found.
|
||||||
|
|
||||||
|
The 1401 does explicitly check for valid instruction lengths. Most 2,3,5,6
|
||||||
|
character instructions will be invalid because the A-address or B-address
|
||||||
|
(or both) are invalid.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((M[IS] & WM) == 0) { /* I-Op: WM under op? */
|
||||||
reason = STOP_NOWM; /* no, error */
|
reason = STOP_NOWM; /* no, error */
|
||||||
break; }
|
break; }
|
||||||
op = M[IS] & CHAR; /* get opcode */
|
op = M[IS] & CHAR; /* get opcode */
|
||||||
|
@ -514,25 +507,26 @@ if ((flags == 0) || (flags & ALLOPT & ~cpu_unit.flags)) {
|
||||||
if (op == OP_SAR) BS = AS; /* SAR? save ASTAR */
|
if (op == OP_SAR) BS = AS; /* SAR? save ASTAR */
|
||||||
PP (IS);
|
PP (IS);
|
||||||
|
|
||||||
if ((t = M[IS]) & WM) goto CHECK_LENGTH; /* WM? 1 char inst */
|
if ((t = M[IS]) & WM) goto CHECK_LENGTH; /* I-1: WM? 1 char inst */
|
||||||
D = ioind = t; /* could be D char, % */
|
D = ioind = t; /* could be D char, % */
|
||||||
AS = hun_table[t]; /* could be A addr */
|
AS = hun_table[t]; /* could be A addr */
|
||||||
PP (IS); /* if %xy, BA is set */
|
PP (IS); /* if %xy, BA is set */
|
||||||
|
|
||||||
if ((t = M[IS]) & WM) { /* WM? 2 char inst */
|
if ((t = M[IS]) & WM) { /* I-2: WM? 2 char inst */
|
||||||
AS = AS | BA; /* ASTAR bad */
|
AS = AS | BA; /* ASTAR bad */
|
||||||
if (!(flags & MLS)) BS = AS;
|
if (!(flags & MLS)) BS = AS;
|
||||||
goto CHECK_LENGTH; }
|
goto CHECK_LENGTH; }
|
||||||
|
D = dev = t; /* could be D char, dev */
|
||||||
AS = AS + ten_table[t]; /* build A addr */
|
AS = AS + ten_table[t]; /* build A addr */
|
||||||
dev = t; /* save char as dev */
|
|
||||||
PP (IS);
|
PP (IS);
|
||||||
|
|
||||||
if ((t = M[IS]) & WM) { /* WM? 3 char inst */
|
if ((t = M[IS]) & WM) { /* I-3: WM? 3 char inst */
|
||||||
AS = AS | BA; /* ASTAR bad */
|
AS = AS | BA; /* ASTAR bad */
|
||||||
if (!(flags & MLS)) BS = AS;
|
if (!(flags & MLS)) BS = AS;
|
||||||
goto CHECK_LENGTH; }
|
goto CHECK_LENGTH; }
|
||||||
|
D = unit = t; /* could be D char, unit */
|
||||||
|
if (unit == BCD_ZERO) unit = 0; /* convert unit to binary */
|
||||||
AS = AS + one_table[t]; /* finish A addr */
|
AS = AS + one_table[t]; /* finish A addr */
|
||||||
unit = (t == BCD_ZERO)? 0: t; /* save char as unit */
|
|
||||||
xa = (AS >> V_INDEX) & M_INDEX; /* get index reg */
|
xa = (AS >> V_INDEX) & M_INDEX; /* get index reg */
|
||||||
if (xa && (ioind != BCD_PERCNT) && (cpu_unit.flags & XSA)) { /* indexed? */
|
if (xa && (ioind != BCD_PERCNT) && (cpu_unit.flags & XSA)) { /* indexed? */
|
||||||
AS = AS + hun_table[M[xa] & CHAR] + ten_table[M[xa + 1] & CHAR] +
|
AS = AS + hun_table[M[xa] & CHAR] + ten_table[M[xa + 1] & CHAR] +
|
||||||
|
@ -541,21 +535,23 @@ if (xa && (ioind != BCD_PERCNT) && (cpu_unit.flags & XSA)) { /* indexed? */
|
||||||
if (!(flags & MLS)) BS = AS; /* not MLS? B = A */
|
if (!(flags & MLS)) BS = AS; /* not MLS? B = A */
|
||||||
PP (IS);
|
PP (IS);
|
||||||
|
|
||||||
if ((t = M[IS]) & WM) goto CHECK_LENGTH; /* WM? 4 char inst */
|
if ((t = M[IS]) & WM) goto CHECK_LENGTH; /* I-4: WM? 4 char inst */
|
||||||
if ((op == OP_B) && (t == BCD_BLANK)) goto CHECK_LENGTH; /* BR + space? */
|
if ((op == OP_B) && (t == BCD_BLANK)) goto CHECK_LENGTH; /* BR + space? */
|
||||||
D = t; /* could be D char */
|
D = t; /* could be D char */
|
||||||
BS = hun_table[t]; /* could be B addr */
|
BS = hun_table[t]; /* could be B addr */
|
||||||
PP (IS);
|
PP (IS);
|
||||||
|
|
||||||
if ((t = M[IS]) & WM) { /* WM? 5 char inst */
|
if ((t = M[IS]) & WM) { /* I-5: WM? 5 char inst */
|
||||||
BS = BS | BA; /* BSTAR bad */
|
BS = BS | BA; /* BSTAR bad */
|
||||||
goto CHECK_LENGTH; }
|
goto CHECK_LENGTH; }
|
||||||
|
D = t; /* could be D char */
|
||||||
BS = BS + ten_table[t]; /* build B addr */
|
BS = BS + ten_table[t]; /* build B addr */
|
||||||
PP (IS);
|
PP (IS);
|
||||||
|
|
||||||
if ((t = M[IS]) & WM) { /* WM? 6 char inst */
|
if ((t = M[IS]) & WM) { /* I-6: WM? 6 char inst */
|
||||||
BS = BS | BA; /* BSTAR bad */
|
BS = BS | BA; /* BSTAR bad */
|
||||||
goto CHECK_LENGTH; }
|
goto CHECK_LENGTH; }
|
||||||
|
D = t; /* could be D char */
|
||||||
BS = BS + one_table[t]; /* finish B addr */
|
BS = BS + one_table[t]; /* finish B addr */
|
||||||
xa = (BS >> V_INDEX) & M_INDEX; /* get index reg */
|
xa = (BS >> V_INDEX) & M_INDEX; /* get index reg */
|
||||||
if (xa && (cpu_unit.flags & XSA)) { /* indexed? */
|
if (xa && (cpu_unit.flags & XSA)) { /* indexed? */
|
||||||
|
@ -564,39 +560,43 @@ if (xa && (cpu_unit.flags & XSA)) { /* indexed? */
|
||||||
BS = (BS & INDEXMASK) % MAXMEMSIZE; }
|
BS = (BS & INDEXMASK) % MAXMEMSIZE; }
|
||||||
PP (IS);
|
PP (IS);
|
||||||
|
|
||||||
if ((M[IS] & WM) || (flags & NOWM)) goto CHECK_LENGTH; /* WM? 7 chr */
|
if (flags & NOWM) goto CHECK_LENGTH; /* I-7: SWM? done */
|
||||||
D = M[IS]; /* last char is D */
|
if ((t = M[IS]) & WM) goto CHECK_LENGTH; /* WM? 7 char inst */
|
||||||
do { PP (IS); } while ((M[IS] & WM) == 0); /* find word mark */
|
D = t; /* last char is D */
|
||||||
|
for (;;) { /* I-8: repeats until WM */
|
||||||
|
if ((t = M[IS]) & WM) break; /* WM? done */
|
||||||
|
D = t; /* last char is D */
|
||||||
|
PP (IS); }
|
||||||
|
|
||||||
CHECK_LENGTH:
|
CHECK_LENGTH:
|
||||||
ilnt = IS - saved_IS; /* get lnt */
|
ilnt = IS - saved_IS; /* get lnt */
|
||||||
if (((flags & len_table [(ilnt <= 8)? ilnt: 8]) == 0) && /* valid lnt? */
|
//if (((flags & len_table [(ilnt <= 8)? ilnt: 8]) == 0) && /* valid lnt? */
|
||||||
((flags & HNOP) == 0)) reason = STOP_INVL;
|
// ((flags & HNOP) == 0)) reason = STOP_INVL;
|
||||||
if ((flags & BREQ) && ADDR_ERR (BS)) reason = STOP_INVB; /* valid A? */
|
if ((flags & BREQ) && ADDR_ERR (BS)) reason = STOP_INVB; /* valid A? */
|
||||||
if ((flags & AREQ) && ADDR_ERR (AS)) reason = STOP_INVA; /* valid B? */
|
if ((flags & AREQ) && ADDR_ERR (AS)) reason = STOP_INVA; /* valid B? */
|
||||||
if (reason) break; /* error in fetch? */
|
if (reason) break; /* error in fetch? */
|
||||||
switch (op) { /* case on opcode */
|
switch (op) { /* case on opcode */
|
||||||
|
|
||||||
/* Move instructions A check B check
|
/* Move/load character instructions A check B check
|
||||||
|
|
||||||
MCW: copy A to B, preserving B WM, here fetch
|
MCW copy A to B, preserving B WM, here fetch
|
||||||
until either A or B WM
|
until either A or B WM
|
||||||
LCA: copy A to B, overwriting B WM, here fetch
|
LCA copy A to B, overwriting B WM, here fetch
|
||||||
until A WM
|
until A WM
|
||||||
MCM: copy A to B, preserving B WM, fetch fetch
|
|
||||||
until record or group mark
|
Instruction lengths:
|
||||||
MCS: copy A to B, clearing B WM, until A WM; fetch fetch
|
|
||||||
reverse scan and suppress leading zeroes
|
1 chained A and B
|
||||||
MN: copy A char digit to B char digit, fetch fetch
|
2,3 invalid A-address
|
||||||
preserving B zone and WM
|
4 chained B address
|
||||||
MZ: copy A char zone to B char zone, fetch fetch
|
5,6 invalid B-address
|
||||||
preserving B digit and WM
|
7 normal
|
||||||
|
8+ normal + modifier
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_MCW: /* move char */
|
case OP_MCW: /* move char */
|
||||||
if (ilnt >= 8) { /* I/O form? */
|
if ((ilnt >= 4) && (ioind == BCD_PERCNT)) { /* I/O form? */
|
||||||
if (ioind != BCD_PERCNT) reason = STOP_INVL;
|
reason = iodisp (dev, unit, MD_NORM, D); /* dispatch I/O */
|
||||||
else reason = iodisp (dev, unit, MD_NORM, D);
|
|
||||||
break; }
|
break; }
|
||||||
if (ADDR_ERR (AS)) { /* check A addr */
|
if (ADDR_ERR (AS)) { /* check A addr */
|
||||||
reason = STOP_INVA;
|
reason = STOP_INVA;
|
||||||
|
@ -609,9 +609,8 @@ case OP_MCW: /* move char */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_LCA: /* load char */
|
case OP_LCA: /* load char */
|
||||||
if (ilnt >= 8) { /* I/O form? */
|
if ((ilnt >= 4) && (ioind == BCD_PERCNT)) { /* I/O form? */
|
||||||
if (ioind != BCD_PERCNT) reason = STOP_INVL;
|
reason = iodisp (dev, unit, MD_WM, D);
|
||||||
else reason = iodisp (dev, unit, MD_WM, D);
|
|
||||||
break; }
|
break; }
|
||||||
if (ADDR_ERR (AS)) { /* check A addr */
|
if (ADDR_ERR (AS)) { /* check A addr */
|
||||||
reason = STOP_INVA;
|
reason = STOP_INVA;
|
||||||
|
@ -621,6 +620,27 @@ case OP_LCA: /* load char */
|
||||||
MM (AS); MM (BS); } /* decr pointers */
|
MM (AS); MM (BS); } /* decr pointers */
|
||||||
while ((wm & WM) == 0); /* stop on A WM */
|
while ((wm & WM) == 0); /* stop on A WM */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* Other move instructions A check B check
|
||||||
|
|
||||||
|
MCM copy A to B, preserving B WM, fetch fetch
|
||||||
|
until record or group mark
|
||||||
|
MCS copy A to B, clearing B WM, until A WM; fetch fetch
|
||||||
|
reverse scan and suppress leading zeroes
|
||||||
|
MN copy A char digit to B char digit, fetch fetch
|
||||||
|
preserving B zone and WM
|
||||||
|
MZ copy A char zone to B char zone, fetch fetch
|
||||||
|
preserving B digit and WM
|
||||||
|
|
||||||
|
Instruction lengths:
|
||||||
|
|
||||||
|
1 chained
|
||||||
|
2,3 invalid A-address
|
||||||
|
4 self (B-address = A-address)
|
||||||
|
5,6 invalid B-address
|
||||||
|
7 normal
|
||||||
|
8+ normal + ignored modifier
|
||||||
|
*/
|
||||||
|
|
||||||
case OP_MCM: /* move to rec/group */
|
case OP_MCM: /* move to rec/group */
|
||||||
do {
|
do {
|
||||||
|
@ -662,38 +682,18 @@ case OP_MZ: /* move zone */
|
||||||
MM (AS); MM (BS); /* decr pointers */
|
MM (AS); MM (BS); /* decr pointers */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Compare - A and B are checked in fetch */
|
/* Branch instruction A check B check
|
||||||
|
|
||||||
case OP_C: /* compare */
|
Instruction lengths:
|
||||||
if (ilnt != 1) { /* if not chained */
|
|
||||||
ind[IN_EQU] = 1; /* clear indicators */
|
|
||||||
ind[IN_UNQ] = ind[IN_HGH] = ind[IN_LOW] = 0; }
|
|
||||||
do {
|
|
||||||
a = M[AS]; /* get characters */
|
|
||||||
b = M[BS];
|
|
||||||
wm = a | b; /* get word marks */
|
|
||||||
if ((a & CHAR) != (b & CHAR)) { /* unequal? */
|
|
||||||
ind[IN_EQU] = 0; /* set indicators */
|
|
||||||
ind[IN_UNQ] = 1;
|
|
||||||
ind[IN_HGH] = col_table[b & CHAR] > col_table [a & CHAR];
|
|
||||||
ind[IN_LOW] = ind[IN_HGH] ^ 1; }
|
|
||||||
MM (AS); MM (BS); } /* decr pointers */
|
|
||||||
while ((wm & WM) == 0); /* stop on A, B WM */
|
|
||||||
if ((a & WM) && !(b & WM)) { /* short A field? */
|
|
||||||
ind[IN_EQU] = ind[IN_LOW] = 0;
|
|
||||||
ind[IN_UNQ] = ind[IN_HGH] = 1; }
|
|
||||||
if (!(cpu_unit.flags & HLE)) /* no HLE? */
|
|
||||||
ind[IN_EQU] = ind[IN_LOW] = ind[IN_HGH] = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Branch instructions A check B check
|
|
||||||
|
|
||||||
B 1/8 char: branch if B char equals d if branch here
|
1 branch if B char equals d, chained if branch here
|
||||||
B 4 char: unconditional branch if branch
|
2,3 invalid B-address if branch here
|
||||||
B 5 char: branch if indicator[d] is set if branch
|
4 unconditional branch if branch
|
||||||
BWZ: branch if (d<0>: B char WM) if branch here
|
5 branch if indicator[d] is set if branch
|
||||||
(d<1>: B char zone = d zone)
|
6 invalid B-address if branch here
|
||||||
BBE: branch if B char & d non-zero if branch here
|
7 branch if B char equals d, if branch here
|
||||||
|
d is last character of B-address
|
||||||
|
8 branch if B char equals d if branch here
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_B: /* branch */
|
case OP_B: /* branch */
|
||||||
|
@ -701,14 +701,29 @@ case OP_B: /* branch */
|
||||||
else if (ilnt == 5) { /* branch on ind? */
|
else if (ilnt == 5) { /* branch on ind? */
|
||||||
if (ind[D]) { BRANCH; } /* test indicator */
|
if (ind[D]) { BRANCH; } /* test indicator */
|
||||||
if (ind_table[D]) ind[D] = 0; } /* reset if needed */
|
if (ind_table[D]) ind[D] = 0; } /* reset if needed */
|
||||||
else {
|
else { /* branch char eq */
|
||||||
if (ADDR_ERR (BS)) { /* branch char eq */
|
if (ADDR_ERR (BS)) { /* validate B addr */
|
||||||
reason = STOP_INVB; /* validate B addr */
|
reason = STOP_INVB;
|
||||||
break; }
|
break; }
|
||||||
if ((M[BS] & CHAR) == D) { BRANCH; } /* char equal? */
|
if ((M[BS] & CHAR) == D) { BRANCH; } /* char equal? */
|
||||||
else { MM (BS); } }
|
else { MM (BS); } }
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* Other branch instructions A check B check
|
||||||
|
|
||||||
|
BWZ branch if (d<0>: B char WM) if branch here
|
||||||
|
(d<1>: B char zone = d zone)
|
||||||
|
BBE branch if B char & d non-zero if branch here
|
||||||
|
|
||||||
|
Instruction lengths:
|
||||||
|
1 chained
|
||||||
|
2,3 invalid A-address and B-address
|
||||||
|
4 self (B-address = A-address, d = last character of A-address)
|
||||||
|
5,6 invalid B-address
|
||||||
|
7 normal, d = last character of B-address
|
||||||
|
8+ normal
|
||||||
|
*/
|
||||||
|
|
||||||
case OP_BWZ: /* branch wm or zone */
|
case OP_BWZ: /* branch wm or zone */
|
||||||
if (((D & 1) && (M[BS] & WM)) || /* d1? test wm */
|
if (((D & 1) && (M[BS] & WM)) || /* d1? test wm */
|
||||||
((D & 2) && ((M[BS] & ZONE) == (D & ZONE)))) /* d2? test zone */
|
((D & 2) && ((M[BS] & ZONE) == (D & ZONE)))) /* d2? test zone */
|
||||||
|
@ -721,14 +736,24 @@ case OP_BBE: /* branch if bit eq */
|
||||||
else { MM (BS); } /* decr pointer */
|
else { MM (BS); } /* decr pointer */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Arithmetic instructions A check B check
|
/* Arithmetic instructions A check B check
|
||||||
|
|
||||||
ZA: move A to B, normalizing A sign, fetch fetch
|
ZA move A to B, normalizing A sign, fetch fetch
|
||||||
preserving B WM, until B WM
|
preserving B WM, until B WM
|
||||||
ZS: move A to B, complementing A sign, fetch fetch
|
ZS move A to B, complementing A sign, fetch fetch
|
||||||
preserving B WM, until B WM
|
preserving B WM, until B WM
|
||||||
A: add A to B fetch fetch
|
A add A to B fetch fetch
|
||||||
S: subtract A from B fetch fetch
|
S subtract A from B fetch fetch
|
||||||
|
C compare A to B fetch fetch
|
||||||
|
|
||||||
|
Instruction lengths:
|
||||||
|
|
||||||
|
1 chained
|
||||||
|
2,3 invalid A-address
|
||||||
|
4 self (B-address = A-address)
|
||||||
|
5,6 invalid B-address
|
||||||
|
7 normal
|
||||||
|
8+ normal + ignored modifier
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_ZA: case OP_ZS: /* zero and add/sub */
|
case OP_ZA: case OP_ZS: /* zero and add/sub */
|
||||||
|
@ -787,42 +812,71 @@ case OP_A: case OP_S: /* add/sub */
|
||||||
carry = (t >= 10);
|
carry = (t >= 10);
|
||||||
M[bsave] = (M[bsave] & ~DIGIT) | sum_table[t]; } }
|
M[bsave] = (M[bsave] & ~DIGIT) | sum_table[t]; } }
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* I/O instructions A check B check
|
|
||||||
|
|
||||||
R: read a card if branch
|
case OP_C: /* compare */
|
||||||
W: write to line printer if branch
|
if (ilnt != 1) { /* if not chained */
|
||||||
WR: write and read if branch
|
ind[IN_EQU] = 1; /* clear indicators */
|
||||||
P: punch a card if branch
|
ind[IN_UNQ] = ind[IN_HGH] = ind[IN_LOW] = 0; }
|
||||||
RP: read and punch if branch
|
do {
|
||||||
WP: write and punch if branch
|
a = M[AS]; /* get characters */
|
||||||
WRP: write read and punch if branch
|
b = M[BS];
|
||||||
RF: read feed (nop)
|
wm = a | b; /* get word marks */
|
||||||
PF: punch feed (nop)
|
if ((a & CHAR) != (b & CHAR)) { /* unequal? */
|
||||||
SS: select stacker if branch
|
ind[IN_EQU] = 0; /* set indicators */
|
||||||
CC: carriage control if branch
|
ind[IN_UNQ] = 1;
|
||||||
MTF: magtape functions
|
ind[IN_HGH] = col_table[b & CHAR] > col_table [a & CHAR];
|
||||||
|
ind[IN_LOW] = ind[IN_HGH] ^ 1; }
|
||||||
|
MM (AS); MM (BS); } /* decr pointers */
|
||||||
|
while ((wm & WM) == 0); /* stop on A, B WM */
|
||||||
|
if ((a & WM) && !(b & WM)) { /* short A field? */
|
||||||
|
ind[IN_EQU] = ind[IN_LOW] = 0;
|
||||||
|
ind[IN_UNQ] = ind[IN_HGH] = 1; }
|
||||||
|
if (!(cpu_unit.flags & HLE)) /* no HLE? */
|
||||||
|
ind[IN_EQU] = ind[IN_LOW] = ind[IN_HGH] = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* I/O instructions A check B check
|
||||||
|
|
||||||
|
R read a card if branch
|
||||||
|
W write to line printer if branch
|
||||||
|
WR write and read if branch
|
||||||
|
P punch a card if branch
|
||||||
|
RP read and punch if branch
|
||||||
|
WP : write and punch if branch
|
||||||
|
WRP write read and punch if branch
|
||||||
|
RF read feed (nop)
|
||||||
|
PF punch feed (nop)
|
||||||
|
SS select stacker if branch
|
||||||
|
CC carriage control if branch
|
||||||
|
|
||||||
|
Instruction lengths:
|
||||||
|
|
||||||
|
1 normal
|
||||||
|
2,3 normal, with modifier
|
||||||
|
4 branch; modifier, if any, is last character of branch address
|
||||||
|
5 branch + modifier
|
||||||
|
6+ normal, with modifier
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_R: /* read */
|
case OP_R: /* read */
|
||||||
if (reason = iomod (ilnt, D, NULL)) break; /* valid modifier? */
|
if (reason = iomod (ilnt, D, NULL)) break; /* valid modifier? */
|
||||||
reason = read_card (ilnt, D); /* read card */
|
reason = read_card (ilnt, D); /* read card */
|
||||||
BS = CDR_BUF + CDR_WIDTH;
|
BS = CDR_BUF + CDR_WIDTH;
|
||||||
if (ilnt >= 4) { BRANCH; } /* check for branch */
|
if ((ilnt == 4) || (ilnt == 5)) { BRANCH; } /* check for branch */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_W: /* write */
|
case OP_W: /* write */
|
||||||
if (reason = iomod (ilnt, D, w_mod)) break; /* valid modifier? */
|
if (reason = iomod (ilnt, D, w_mod)) break; /* valid modifier? */
|
||||||
reason = write_line (ilnt, D); /* print line */
|
reason = write_line (ilnt, D); /* print line */
|
||||||
BS = LPT_BUF + LPT_WIDTH;
|
BS = LPT_BUF + LPT_WIDTH;
|
||||||
if (ilnt >= 4) { BRANCH; } /* check for branch */
|
if ((ilnt == 4) || (ilnt == 5)) { BRANCH; } /* check for branch */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_P: /* punch */
|
case OP_P: /* punch */
|
||||||
if (reason = iomod (ilnt, D, NULL)) break; /* valid modifier? */
|
if (reason = iomod (ilnt, D, NULL)) break; /* valid modifier? */
|
||||||
reason = punch_card (ilnt, D); /* punch card */
|
reason = punch_card (ilnt, D); /* punch card */
|
||||||
BS = CDP_BUF + CDP_WIDTH;
|
BS = CDP_BUF + CDP_WIDTH;
|
||||||
if (ilnt >= 4) { BRANCH; } /* check for branch */
|
if ((ilnt == 4) || (ilnt == 5)) { BRANCH; } /* check for branch */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_WR: /* write and read */
|
case OP_WR: /* write and read */
|
||||||
|
@ -830,7 +884,7 @@ case OP_WR: /* write and read */
|
||||||
reason = write_line (ilnt, D); /* print line */
|
reason = write_line (ilnt, D); /* print line */
|
||||||
r1 = read_card (ilnt, D); /* read card */
|
r1 = read_card (ilnt, D); /* read card */
|
||||||
BS = CDR_BUF + CDR_WIDTH;
|
BS = CDR_BUF + CDR_WIDTH;
|
||||||
if (ilnt >= 4) { BRANCH; } /* check for branch */
|
if ((ilnt == 4) || (ilnt == 5)) { BRANCH; } /* check for branch */
|
||||||
if (reason == SCPE_OK) reason = r1; /* merge errors */
|
if (reason == SCPE_OK) reason = r1; /* merge errors */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -839,7 +893,7 @@ case OP_WP: /* write and punch */
|
||||||
reason = write_line (ilnt, D); /* print line */
|
reason = write_line (ilnt, D); /* print line */
|
||||||
r1 = punch_card (ilnt, D); /* punch card */
|
r1 = punch_card (ilnt, D); /* punch card */
|
||||||
BS = CDP_BUF + CDP_WIDTH;
|
BS = CDP_BUF + CDP_WIDTH;
|
||||||
if (ilnt >= 4) { BRANCH; } /* check for branch */
|
if ((ilnt == 4) || (ilnt == 5)) { BRANCH; } /* check for branch */
|
||||||
if (reason == SCPE_OK) reason = r1; /* merge errors */
|
if (reason == SCPE_OK) reason = r1; /* merge errors */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -848,7 +902,7 @@ case OP_RP: /* read and punch */
|
||||||
reason = read_card (ilnt, D); /* read card */
|
reason = read_card (ilnt, D); /* read card */
|
||||||
r1 = punch_card (ilnt, D); /* punch card */
|
r1 = punch_card (ilnt, D); /* punch card */
|
||||||
BS = CDP_BUF + CDP_WIDTH;
|
BS = CDP_BUF + CDP_WIDTH;
|
||||||
if (ilnt >= 4) { BRANCH; } /* check for branch */
|
if ((ilnt == 4) || (ilnt == 5)) { BRANCH; } /* check for branch */
|
||||||
if (reason == SCPE_OK) reason = r1; /* merge errors */
|
if (reason == SCPE_OK) reason = r1; /* merge errors */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -858,24 +912,36 @@ case OP_WRP: /* write, read, punch */
|
||||||
r1 = read_card (ilnt, D); /* read card */
|
r1 = read_card (ilnt, D); /* read card */
|
||||||
r2 = punch_card (ilnt, D); /* punch card */
|
r2 = punch_card (ilnt, D); /* punch card */
|
||||||
BS = CDP_BUF + CDP_WIDTH;
|
BS = CDP_BUF + CDP_WIDTH;
|
||||||
if (ilnt >= 4) { BRANCH; } /* check for branch */
|
if ((ilnt == 4) || (ilnt == 5)) { BRANCH; } /* check for branch */
|
||||||
if (reason == SCPE_OK) reason = (r1 == SCPE_OK)? r2: r1;
|
if (reason == SCPE_OK) reason = (r1 == SCPE_OK)? r2: r1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_SS: /* select stacker */
|
case OP_SS: /* select stacker */
|
||||||
if (reason = iomod (ilnt, D, ss_mod)) break; /* valid modifier? */
|
if (reason = iomod (ilnt, D, ss_mod)) break; /* valid modifier? */
|
||||||
if (reason = select_stack (D)) break; /* sel stack, error? */
|
if (reason = select_stack (D)) break; /* sel stack, error? */
|
||||||
if (ilnt >= 4) { BRANCH; } /* check for branch */
|
if ((ilnt == 4) || (ilnt == 5)) { BRANCH; } /* check for branch */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_CC: /* carriage control */
|
case OP_CC: /* carriage control */
|
||||||
if (reason = carriage_control (D)) break; /* car ctrl, error? */
|
if (reason = carriage_control (D)) break; /* car ctrl, error? */
|
||||||
if (ilnt >= 4) { BRANCH; } /* check for branch */
|
if ((ilnt == 4) || (ilnt == 5)) { BRANCH; } /* check for branch */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* MTF - magtape functions - must be at least 4 characters
|
||||||
|
|
||||||
|
Instruction lengths:
|
||||||
|
|
||||||
|
1-3 invalid I/O address
|
||||||
|
4 normal, d-character is unit
|
||||||
|
5 normal
|
||||||
|
6+ normal, d-character is last character
|
||||||
|
*/
|
||||||
|
|
||||||
case OP_MTF: /* magtape function */
|
case OP_MTF: /* magtape function */
|
||||||
if (reason = iomod (ilnt, D, mtf_mod)) break; /* valid modifier? */
|
if (ilnt < 4) reason = STOP_INVL; /* too short? */
|
||||||
if (reason = mt_func (unit, D)) break; /* mt func, error? */
|
else if (ioind != BCD_PERCNT) reason = STOP_INVA;
|
||||||
|
else if (reason = iomod (ilnt, D, mtf_mod)) break; /* valid modifier? */
|
||||||
|
reason = mt_func (unit, D); /* mt func, error? */
|
||||||
break; /* can't branch */
|
break; /* can't branch */
|
||||||
|
|
||||||
case OP_RF: case OP_PF: /* read, punch feed */
|
case OP_RF: case OP_PF: /* read, punch feed */
|
||||||
|
@ -902,6 +968,15 @@ case OP_RF: case OP_PF: /* read, punch feed */
|
||||||
|
|
||||||
The first A field character is masked to its digit part, all others
|
The first A field character is masked to its digit part, all others
|
||||||
are copied intact
|
are copied intact
|
||||||
|
|
||||||
|
Instruction lengths:
|
||||||
|
|
||||||
|
1 chained
|
||||||
|
2,3 invalid A-address
|
||||||
|
4 self (B-address = A-address)
|
||||||
|
5,6 invalid B-address
|
||||||
|
7 normal
|
||||||
|
8+ normal + ignored modifier
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_MCE: /* edit */
|
case OP_MCE: /* edit */
|
||||||
|
@ -1040,6 +1115,15 @@ case OP_MCE: /* edit */
|
||||||
LD + 1 + length of multiplier. Locate the low order multiplier digit,
|
LD + 1 + length of multiplier. Locate the low order multiplier digit,
|
||||||
and at the same time zero out the product field. Then compute the sign
|
and at the same time zero out the product field. Then compute the sign
|
||||||
of the result.
|
of the result.
|
||||||
|
|
||||||
|
Instruction lengths:
|
||||||
|
|
||||||
|
1 chained
|
||||||
|
2,3 invalid A-address
|
||||||
|
4 self (B-address = A-address)
|
||||||
|
5,6 invalid B-address
|
||||||
|
7 normal
|
||||||
|
8+ normal + ignored modifier
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_MUL:
|
case OP_MUL:
|
||||||
|
@ -1085,7 +1169,7 @@ case OP_MUL:
|
||||||
|
|
||||||
/* Divide. Comments from the PDP-10 based simulator by Len Fehskens.
|
/* Divide. Comments from the PDP-10 based simulator by Len Fehskens.
|
||||||
|
|
||||||
Divide is done, like multiply, pretty muchy the same way you do it with
|
Divide is done, like multiply, pretty much the same way you do it with
|
||||||
pencil and paper; successive subtraction of the divisor from a substring
|
pencil and paper; successive subtraction of the divisor from a substring
|
||||||
of the dividend while counting up the corresponding quotient digit.
|
of the dividend while counting up the corresponding quotient digit.
|
||||||
|
|
||||||
|
@ -1106,6 +1190,15 @@ case OP_MUL:
|
||||||
|
|
||||||
Start by locating the high order non-zero digit of the divisor. This
|
Start by locating the high order non-zero digit of the divisor. This
|
||||||
also tests for a divide by zero.
|
also tests for a divide by zero.
|
||||||
|
|
||||||
|
Instruction lengths:
|
||||||
|
|
||||||
|
1 chained
|
||||||
|
2,3 invalid A-address
|
||||||
|
4 self (B-address = A-address)
|
||||||
|
5,6 invalid B-address
|
||||||
|
7 normal
|
||||||
|
8+ normal + ignored modifier
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_DIV:
|
case OP_DIV:
|
||||||
|
@ -1170,16 +1263,19 @@ case OP_DIV:
|
||||||
BS = qs - 2; /* BS = quo 10's pos */
|
BS = qs - 2; /* BS = quo 10's pos */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Miscellaneous instructions A check B check
|
/* Word mark instructions A check B check
|
||||||
|
|
||||||
SWM: set WM on A char and B char fetch fetch
|
SWM set WM on A char and B char fetch fetch
|
||||||
CWM: clear WM on A char and B char fetch fetch
|
CWM clear WM on A char and B char fetch fetch
|
||||||
CS: clear from B down to nearest hundreds address if branch fetch
|
|
||||||
MA: add A addr and B addr, store at B addr fetch fetch
|
Instruction lengths:
|
||||||
SAR: store A* at A addr fetch
|
|
||||||
SBR: store B* at A addr fetch
|
1 chained
|
||||||
NOP: no operation
|
2,3 invalid A-address
|
||||||
H: halt
|
4 one operand (B-address = A-address)
|
||||||
|
5,6 invalid B-address
|
||||||
|
7 two operands (SWM cannot be longer than 7)
|
||||||
|
8+ two operands + ignored modifier
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_SWM: /* set word mark */
|
case OP_SWM: /* set word mark */
|
||||||
|
@ -1194,13 +1290,41 @@ case OP_CWM: /* clear word mark */
|
||||||
MM (AS); MM (BS); /* decr pointers */
|
MM (AS); MM (BS); /* decr pointers */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* Clear storage instruction A check B check
|
||||||
|
|
||||||
|
CS clear from B down to nearest hundreds if branch fetch
|
||||||
|
address
|
||||||
|
|
||||||
|
Instruction lengths:
|
||||||
|
|
||||||
|
1 chained
|
||||||
|
2,3 invalid A-address and B-address
|
||||||
|
4 one operand (B-address = A-address)
|
||||||
|
5,6 invalid B-address
|
||||||
|
7 branch
|
||||||
|
8+ one operand, branch ignored
|
||||||
|
*/
|
||||||
|
|
||||||
case OP_CS: /* clear storage */
|
case OP_CS: /* clear storage */
|
||||||
t = (BS / 100) * 100; /* lower bound */
|
t = (BS / 100) * 100; /* lower bound */
|
||||||
while (BS >= t) M[BS--] = 0; /* clear region */
|
while (BS >= t) M[BS--] = 0; /* clear region */
|
||||||
if (BS < 0) BS = BS + MEMSIZE; /* wrap if needed */
|
if (BS < 0) BS = BS + MEMSIZE; /* wrap if needed */
|
||||||
if (ilnt >= 7) { BRANCH; } /* branch variant? */
|
if (ilnt == 7) { BRANCH; } /* branch variant? */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* Modify address instruction A check B check
|
||||||
|
|
||||||
|
MA add A addr and B addr, store at B addr fetch fetch
|
||||||
|
|
||||||
|
Instruction lengths:
|
||||||
|
1 chained
|
||||||
|
2,3 invalid A-address and B-address
|
||||||
|
4 self (B-address = A-address)
|
||||||
|
5,6 invalid B-address
|
||||||
|
7 normal
|
||||||
|
8+ normal + ignored modifier
|
||||||
|
*/
|
||||||
|
|
||||||
case OP_MA: /* modify address */
|
case OP_MA: /* modify address */
|
||||||
a = one_table[M[AS] & CHAR]; MM (AS); /* get A address */
|
a = one_table[M[AS] & CHAR]; MM (AS); /* get A address */
|
||||||
a = a + ten_table[M[AS] & CHAR]; MM (AS);
|
a = a + ten_table[M[AS] & CHAR]; MM (AS);
|
||||||
|
@ -1215,15 +1339,32 @@ case OP_MA: /* modify address */
|
||||||
if (((a % 4000) + (b % 4000)) >= 4000) BS = BS + 2; /* carry? */
|
if (((a % 4000) + (b % 4000)) >= 4000) BS = BS + 2; /* carry? */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* Store address instructions A-check B-check
|
||||||
|
|
||||||
|
SAR store A* at A addr fetch
|
||||||
|
SBR store B* at A addr fetch
|
||||||
|
|
||||||
|
Instruction lengths:
|
||||||
|
1 chained
|
||||||
|
2,3 invalid A-address
|
||||||
|
4 normal
|
||||||
|
5+ B-address overwritten from instruction;
|
||||||
|
invalid address ignored
|
||||||
|
*/
|
||||||
|
|
||||||
case OP_SAR: case OP_SBR: /* store A, B reg */
|
case OP_SAR: case OP_SBR: /* store A, B reg */
|
||||||
M[AS] = (M[AS] & WM) | store_addr_u (BS); MM (AS);
|
M[AS] = (M[AS] & WM) | store_addr_u (BS); MM (AS);
|
||||||
M[AS] = (M[AS] & WM) | store_addr_t (BS); MM (AS);
|
M[AS] = (M[AS] & WM) | store_addr_t (BS); MM (AS);
|
||||||
M[AS] = (M[AS] & WM) | store_addr_h (BS); MM (AS);
|
M[AS] = (M[AS] & WM) | store_addr_h (BS); MM (AS);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* NOP - no validity checking, all instructions length ok */
|
||||||
|
|
||||||
case OP_NOP: /* nop */
|
case OP_NOP: /* nop */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* HALT - unless length = 4 (branch), no validity checking; all lengths ok */
|
||||||
|
|
||||||
case OP_H: /* halt */
|
case OP_H: /* halt */
|
||||||
if (ilnt == 4) hb_pend = 1; /* set pending branch */
|
if (ilnt == 4) hb_pend = 1; /* set pending branch */
|
||||||
reason = STOP_HALT; /* stop simulator */
|
reason = STOP_HALT; /* stop simulator */
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
To: Users
|
To: Users
|
||||||
From: Bob Supnik
|
From: Bob Supnik
|
||||||
Subj: IBM 1401 Simulator Usage
|
Subj: IBM 1401 Simulator Usage
|
||||||
Date: 20-Apr-2003
|
Date: 15-Jul-2003
|
||||||
|
|
||||||
COPYRIGHT NOTICE
|
COPYRIGHT NOTICE
|
||||||
|
|
||||||
|
@ -39,13 +39,16 @@ This memorandum documents the IBM 1401 simulator.
|
||||||
sim/ sim_defs.h
|
sim/ sim_defs.h
|
||||||
sim_rev.h
|
sim_rev.h
|
||||||
sim_sock.h
|
sim_sock.h
|
||||||
|
sim_tape.h
|
||||||
sim_tmxr.h
|
sim_tmxr.h
|
||||||
scp.c
|
scp.c
|
||||||
scp_tty.c
|
scp_tty.c
|
||||||
sim_sock.c
|
sim_sock.c
|
||||||
|
sim_tape.c
|
||||||
sim_tmxr.c
|
sim_tmxr.c
|
||||||
|
|
||||||
sim/i1401/ i1401_defs.h
|
sim/i1401/ i1401_defs.h
|
||||||
|
i1401_dat.h
|
||||||
i1401_cpu.c
|
i1401_cpu.c
|
||||||
i1401_cd.c
|
i1401_cd.c
|
||||||
i1401_iq.c
|
i1401_iq.c
|
||||||
|
|
|
@ -138,7 +138,7 @@ standard on the Model 2.
|
||||||
|
|
||||||
If memory size is being reduced, and the memory being truncated contains
|
If memory size is being reduced, and the memory being truncated contains
|
||||||
non-zero data, the simulator asks for confirmation. Data in the truncated
|
non-zero data, the simulator asks for confirmation. Data in the truncated
|
||||||
portion of memory is lost. Initially, the CPU is a Model I, memory size is
|
portion of memory is lost. Initially, the CPU is a Model 1, memory size is
|
||||||
20K, and indirect addressing, editing instructions, and divide are enabled.
|
20K, and indirect addressing, editing instructions, and divide are enabled.
|
||||||
|
|
||||||
Memory is implemented as 5 bit BCD digits, as follows:
|
Memory is implemented as 5 bit BCD digits, as follows:
|
||||||
|
@ -393,7 +393,7 @@ controlled by command line switches:
|
||||||
-s display as flag terminated numeric string
|
-s display as flag terminated numeric string
|
||||||
(CPU and DP only)
|
(CPU and DP only)
|
||||||
-m display instruction mnemonics
|
-m display instruction mnemonics
|
||||||
(CPU and only)
|
(CPU and DP only)
|
||||||
-d display 50 characters per line, with word
|
-d display 50 characters per line, with word
|
||||||
marks denoted by "_" on the line above
|
marks denoted by "_" on the line above
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,8 @@ BSC32_SBRS= \
|
||||||
$(INTDIR)/scp.sbr \
|
$(INTDIR)/scp.sbr \
|
||||||
$(INTDIR)/scp_tty.sbr \
|
$(INTDIR)/scp_tty.sbr \
|
||||||
$(INTDIR)/sim_tmxr.sbr \
|
$(INTDIR)/sim_tmxr.sbr \
|
||||||
$(INTDIR)/sim_sock.sbr
|
$(INTDIR)/sim_sock.sbr \
|
||||||
|
$(INTDIR)/ibm1130_fmt.sbr
|
||||||
|
|
||||||
$(OUTDIR)/ibm1130.bsc : $(OUTDIR) $(BSC32_SBRS)
|
$(OUTDIR)/ibm1130.bsc : $(OUTDIR) $(BSC32_SBRS)
|
||||||
$(BSC32) @<<
|
$(BSC32) @<<
|
||||||
|
@ -99,7 +100,8 @@ LINK32_OBJS= \
|
||||||
$(INTDIR)/scp.obj \
|
$(INTDIR)/scp.obj \
|
||||||
$(INTDIR)/scp_tty.obj \
|
$(INTDIR)/scp_tty.obj \
|
||||||
$(INTDIR)/sim_tmxr.obj \
|
$(INTDIR)/sim_tmxr.obj \
|
||||||
$(INTDIR)/sim_sock.obj
|
$(INTDIR)/sim_sock.obj \
|
||||||
|
$(INTDIR)/ibm1130_fmt.obj
|
||||||
|
|
||||||
$(OUTDIR)/ibm1130.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
|
$(OUTDIR)/ibm1130.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
|
||||||
$(LINK32) @<<
|
$(LINK32) @<<
|
||||||
|
@ -149,7 +151,8 @@ BSC32_SBRS= \
|
||||||
$(INTDIR)/scp.sbr \
|
$(INTDIR)/scp.sbr \
|
||||||
$(INTDIR)/scp_tty.sbr \
|
$(INTDIR)/scp_tty.sbr \
|
||||||
$(INTDIR)/sim_tmxr.sbr \
|
$(INTDIR)/sim_tmxr.sbr \
|
||||||
$(INTDIR)/sim_sock.sbr
|
$(INTDIR)/sim_sock.sbr \
|
||||||
|
$(INTDIR)/ibm1130_fmt.sbr
|
||||||
|
|
||||||
$(OUTDIR)/ibm1130.bsc : $(OUTDIR) $(BSC32_SBRS)
|
$(OUTDIR)/ibm1130.bsc : $(OUTDIR) $(BSC32_SBRS)
|
||||||
$(BSC32) @<<
|
$(BSC32) @<<
|
||||||
|
@ -176,7 +179,8 @@ LINK32_OBJS= \
|
||||||
$(INTDIR)/scp.obj \
|
$(INTDIR)/scp.obj \
|
||||||
$(INTDIR)/scp_tty.obj \
|
$(INTDIR)/scp_tty.obj \
|
||||||
$(INTDIR)/sim_tmxr.obj \
|
$(INTDIR)/sim_tmxr.obj \
|
||||||
$(INTDIR)/sim_sock.obj
|
$(INTDIR)/sim_sock.obj \
|
||||||
|
$(INTDIR)/ibm1130_fmt.obj
|
||||||
|
|
||||||
$(OUTDIR)/ibm1130.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
|
$(OUTDIR)/ibm1130.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
|
||||||
$(LINK32) @<<
|
$(LINK32) @<<
|
||||||
|
@ -249,7 +253,7 @@ $(INTDIR)/ibm1130_stddev.obj : $(SOURCE) $(DEP_IBM1130_) $(INTDIR)
|
||||||
SOURCE=.\ibm1130.rc
|
SOURCE=.\ibm1130.rc
|
||||||
DEP_IBM1130_R=\
|
DEP_IBM1130_R=\
|
||||||
.\1130consoleblank.bmp\
|
.\1130consoleblank.bmp\
|
||||||
.\HAND.CUR
|
.\hand.cur
|
||||||
|
|
||||||
$(INTDIR)/ibm1130.res : $(SOURCE) $(DEP_IBM1130_R) $(INTDIR)
|
$(INTDIR)/ibm1130.res : $(SOURCE) $(DEP_IBM1130_R) $(INTDIR)
|
||||||
$(RSC) $(RSC_PROJ) $(SOURCE)
|
$(RSC) $(RSC_PROJ) $(SOURCE)
|
||||||
|
@ -354,6 +358,14 @@ DEP_SIM_S=\
|
||||||
$(INTDIR)/sim_sock.obj : $(SOURCE) $(DEP_SIM_S) $(INTDIR)
|
$(INTDIR)/sim_sock.obj : $(SOURCE) $(DEP_SIM_S) $(INTDIR)
|
||||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||||
|
|
||||||
|
# End Source File
|
||||||
|
################################################################################
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\ibm1130_fmt.c
|
||||||
|
|
||||||
|
$(INTDIR)/ibm1130_fmt.obj : $(SOURCE) $(INTDIR)
|
||||||
|
|
||||||
# End Source File
|
# End Source File
|
||||||
# End Group
|
# End Group
|
||||||
# End Project
|
# End Project
|
||||||
|
|
|
@ -9,26 +9,27 @@
|
||||||
* Mail to sim@ibm1130.org
|
* Mail to sim@ibm1130.org
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// ctrl-M (Enter) => EOF
|
// 03 ctrl-C => Program stop (not handled here)
|
||||||
// ctrl-U => Erase field
|
// 05 ctrl-E => Simulator stop (not handled here)
|
||||||
// ctrl-Q => Interrupt request (not here)
|
// 08 ctrl-H => Backspace
|
||||||
// ctrl-C => Program stop (not here)
|
// 0D ctrl-M (Enter) => EOF
|
||||||
// \ => "not"
|
// 11 ctrl-Q => Interrupt request (not handled here)
|
||||||
// Del => backspace
|
// 12 ctrl-R => "cent" (R because that's where cent is on the 1130 keyboard)
|
||||||
// Ctrl-H => backspace
|
// 15 ctrl-U => Erase Field
|
||||||
|
// 7E ~ => "not"
|
||||||
|
// FF Del => Backspace again
|
||||||
|
|
||||||
static uint16 ascii_to_conin[] = /* ASCII to ((hollerith << 4) | special key flags) */
|
static uint16 ascii_to_conin[] = /* ASCII to ((hollerith << 4) | special key flags) */
|
||||||
{
|
{
|
||||||
/* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */
|
/* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */
|
||||||
/* 00 */ 0, 0, 0, 0, 0, 0, 0, 0,0x0004, 0, 0, 0, 0,0x0008, 0, 0,
|
/* 00 */ 0, 0, 0, 0, 0, 0, 0, 0,0x0004, 0, 0, 0, 0,0x0008, 0, 0,
|
||||||
/* 01 */ 0, 0, 0, 0, 0,0x0002, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
/* 10 */ 0, 0,0x8820, 0, 0,0x0002, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
/* 20 */ 0x0001,0x4820,0x0060,0x0420,0x4420,0x2220,0x8000,0x0120,0x8120,0x4120,0x4220,0x80a0,0x2420,0x4000,0x8420,0x3000,
|
/* 20 */ 0x0001,0x4820,0x0060,0x0420,0x4420,0x2220,0x8000,0x0120,0x8120,0x4120,0x4220,0x80a0,0x2420,0x4000,0x8420,0x3000,
|
||||||
/* 30 */ 0x2000,0x1000,0x0800,0x0400,0x0200,0x0100,0x0080,0x0040,0x0020,0x0010,0x0820,0x40a0,0x8220,0x00a0,0x20a0,0x2060,
|
/* 30 */ 0x2000,0x1000,0x0800,0x0400,0x0200,0x0100,0x0080,0x0040,0x0020,0x0010,0x0820,0x40a0,0x8220,0x00a0,0x20a0,0x2060,
|
||||||
/* 40 */ 0x0220,0x9000,0x8800,0x8400,0x8200,0x8100,0x8080,0x8040,0x8020,0x8010,0x5000,0x4800,0x4400,0x4200,0x4100,0x4080,
|
/* 40 */ 0x0220,0x9000,0x8800,0x8400,0x8200,0x8100,0x8080,0x8040,0x8020,0x8010,0x5000,0x4800,0x4400,0x4200,0x4100,0x4080,
|
||||||
/* 50 */ 0x4040,0x4020,0x4010,0x2800,0x2400,0x2200,0x2100,0x2080,0x2040,0x2020,0x2010,0xa420, 0,0xc420,0x4060,0x2120,
|
/* 50 */ 0x4040,0x4020,0x4010,0x2800,0x2400,0x2200,0x2100,0x2080,0x2040,0x2020,0x2010, 0, 0, 0, 0,0x2120,
|
||||||
/* 60 */ 0,0x9000,0x8800,0x8400,0x8200,0x8100,0x8080,0x8040,0x8020,0x8010,0x5000,0x4800,0x4400,0x4200,0x4100,0x4080,
|
/* 60 */ 0,0x9000,0x8800,0x8400,0x8200,0x8100,0x8080,0x8040,0x8020,0x8010,0x5000,0x4800,0x4400,0x4200,0x4100,0x4080,
|
||||||
/* 70 */ 0x4040,0x4020,0x4010,0x2800,0x2400,0x2200,0x2100,0x2080,0x2040,0x2020,0x2010,0xa420, 0,0x8060, 0,0x0004,
|
/* 70 */ 0x4040,0x4020,0x4010,0x2800,0x2400,0x2200,0x2100,0x2080,0x2040,0x2020,0x2010, 0,0xB060, 0, 0,0x0004,
|
||||||
/* 80 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
/* 80 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
/* 90 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
/* 90 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
/* a0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
/* a0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
@ -38,4 +39,3 @@ static uint16 ascii_to_conin[] = /* ASCII to ((hollerith << 4) | special key
|
||||||
/* e0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
/* e0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
/* f0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x0004,
|
/* f0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x0004,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -12,31 +12,47 @@
|
||||||
|
|
||||||
#define _0_ '\0'
|
#define _0_ '\0'
|
||||||
|
|
||||||
#define CENT '\xA2'
|
#define CENT_ '\xA2' /* cent and not: standard DOS mapping */
|
||||||
#define REST IGNR
|
#define NOT_ '\xAC'
|
||||||
#define RDRSTP '?'
|
#define IGNR_ '\xFF'
|
||||||
#define NOT '\xAC'
|
#define CRLF_ '\r'
|
||||||
#define IGNR '\xFF'
|
|
||||||
#define CRLF '\r'
|
|
||||||
|
|
||||||
static char conout_to_ascii[] = /* console output code to ASCII */
|
#define COUT_IS_CTRL 0x01 /* conout characters with bit 1 set are controls: */
|
||||||
|
|
||||||
|
#define COUT_CTRL_BLACK 0x04 /* none or one of these bits */
|
||||||
|
#define COUT_CTRL_RED 0x08
|
||||||
|
|
||||||
|
#define COUT_CTRL_LINEFEED 0x02 /* plus none or one of these bits */
|
||||||
|
#define COUT_CTRL_BACKSPACE 0x10
|
||||||
|
#define COUT_CTRL_SPACE 0x20
|
||||||
|
#define COUT_CTRL_TAB 0x40
|
||||||
|
#define COUT_CTRL_RETURN 0x80
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# pragma warning(disable:4245) /* enable int->char demotion warning caused by characters with high-bit set */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static unsigned char conout_to_ascii[] = /* console output code to ASCII */
|
||||||
{
|
{
|
||||||
/* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */
|
/* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */
|
||||||
/* 00 */ '.', _0_, CENT, '\n', '@', REST, '%', _0_, _0_,RDRSTP, _0_, _0_, _0_, _0_, _0_, _0_,
|
/* 00 */ '.', IGNR_,CENT_, '\n', '@', IGNR_,'%', _0_, _0_, IGNR_,_0_, _0_, _0_, _0_, _0_, _0_,
|
||||||
/* 10 */ 'f', '\b', 'F', _0_, 'g', _0_, 'G', _0_, 'b', _0_, 'B', _0_, 'c', _0_, 'C', _0_,
|
/* 10 */ 'F', '\b', 'f', _0_, 'G', _0_, 'g', _0_, 'B', _0_, 'b', _0_, 'C', _0_, 'c', _0_,
|
||||||
/* 20 */ 'i', ' ', 'I', _0_, 'h', _0_, 'H', _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_,
|
/* 20 */ 'I', ' ', 'i', _0_, 'H', _0_, 'h', _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_,
|
||||||
/* 30 */ 'd', _0_, 'D', _0_, 'e', _0_, 'E', _0_, _0_, _0_, _0_, _0_, 'a', _0_, 'A', _0_,
|
/* 30 */ 'D', _0_, 'd', _0_, 'E', _0_, 'e', _0_, _0_, _0_, _0_, _0_, 'A', _0_, 'a', _0_,
|
||||||
/* 40 */ '$', _0_, '!', _0_, '&', _0_, '>', _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_,
|
/* 40 */ '$', '\t', '!', _0_, '&', _0_, '>', _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_,
|
||||||
/* 50 */ 'o', _0_, 'O', _0_, 'p', _0_, 'P', _0_, 'k', _0_, 'K', _0_, 'l', _0_, 'L', _0_,
|
/* 50 */ 'O', _0_, 'o', _0_, 'P', _0_, 'o', _0_, 'K', _0_, 'k', _0_, 'L', _0_, 'l', _0_,
|
||||||
/* 60 */ 'r', _0_, 'R', _0_, 'q', _0_, 'Q', _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_,
|
/* 60 */ 'R', _0_, 'r', _0_, 'Q', _0_, 'q', _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_,
|
||||||
/* 70 */ 'm', _0_, 'M', _0_, 'n', _0_, 'N', _0_, _0_, _0_, _0_, _0_, 'j', _0_, _0_, _0_,
|
/* 70 */ 'M', _0_, 'm', _0_, 'N', _0_, 'n', _0_, _0_, _0_, _0_, _0_, 'J', _0_, 'j', _0_,
|
||||||
/* 80 */ ',', CRLF, ':', _0_, '-', _0_, '?', _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_,
|
/* 80 */ ',', CRLF_, ':', _0_, '-', _0_, '?', _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_,
|
||||||
/* 90 */ 'w', _0_, 'W', _0_, 'x', _0_, 'X', _0_, 's', _0_, 'S', _0_, 't', _0_, 'T', _0_,
|
/* 90 */ 'W', _0_, 'w', _0_, 'X', _0_, 'x', _0_, 'S', _0_, 's', _0_, 'T', _0_, 't', _0_,
|
||||||
/* A0 */ 'z', _0_, 'Z', _0_, 'y', _0_, 'Y', _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_,
|
/* A0 */ 'Z', _0_, 'z', _0_, 'Y', _0_, 'y', _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_,
|
||||||
/* B0 */ 'u', _0_, 'U', _0_, 'v', _0_, 'V', _0_, _0_, _0_, _0_, _0_, '/', _0_, '_', _0_,
|
/* B0 */ 'U', _0_, 'u', _0_, 'V', _0_, 'v', _0_, _0_, _0_, _0_, _0_, '/', _0_, '_', _0_,
|
||||||
/* C0 */ '#', _0_, '=', _0_, '0', _0_, '|', _0_, _0_, _0_, _0_, _0_, _0_, _0_, 'J', _0_,
|
/* C0 */ '#', _0_, '=', _0_, '0', _0_, '|', _0_, _0_, _0_, _0_, _0_, 'J', _0_, 'j', _0_,
|
||||||
/* D0 */ '6', _0_, ';', _0_, '7', _0_, '*', _0_, '2', _0_, '+', _0_, '3', _0_, '<', _0_,
|
/* D0 */ '6', _0_, ';', _0_, '7', _0_, '*', _0_, '2', _0_, '+', _0_, '3', _0_, '<', _0_,
|
||||||
/* E0 */ '9', _0_, '"', _0_, '8', _0_, '\'', _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_,
|
/* E0 */ '9', _0_, '"', _0_, '8', _0_, '\'', _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_,
|
||||||
/* F0 */ '4', _0_, NOT, _0_, '5', _0_, ')', _0_, _0_, _0_, _0_, _0_, '1', _0_, '(', _0_,
|
/* F0 */ '4', _0_, NOT_, _0_, '5', _0_, ')', _0_, _0_, _0_, _0_, _0_, '1', _0_, '(', _0_,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# pragma warning(default:4245) /* enable int->char demotion warning */
|
||||||
|
#endif
|
||||||
|
|
|
@ -9,13 +9,14 @@
|
||||||
* or modifications.
|
* or modifications.
|
||||||
*
|
*
|
||||||
* This is not a supported product, but I welcome bug reports and fixes.
|
* This is not a supported product, but I welcome bug reports and fixes.
|
||||||
* Mail to sim@ibm1130.org
|
* Mail to simh@ibm1130.org
|
||||||
|
|
||||||
25-Jun-01 BLK Written
|
25-Jun-01 BLK Written
|
||||||
10-May-02 BLK Fixed bug in MDX instruction
|
10-May-02 BLK Fixed bug in MDX instruction
|
||||||
27-Mar-02 BLK Made BOSC work even in short form
|
27-Mar-02 BLK Made BOSC work even in short form
|
||||||
16-Aug-02 BLK Fixed bug in multiply instruction; didn't work with negative values
|
16-Aug-02 BLK Fixed bug in multiply instruction; didn't work with negative values
|
||||||
18-Mar-03 BLK Fixed bug in divide instruction; didn't work with negative values
|
18-Mar-03 BLK Fixed bug in divide instruction; didn't work with negative values
|
||||||
|
23-Jul-03 BLK Prevented tti polling in CGI mode
|
||||||
|
|
||||||
The register state for the IBM 1130 CPU is:
|
The register state for the IBM 1130 CPU is:
|
||||||
|
|
||||||
|
@ -470,23 +471,17 @@ t_stat sim_instr (void)
|
||||||
if (wait_state) { /* waiting? */
|
if (wait_state) { /* waiting? */
|
||||||
sim_interval = 0; /* run the clock out */
|
sim_interval = 0; /* run the clock out */
|
||||||
|
|
||||||
if (sim_qcount() <= 1) { /* waiting for keyboard only */
|
if (sim_qcount() <= (cgi ? 0 : 1)) { /* one routine queued? we're waiting for keyboard only */
|
||||||
if (keyboard_is_locked()) { /* CPU is not expecting a keystroke */
|
if (keyboard_is_busy()) { /* we are actually waiting for a keystroke */
|
||||||
|
if ((status = sim_process_event()) != 0) /* get it with wait_state still set */
|
||||||
|
reason = status;
|
||||||
|
}
|
||||||
|
else { /* CPU is not expecting a keystroke (keyboard interrupt) */
|
||||||
if (wait_state == WAIT_OP)
|
if (wait_state == WAIT_OP)
|
||||||
reason = STOP_WAIT; /* end the simulation */
|
reason = STOP_WAIT; /* end the simulation */
|
||||||
else
|
else
|
||||||
reason = STOP_INVALID_INSTR;
|
reason = STOP_INVALID_INSTR;
|
||||||
}
|
}
|
||||||
else { /* we are actually waiting for a keystroke */
|
|
||||||
if ((status = sim_process_event()) != 0) /* get it with wait_state still set */
|
|
||||||
reason = status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (sim_clock_queue == NULL) { /* not waiting for anything */
|
|
||||||
if (wait_state == WAIT_OP)
|
|
||||||
reason = STOP_WAIT; /* end the simulation */
|
|
||||||
else
|
|
||||||
reason = STOP_INVALID_INSTR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gdu_active()) /* but don't stop simulator if 2250 GDU is running */
|
if (gdu_active()) /* but don't stop simulator if 2250 GDU is running */
|
||||||
|
@ -1254,7 +1249,7 @@ void xio_error (char *msg)
|
||||||
* register_cmd - add a command to the extensible command table
|
* register_cmd - add a command to the extensible command table
|
||||||
* ------------------------------------------------------------------------ */
|
* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
t_stat register_cmd (char *name, t_stat (*action)(int32, char *), int arg, char *help)
|
t_stat register_cmd (char *name, t_stat (*action)(int32 flag, char *ptr), int arg, char *help)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
1092
Ibm1130/ibm1130_cr.c
1092
Ibm1130/ibm1130_cr.c
File diff suppressed because it is too large
Load diff
|
@ -258,23 +258,23 @@ void xio_2250_display (int32 addr, int32 func, int32 modify); // vector displ
|
||||||
void xio_error (char *msg);
|
void xio_error (char *msg);
|
||||||
|
|
||||||
void bail (char *msg);
|
void bail (char *msg);
|
||||||
t_stat load_cr_boot (int drv);
|
t_stat load_cr_boot (int drv, int switches);
|
||||||
t_stat cr_boot (int unitno, DEVICE *dptr);
|
t_stat cr_boot (int unitno, DEVICE *dptr);
|
||||||
void calc_ints (void); /* recalculate interrupt bitmask */
|
void calc_ints (void); /* recalculate interrupt bitmask */
|
||||||
void trace_io (char *fmt, ...); /* debugging printout */
|
void trace_io (char *fmt, ...); /* debugging printout */
|
||||||
void scp_panic (char *msg); /* bail out of simulator */
|
void scp_panic (char *msg); /* bail out of simulator */
|
||||||
char *upcase(char *str);
|
char *upcase(char *str);
|
||||||
void break_simulation (t_stat reason); /* let a device halt the simulation */
|
void break_simulation (t_stat reason); /* let a device halt the simulation */
|
||||||
char hollerith_to_ascii (int16 hol); /* for debugging use only */
|
char hollerith_to_ascii (uint16 hol); /* for debugging use only */
|
||||||
t_bool gdu_active (void);
|
t_bool gdu_active (void);
|
||||||
void remark_cmd (char *remark);
|
void remark_cmd (char *remark);
|
||||||
void stuff_cmd (char *cmd);
|
void stuff_cmd (char *cmd);
|
||||||
void update_gui (t_bool force);
|
void update_gui (t_bool force);
|
||||||
void sim_init (void);
|
void sim_init (void);
|
||||||
t_stat register_cmd (char *name, t_stat (*action)(int32, char *), int arg, char *help);
|
t_stat register_cmd (char *name, t_stat (*action)(int32 flag, char *ptr), int arg, char *help);
|
||||||
|
|
||||||
/* GUI interface routines */
|
/* GUI interface routines */
|
||||||
t_bool keyboard_is_locked (void);
|
t_bool keyboard_is_busy (void);
|
||||||
void forms_check (int set); /* device notification to console lamp display */
|
void forms_check (int set); /* device notification to console lamp display */
|
||||||
void print_check (int set);
|
void print_check (int set);
|
||||||
void keyboard_selected (int select);
|
void keyboard_selected (int select);
|
||||||
|
|
|
@ -13,14 +13,17 @@ commands may NOT be accurate. This should probably be fixed.
|
||||||
* usual yada-yada. Please keep this notice and the copyright in any distributions
|
* usual yada-yada. Please keep this notice and the copyright in any distributions
|
||||||
* or modifications.
|
* or modifications.
|
||||||
*
|
*
|
||||||
* This is not a supported product, but I welcome bug reports and fixes.
|
|
||||||
* Mail to sim@ibm1130.org
|
|
||||||
*
|
|
||||||
* Revision History
|
* Revision History
|
||||||
|
* 15-jun-03 moved actual read on XIO read to end of time interval,
|
||||||
|
* as the APL boot card required 2 instructions to run between the
|
||||||
|
* time read was initiated and the time the data was read (a jump and a wait)
|
||||||
|
*
|
||||||
* 01-sep-02 corrected treatment of -m and -r flags in dsk_attach
|
* 01-sep-02 corrected treatment of -m and -r flags in dsk_attach
|
||||||
* in cgi mode, so that file is opened readonly but emulated
|
* in cgi mode, so that file is opened readonly but emulated
|
||||||
* disk is writable.
|
* disk is writable.
|
||||||
*
|
*
|
||||||
|
* This is not a supported product, but I welcome bug reports and fixes.
|
||||||
|
* Mail to simh@ibm1130.org
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ibm1130_defs.h"
|
#include "ibm1130_defs.h"
|
||||||
|
@ -75,6 +78,7 @@ static int16 dsk_sec[DSK_NUMDR] = {0}; /* next-sector-up */
|
||||||
static char dsk_lastio[DSK_NUMDR]; /* last stdio operation: IO_READ or IO_WRITE */
|
static char dsk_lastio[DSK_NUMDR]; /* last stdio operation: IO_READ or IO_WRITE */
|
||||||
int32 dsk_swait = 50; /* seek time -- see how short a delay we can get away with */
|
int32 dsk_swait = 50; /* seek time -- see how short a delay we can get away with */
|
||||||
int32 dsk_rwait = 50; /* rotate time */
|
int32 dsk_rwait = 50; /* rotate time */
|
||||||
|
static t_bool raw_disk_debug = FALSE;
|
||||||
|
|
||||||
static t_stat dsk_svc (UNIT *uptr);
|
static t_stat dsk_svc (UNIT *uptr);
|
||||||
static t_stat dsk_reset (DEVICE *dptr);
|
static t_stat dsk_reset (DEVICE *dptr);
|
||||||
|
@ -141,6 +145,15 @@ static int32 dsk_ilswlevel[DSK_NUMDR] =
|
||||||
2, 2, 2, 2
|
2, 2, 2, 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef enum {DSK_FUNC_IDLE, DSK_FUNC_READ, DSK_FUNC_VERIFY, DSK_FUNC_WRITE, DSK_FUNC_SEEK, DSK_FUNC_FAILED} DSK_FUNC;
|
||||||
|
|
||||||
|
static struct tag_dsk_action { /* stores data needed for pending IO activity */
|
||||||
|
int32 io_address;
|
||||||
|
uint32 io_filepos;
|
||||||
|
int io_nwords;
|
||||||
|
int io_sector;
|
||||||
|
} dsk_action[DSK_NUMDR];
|
||||||
|
|
||||||
/* xio_disk - XIO command interpreter for the disk drives */
|
/* xio_disk - XIO command interpreter for the disk drives */
|
||||||
/*
|
/*
|
||||||
* device status word:
|
* device status word:
|
||||||
|
@ -167,7 +180,7 @@ extern void void_backtrace (int afrom, int ato);
|
||||||
void xio_disk (int32 iocc_addr, int32 func, int32 modify, int drv)
|
void xio_disk (int32 iocc_addr, int32 func, int32 modify, int drv)
|
||||||
{
|
{
|
||||||
int i, rev, nsteps, newcyl, sec, nwords;
|
int i, rev, nsteps, newcyl, sec, nwords;
|
||||||
t_addr newpos;
|
uint32 newpos; // changed from t_addr to uint32 in anticipation of simh 64-bit development
|
||||||
char msg[80];
|
char msg[80];
|
||||||
UNIT *uptr = dsk_unit+drv;
|
UNIT *uptr = dsk_unit+drv;
|
||||||
int16 buf[DSK_NUMWD];
|
int16 buf[DSK_NUMWD];
|
||||||
|
@ -195,7 +208,7 @@ void xio_disk (int32 iocc_addr, int32 func, int32 modify, int drv)
|
||||||
|
|
||||||
nwords = M[iocc_addr++ & mem_mask]; /* get word count w/o upsetting SAR/SBR */
|
nwords = M[iocc_addr++ & mem_mask]; /* get word count w/o upsetting SAR/SBR */
|
||||||
|
|
||||||
if (nwords == 0) /* this is bad -- locks up disk controller ! */
|
if (nwords == 0) /* this is bad -- on real 1130, this locks up disk controller ! */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (! BETWEEN(nwords, 1, DSK_NUMWD)) { /* count bad */
|
if (! BETWEEN(nwords, 1, DSK_NUMWD)) { /* count bad */
|
||||||
|
@ -205,49 +218,32 @@ void xio_disk (int32 iocc_addr, int32 func, int32 modify, int drv)
|
||||||
|
|
||||||
sec = modify & 0x07; /* get sector on cylinder */
|
sec = modify & 0x07; /* get sector on cylinder */
|
||||||
|
|
||||||
if ((modify & 0x0080) == 0) { /* it's real if not a read check */
|
if ((modify & 0x0080) == 0) { /* it's a real read if it's not a read check */
|
||||||
|
// ah. We have a problem. The APL boot card counts on there being time for at least one
|
||||||
|
// more instruction to execute between the XIO read and the time the data starts loading
|
||||||
|
// into core. So, we have to defer the actual read operation a bit. Might as well wait
|
||||||
|
// until it's time to issue the operation complete interrupt. This means saving the
|
||||||
|
// IO information, then performing the actual read in dsk_svc.
|
||||||
|
|
||||||
newpos = (uptr->CYL*DSK_NUMSC*DSK_NUMSF + sec)*2*DSK_NUMWD;
|
newpos = (uptr->CYL*DSK_NUMSC*DSK_NUMSF + sec)*2*DSK_NUMWD;
|
||||||
|
|
||||||
if (MEM_MAPPED(uptr)) {
|
dsk_action[drv].io_address = iocc_addr;
|
||||||
memcpy(buf, (char *) uptr->filebuf + newpos, 2*DSK_NUMWD);
|
dsk_action[drv].io_nwords = nwords;
|
||||||
}
|
dsk_action[drv].io_sector = sec;
|
||||||
else {
|
dsk_action[drv].io_filepos = newpos;
|
||||||
if (uptr->pos != newpos || dsk_lastio[drv] != IO_READ) {
|
|
||||||
fseek(uptr->fileref, newpos, SEEK_SET);
|
|
||||||
dsk_lastio[drv] = IO_READ;
|
|
||||||
}
|
|
||||||
fxread(buf, 2, DSK_NUMWD, uptr->fileref); // read whole sector so we're in position for next read
|
|
||||||
uptr->pos = newpos + 2*DSK_NUMWD;
|
|
||||||
}
|
|
||||||
|
|
||||||
void_backtrace(iocc_addr, iocc_addr + nwords - 1); // mark prev instruction as altered
|
uptr->FUNC = DSK_FUNC_READ;
|
||||||
|
|
||||||
trace_io("* DSK%d read %d words from %d.%d (%x, %x) to M[%04x-%04x]", drv, nwords, uptr->CYL, sec, uptr->CYL*8 + sec, newpos, iocc_addr & mem_mask,
|
|
||||||
(iocc_addr + nwords - 1) & mem_mask);
|
|
||||||
|
|
||||||
// // this will help debug the monitor by letting me watch phase loading
|
|
||||||
// if (nwords >= 3)
|
|
||||||
// printf("* DSK%d XIO @ %04x read %d words from %d.%d (%x, %x) to M[%04x-%04x]\n", drv, prev_IAR, nwords, uptr->CYL, sec, uptr->CYL*8 + sec, newpos, iocc_addr & mem_mask,
|
|
||||||
// (iocc_addr + nwords - 1) & mem_mask);
|
|
||||||
|
|
||||||
i = uptr->CYL*8 + sec;
|
|
||||||
if (buf[0] != i)
|
|
||||||
printf("*DSK read bad sector#\n");
|
|
||||||
|
|
||||||
for (i = 0; i < nwords; i++)
|
|
||||||
M[(iocc_addr+i) & mem_mask] = buf[i];
|
|
||||||
|
|
||||||
#ifdef TRACE_DMS_IO
|
|
||||||
if (trace_dms)
|
|
||||||
tracesector(0, nwords, iocc_addr & mem_mask, uptr->CYL*8 + sec);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
trace_io("* DSK%d verify %d.%d (%x)", drv, uptr->CYL, sec, uptr->CYL*8 + sec);
|
trace_io("* DSK%d verify %d.%d (%x)", drv, uptr->CYL, sec, uptr->CYL*8 + sec);
|
||||||
|
|
||||||
uptr->FUNC = func;
|
if (raw_disk_debug)
|
||||||
sim_activate(uptr, dsk_rwait);
|
printf("* DSK%d verify %d.%d (%x)", drv, uptr->CYL, sec, uptr->CYL*8 + sec);
|
||||||
|
|
||||||
|
uptr->FUNC = DSK_FUNC_VERIFY;
|
||||||
|
}
|
||||||
|
|
||||||
|
sim_activate(uptr, dsk_rwait);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XIO_INITW:
|
case XIO_INITW:
|
||||||
|
@ -279,7 +275,8 @@ void xio_disk (int32 iocc_addr, int32 func, int32 modify, int drv)
|
||||||
|
|
||||||
trace_io("* DSK%d wrote %d words from M[%04x-%04x] to %d.%d (%x, %x)", drv, nwords, iocc_addr & mem_mask, (iocc_addr + nwords - 1) & mem_mask, uptr->CYL, sec, uptr->CYL*8 + sec, newpos);
|
trace_io("* DSK%d wrote %d words from M[%04x-%04x] to %d.%d (%x, %x)", drv, nwords, iocc_addr & mem_mask, (iocc_addr + nwords - 1) & mem_mask, uptr->CYL, sec, uptr->CYL*8 + sec, newpos);
|
||||||
|
|
||||||
// printf("* DSK%d XIO @ %04x wrote %d words from M[%04x-%04x] to %d.%d (%x, %x)\n", drv, prev_IAR, nwords, iocc_addr & mem_mask, (iocc_addr + nwords - 1) & mem_mask, uptr->CYL, sec, uptr->CYL*8 + sec, newpos);
|
if (raw_disk_debug)
|
||||||
|
printf("* DSK%d XIO @ %04x wrote %d words from M[%04x-%04x] to %d.%d (%x, %x)\n", drv, prev_IAR, nwords, iocc_addr & mem_mask, (iocc_addr + nwords - 1) & mem_mask, uptr->CYL, sec, uptr->CYL*8 + sec, newpos);
|
||||||
|
|
||||||
#ifdef TRACE_DMS_IO
|
#ifdef TRACE_DMS_IO
|
||||||
if (trace_dms)
|
if (trace_dms)
|
||||||
|
@ -309,7 +306,7 @@ void xio_disk (int32 iocc_addr, int32 func, int32 modify, int drv)
|
||||||
uptr->pos = newpos + 2*DSK_NUMWD;
|
uptr->pos = newpos + 2*DSK_NUMWD;
|
||||||
}
|
}
|
||||||
|
|
||||||
uptr->FUNC = func;
|
uptr->FUNC = DSK_FUNC_WRITE;
|
||||||
sim_activate(uptr, dsk_rwait);
|
sim_activate(uptr, dsk_rwait);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -332,7 +329,7 @@ void xio_disk (int32 iocc_addr, int32 func, int32 modify, int drv)
|
||||||
else if (newcyl >= DSK_NUMCY)
|
else if (newcyl >= DSK_NUMCY)
|
||||||
newcyl = DSK_NUMCY-1;
|
newcyl = DSK_NUMCY-1;
|
||||||
|
|
||||||
uptr->FUNC = func;
|
uptr->FUNC = DSK_FUNC_SEEK;
|
||||||
uptr->CYL = newcyl;
|
uptr->CYL = newcyl;
|
||||||
sim_activate(uptr, dsk_swait); /* schedule interrupt */
|
sim_activate(uptr, dsk_swait); /* schedule interrupt */
|
||||||
|
|
||||||
|
@ -371,30 +368,78 @@ static void diskfail (UNIT *uptr, int errflag)
|
||||||
{
|
{
|
||||||
sim_cancel(uptr); /* cancel any pending ops */
|
sim_cancel(uptr); /* cancel any pending ops */
|
||||||
SETBIT(uptr->flags, errflag); /* set the error flag */
|
SETBIT(uptr->flags, errflag); /* set the error flag */
|
||||||
uptr->FUNC = XIO_FAILED; /* tell svc routine why it failed */
|
uptr->FUNC = DSK_FUNC_FAILED; /* tell svc routine why it failed */
|
||||||
sim_activate(uptr, 1); /* schedule an immediate op complete interrupt */
|
sim_activate(uptr, 1); /* schedule an immediate op complete interrupt */
|
||||||
}
|
}
|
||||||
|
|
||||||
t_stat dsk_svc (UNIT *uptr)
|
t_stat dsk_svc (UNIT *uptr)
|
||||||
{
|
{
|
||||||
int drv = uptr - dsk_unit;
|
int drv = uptr - dsk_unit, i, nwords, sec;
|
||||||
|
int16 buf[DSK_NUMWD];
|
||||||
|
uint32 newpos; // changed from t_addr to uint32 in anticipation of simh 64-bit development
|
||||||
|
int32 iocc_addr;
|
||||||
|
|
||||||
CLRBIT(dsk_dsw[drv], DSK_DSW_DISK_BUSY); /* activate operation complete interrupt */
|
if (uptr->FUNC == DSK_FUNC_IDLE) /* service function called with no activity? not good, but ignore */
|
||||||
|
return SCPE_OK;
|
||||||
|
|
||||||
|
CLRBIT(dsk_dsw[drv], DSK_DSW_DISK_BUSY); /* activate operation complete interrupt */
|
||||||
SETBIT(dsk_dsw[drv], DSK_DSW_OP_COMPLETE);
|
SETBIT(dsk_dsw[drv], DSK_DSW_OP_COMPLETE);
|
||||||
|
|
||||||
if (uptr->flags & (UNIT_OPERR|UNIT_HARDERR)) { /* word count error or data error */
|
if (uptr->flags & (UNIT_OPERR|UNIT_HARDERR)) { /* word count error or data error */
|
||||||
SETBIT(dsk_dsw[drv], DSK_DSW_DATA_ERROR);
|
SETBIT(dsk_dsw[drv], DSK_DSW_DATA_ERROR);
|
||||||
CLRBIT(uptr->flags, UNIT_OPERR); /* but don't clear hard error */
|
CLRBIT(uptr->flags, UNIT_OPERR); /* soft error is one time occurrence; don't clear hard error */
|
||||||
}
|
}
|
||||||
|
/* schedule interrupt */
|
||||||
SETBIT(ILSW[dsk_ilswlevel[drv]], dsk_ilswbit[drv]);
|
SETBIT(ILSW[dsk_ilswlevel[drv]], dsk_ilswbit[drv]);
|
||||||
|
|
||||||
#ifdef XXXX
|
switch (uptr->FUNC) { /* take care of business */
|
||||||
switch (uptr->FUNC) {
|
case DSK_FUNC_IDLE:
|
||||||
case XIO_CONTROL:
|
case DSK_FUNC_VERIFY:
|
||||||
case XIO_INITR:
|
case DSK_FUNC_WRITE:
|
||||||
case XIO_INITW:
|
case DSK_FUNC_SEEK:
|
||||||
case XIO_FAILED:
|
case DSK_FUNC_FAILED:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DSK_FUNC_READ: /* actually read the data into core */
|
||||||
|
iocc_addr = dsk_action[drv].io_address; /* recover saved parameters */
|
||||||
|
nwords = dsk_action[drv].io_nwords;
|
||||||
|
newpos = dsk_action[drv].io_filepos;
|
||||||
|
sec = dsk_action[drv].io_sector;
|
||||||
|
|
||||||
|
if (MEM_MAPPED(uptr)) {
|
||||||
|
memcpy(buf, (char *) uptr->filebuf + newpos, 2*DSK_NUMWD);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (uptr->pos != newpos || dsk_lastio[drv] != IO_READ) {
|
||||||
|
fseek(uptr->fileref, newpos, SEEK_SET);
|
||||||
|
dsk_lastio[drv] = IO_READ;
|
||||||
|
uptr->pos = newpos;
|
||||||
|
}
|
||||||
|
fxread(buf, 2, DSK_NUMWD, uptr->fileref); // read whole sector so we're in position for next read
|
||||||
|
uptr->pos = newpos + 2*DSK_NUMWD;
|
||||||
|
}
|
||||||
|
|
||||||
|
void_backtrace(iocc_addr, iocc_addr + nwords - 1); // mark prev instruction as altered
|
||||||
|
|
||||||
|
trace_io("* DSK%d read %d words from %d.%d (%x, %x) to M[%04x-%04x]", drv, nwords, uptr->CYL, sec, uptr->CYL*8 + sec, newpos, iocc_addr & mem_mask,
|
||||||
|
(iocc_addr + nwords - 1) & mem_mask);
|
||||||
|
|
||||||
|
// // this will help debug the monitor by letting me watch phase loading
|
||||||
|
if (raw_disk_debug)
|
||||||
|
printf("* DSK%d XIO @ %04x read %d words from %d.%d (%x, %x) to M[%04x-%04x]\n", drv, prev_IAR, nwords, uptr->CYL, sec, uptr->CYL*8 + sec, newpos, iocc_addr & mem_mask,
|
||||||
|
(iocc_addr + nwords - 1) & mem_mask);
|
||||||
|
|
||||||
|
i = uptr->CYL*8 + sec;
|
||||||
|
if (buf[0] != i)
|
||||||
|
printf("*DSK read bad sector #\n");
|
||||||
|
|
||||||
|
for (i = 0; i < nwords; i++)
|
||||||
|
M[(iocc_addr+i) & mem_mask] = buf[i];
|
||||||
|
|
||||||
|
#ifdef TRACE_DMS_IO
|
||||||
|
if (trace_dms)
|
||||||
|
tracesector(0, nwords, iocc_addr & mem_mask, uptr->CYL*8 + sec);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -402,8 +447,8 @@ t_stat dsk_svc (UNIT *uptr)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
uptr->FUNC = -1; // we're done with this operation
|
|
||||||
#endif
|
uptr->FUNC = DSK_FUNC_IDLE; // we're done with this operation
|
||||||
|
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
@ -428,7 +473,7 @@ t_stat dsk_reset (DEVICE *dptr)
|
||||||
CLRBIT(uptr->flags, UNIT_OPERR|UNIT_HARDERR);
|
CLRBIT(uptr->flags, UNIT_OPERR|UNIT_HARDERR);
|
||||||
|
|
||||||
uptr->CYL = 0;
|
uptr->CYL = 0;
|
||||||
uptr->FUNC = -1;
|
uptr->FUNC = DSK_FUNC_IDLE;
|
||||||
dsk_dsw[drv] = (uptr->flags & UNIT_ATT) ? DSK_DSW_CARRIAGE_HOME : 0;
|
dsk_dsw[drv] = (uptr->flags & UNIT_ATT) ? DSK_DSW_CARRIAGE_HOME : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -450,7 +495,7 @@ static t_stat dsk_attach (UNIT *uptr, char *cptr)
|
||||||
return rval;
|
return rval;
|
||||||
|
|
||||||
uptr->CYL = 0; // reset the device
|
uptr->CYL = 0; // reset the device
|
||||||
uptr->FUNC = -1;
|
uptr->FUNC = DSK_FUNC_IDLE;
|
||||||
dsk_dsw[drv] = DSK_DSW_CARRIAGE_HOME;
|
dsk_dsw[drv] = DSK_DSW_CARRIAGE_HOME;
|
||||||
|
|
||||||
CLRBIT(uptr->flags, UNIT_RO|UNIT_ROABLE|UNIT_BUFABLE|UNIT_BUF|UNIT_RONLY|UNIT_OPERR|UNIT_HARDERR);
|
CLRBIT(uptr->flags, UNIT_RO|UNIT_ROABLE|UNIT_BUFABLE|UNIT_BUF|UNIT_RONLY|UNIT_OPERR|UNIT_HARDERR);
|
||||||
|
@ -479,6 +524,7 @@ static t_stat dsk_attach (UNIT *uptr, char *cptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
enable_dms_tracing(sim_switches & SWMASK('D'));
|
enable_dms_tracing(sim_switches & SWMASK('D'));
|
||||||
|
raw_disk_debug = sim_switches & SWMASK('G');
|
||||||
|
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
@ -498,7 +544,7 @@ static t_stat dsk_detach (UNIT *uptr)
|
||||||
calc_ints();
|
calc_ints();
|
||||||
|
|
||||||
uptr->CYL = 0;
|
uptr->CYL = 0;
|
||||||
uptr->FUNC = -1;
|
uptr->FUNC = DSK_FUNC_IDLE;
|
||||||
dsk_dsw[drv] = DSK_DSW_NOT_READY;
|
dsk_dsw[drv] = DSK_DSW_NOT_READY;
|
||||||
|
|
||||||
if (drv == 0) {
|
if (drv == 0) {
|
||||||
|
@ -518,7 +564,7 @@ static t_stat dsk_boot (int unitno, DEVICE *dptr)
|
||||||
if ((rval = reset_all(0)) != SCPE_OK)
|
if ((rval = reset_all(0)) != SCPE_OK)
|
||||||
return rval;
|
return rval;
|
||||||
|
|
||||||
return load_cr_boot(unitno);
|
return load_cr_boot(unitno, sim_switches);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TRACE_DMS_IO
|
#ifdef TRACE_DMS_IO
|
||||||
|
|
303
Ibm1130/ibm1130_fmt.c
Normal file
303
Ibm1130/ibm1130_fmt.c
Normal file
|
@ -0,0 +1,303 @@
|
||||||
|
// ibm1130_fmt.c : interpret tabs in 1130 Assembler or Fortran source
|
||||||
|
// Bob Flanders
|
||||||
|
// -------------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// These routines are used by ibm1130_cr.c when the user has indicated
|
||||||
|
// that the input text is formatted with tabs. Input lines are edited
|
||||||
|
// into the appropriate column format. Three edit modes are recognized:
|
||||||
|
//
|
||||||
|
// Assembler mode:
|
||||||
|
// Input lines of the form
|
||||||
|
//
|
||||||
|
// [label]<whitespace>[opcode]<tab>[tag][L]<tab>[argument]
|
||||||
|
//
|
||||||
|
// are rearranged so that the input fields are placed in the appropriate columns
|
||||||
|
//
|
||||||
|
// The label must start on the first character of the line. If there is no label,
|
||||||
|
// the first character(s) before the opcode must be whitespace. Following the opcode, there
|
||||||
|
// MUST be a tab character, followed by the format and tag. Following the format and tag
|
||||||
|
// may be exactly one whitespace character, and then starts the argument.
|
||||||
|
//
|
||||||
|
// Input lines with * in column 1 and blank lines are turned into Assembler comments,
|
||||||
|
// with the * in the Opcode field.
|
||||||
|
//
|
||||||
|
// Assembler directive lines at the beginning of the deck must be preceded by
|
||||||
|
// ! to indicate that they are not comments. For example,
|
||||||
|
//
|
||||||
|
// !*LIST
|
||||||
|
// * This is a comment
|
||||||
|
//
|
||||||
|
// Fortran mode:
|
||||||
|
// Input lines of the form
|
||||||
|
//
|
||||||
|
// [label]<tab>statement
|
||||||
|
//
|
||||||
|
// or
|
||||||
|
//
|
||||||
|
// [label]<tab>Xcontinuation
|
||||||
|
//
|
||||||
|
// where X is a non alphabetic contination character are rearranged in the
|
||||||
|
// appropriate manner:
|
||||||
|
//
|
||||||
|
// 1 2
|
||||||
|
// 12345678901234567890...
|
||||||
|
// ------------------------
|
||||||
|
// label statement
|
||||||
|
// labelXcontinuation
|
||||||
|
//
|
||||||
|
// However, you must take care that you don't end up with statement text after column 72.
|
||||||
|
//
|
||||||
|
// Input lines with * or C in column 1 are left alone (comments and directives)
|
||||||
|
//
|
||||||
|
// (The ! escape is not used before Fortran directives as before Assembler directives)
|
||||||
|
//
|
||||||
|
// Tab mode:
|
||||||
|
// Tabs are replaced with spaces. Tab settings are assumed to be eight characters wide,
|
||||||
|
// as is standard for vi, notepad, etc.
|
||||||
|
// -------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <memory.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "ibm1130_fmt.h"
|
||||||
|
|
||||||
|
#define MAXLINE 81 // maximum output line size
|
||||||
|
#define WORKSZ 256 // size for tab work area
|
||||||
|
#define TAGOFFSET 12 // offset for tag field
|
||||||
|
#define FMTOFFSET 11 // offset for format field
|
||||||
|
|
||||||
|
#define MIN(a,b) ((a < b) ? a : b)
|
||||||
|
#define AMSG " with Assembler Reformat"
|
||||||
|
#define FMSG " with FORTRAN Reformat"
|
||||||
|
#define AFORMAT "%20.20s%-60.60s"," "
|
||||||
|
#define ACOMMENTFMT "%20.20s%-60.60s"," "
|
||||||
|
#define ABLANKLINE "%20.20s*"," "
|
||||||
|
#define FFORMAT "%-5.5s %-74.74s"
|
||||||
|
#define FCONTFMT "%-5.5s%-75.75s"
|
||||||
|
|
||||||
|
char gszLabel[6]; // work area for label
|
||||||
|
char gszArg[MAXLINE]; // .. argument
|
||||||
|
char gszOutput[MAXLINE]; // .. output
|
||||||
|
short gaiAsmTabs[] = {7,12,15,20,25,30,35,40,45,52,0};// tab stops for assembler
|
||||||
|
|
||||||
|
short gaiPlainTabs[] = {9, 17, 25, 33, 41, 49, 57, 65, 73, 0};// tab stops for just plain tabs
|
||||||
|
|
||||||
|
// ///////////////
|
||||||
|
// helper routines
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////
|
||||||
|
// ExpandTabs: Expand tabs to spaces
|
||||||
|
|
||||||
|
char* ExpandTabs(char* p_szInbuf, // expand tabs .. input buffer
|
||||||
|
char* p_szOutbuf, // .. output buffer
|
||||||
|
short* p_aiTabs) // .. array of tab stops (1 based) -- 0 end of array
|
||||||
|
{
|
||||||
|
short iI, // input position
|
||||||
|
iO, // output position
|
||||||
|
iT; // next tab stop
|
||||||
|
|
||||||
|
char cX; // character to test
|
||||||
|
|
||||||
|
iI = 0; // init input position
|
||||||
|
iO = 0; // init output position
|
||||||
|
iT = 0; // init tab stop
|
||||||
|
|
||||||
|
while (cX = *(p_szInbuf + iI)) // while there are characters
|
||||||
|
{
|
||||||
|
if (cX == '\t') // q. tab character?
|
||||||
|
{ // a. yes ..
|
||||||
|
while ((p_aiTabs[iT] <= iO + 1) // search for next valid stop ..
|
||||||
|
&& (p_aiTabs[iT] != 0)) // .. or end of table
|
||||||
|
iT++; // .. go to next tab
|
||||||
|
|
||||||
|
if (p_aiTabs[iT] != 0) // q. end of tab array?
|
||||||
|
{ // a. no ..
|
||||||
|
while (iO < (p_aiTabs[iT] - 1)) // fill to tab with blanks
|
||||||
|
*(p_szOutbuf + iO++) = ' '; // .. put in a blank
|
||||||
|
|
||||||
|
}
|
||||||
|
else // Otherwise ...
|
||||||
|
*(p_szOutbuf + iO++) = ' '; // .. Translate to blank
|
||||||
|
}
|
||||||
|
else // Otherwise .. not tab
|
||||||
|
*(p_szOutbuf + iO++) = cX; // .. save the input char
|
||||||
|
|
||||||
|
iI++; // next input character
|
||||||
|
}
|
||||||
|
|
||||||
|
*(p_szOutbuf + iO) = 0; // end the string..
|
||||||
|
return p_szOutbuf; // .. return output area addr
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
// extract next token, modify pointer
|
||||||
|
|
||||||
|
char* GetToken(char* p_szOut, // output location
|
||||||
|
int p_iLen, // max output length
|
||||||
|
char**p_pszToken) // pointer to input token
|
||||||
|
{
|
||||||
|
int iI; // work integer
|
||||||
|
char* pszX; // work pointer
|
||||||
|
|
||||||
|
pszX = *p_pszToken; // get pointer to token
|
||||||
|
|
||||||
|
for (iI = 0; *(pszX + iI) && (!isspace(*(pszX + iI)));) // while not whitespace & not end
|
||||||
|
iI++; // .. count token length
|
||||||
|
|
||||||
|
memset(p_szOut, 0, p_iLen); // zero out output area
|
||||||
|
|
||||||
|
if (iI > 0) // q. any chars?
|
||||||
|
strncpy(p_szOut, *p_pszToken, MIN(iI, p_iLen-1)); // a. yes.. copy max of p_iLen-1
|
||||||
|
|
||||||
|
*p_pszToken += iI; // point beyond token
|
||||||
|
return p_szOut; // .. return token pointer
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////
|
||||||
|
// EditToAsm - convert tab-formatted text line to 1130 Assembler format
|
||||||
|
|
||||||
|
char *EditToAsm (char* p_pszEdit) // convert line to 1130 assembler
|
||||||
|
{
|
||||||
|
char pszLine[MAXLINE]; // source line
|
||||||
|
char pszWork[WORKSZ]; // work buffer
|
||||||
|
char acTFWrk[2]; // tag/format work area
|
||||||
|
size_t iI; // work integer
|
||||||
|
|
||||||
|
if (p_pszEdit == NULL) // q. null request?
|
||||||
|
return AMSG; // a. yes .. return display message
|
||||||
|
|
||||||
|
if (*p_pszEdit == '!') // leave lines starting with ! alone
|
||||||
|
return EditToWhitespace(p_pszEdit+1);
|
||||||
|
|
||||||
|
if (*p_pszEdit == '*') // q. comment line?
|
||||||
|
{ // a. yes..
|
||||||
|
strncpy(pszWork, EditToWhitespace(p_pszEdit), MAXLINE); // .. convert any tabs
|
||||||
|
sprintf(gszOutput, ACOMMENTFMT, pszWork); // .. put the comment out there in the opcode column
|
||||||
|
return gszOutput; // .. and return it
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(pszLine, p_pszEdit, MAXLINE-1); // copy the line local
|
||||||
|
|
||||||
|
ExpandTabs(pszLine, pszWork, gaiAsmTabs); // expand the tabs
|
||||||
|
strncpy(pszLine, pszWork, MAXLINE-1); // copy the line back
|
||||||
|
|
||||||
|
for (iI = strlen(pszLine); iI--;) // trim trailing whitespace
|
||||||
|
{
|
||||||
|
if (*(pszLine + iI) <= ' ') // q. space or less?
|
||||||
|
*(pszLine + iI) = 0; // a. yes .. remove it
|
||||||
|
else // otherwise
|
||||||
|
break; // .. done. Leave loop.
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(pszLine) == 0) // q. blank line?
|
||||||
|
{ // a. yes .. Assembler abhors these so
|
||||||
|
sprintf(gszOutput, ABLANKLINE); // format as comment statement
|
||||||
|
return gszOutput; // .. and return it
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: Add code to process a strip switch
|
||||||
|
// comment?
|
||||||
|
|
||||||
|
if (strlen(pszLine) > (TAGOFFSET + 1)) // q. line long enough?
|
||||||
|
{ // a. yes.. reorder tag/format
|
||||||
|
memcpy(acTFWrk, pszLine + FMTOFFSET, 2); // get tag/format
|
||||||
|
memset((pszLine + FMTOFFSET), ' ', 2); // .. blank 'em out
|
||||||
|
|
||||||
|
for (iI = 0; iI < 2; iI ++)
|
||||||
|
if (isalpha(acTFWrk[iI])) // q. alpha char?
|
||||||
|
*(pszLine + FMTOFFSET) = acTFWrk[iI]; // a. yes .. make it format
|
||||||
|
else if (isdigit(acTFWrk[iI])) // q. digit?
|
||||||
|
*(pszLine + TAGOFFSET) = acTFWrk[iI]; // a. yes .. make it the tag
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(gszOutput, AFORMAT, pszLine); // format the line
|
||||||
|
|
||||||
|
return gszOutput; // return formatted line
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////
|
||||||
|
// EditToFortran - convert tab-formatted input text line to FORTRAN format
|
||||||
|
// (a la DEC Fortran)
|
||||||
|
|
||||||
|
char *EditToFortran(char* p_pszEdit) // convert line to 1130 assembler
|
||||||
|
{
|
||||||
|
char pszLine[MAXLINE]; // source line
|
||||||
|
char* pszWork; // work pointer
|
||||||
|
size_t iI; // work integer
|
||||||
|
char bContinue; // true if continue
|
||||||
|
|
||||||
|
if (p_pszEdit == NULL) // q. null request?
|
||||||
|
return FMSG; // a. yes .. return display message
|
||||||
|
|
||||||
|
if (strchr(p_pszEdit, '\t') == NULL) // q. no tab in the line?
|
||||||
|
return p_pszEdit; // a. nope, return line as is, assume it's formatted correctly
|
||||||
|
|
||||||
|
if (*p_pszEdit == 'C' || *p_pszEdit == '*' || *p_pszEdit == '\0') // q. comment or directive or blank line?
|
||||||
|
{ // a. yes.. don't restructure
|
||||||
|
return EditToWhitespace(p_pszEdit);
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(pszLine, p_pszEdit, MAXLINE-1); // copy the line local
|
||||||
|
|
||||||
|
for (iI = strlen(pszLine); iI--;) // trim trailing whitespace
|
||||||
|
{
|
||||||
|
if (*(pszLine + iI) <= ' ') // q. space or less?
|
||||||
|
*(pszLine + iI) = 0; // a. yes .. remove it
|
||||||
|
else // otherwise
|
||||||
|
break; // .. done. Leave loop.
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Add code to process a strip switch
|
||||||
|
// comment?
|
||||||
|
|
||||||
|
pszWork = (char*) pszLine; // set pointer to line
|
||||||
|
GetToken(gszLabel, 6, &pszWork); // get the line, if any.
|
||||||
|
|
||||||
|
pszWork++; // skip tab/whitespace
|
||||||
|
|
||||||
|
// continuation...
|
||||||
|
bContinue = ((isdigit(*pszWork) && (*pszWork != '0')) // if first char non-zero digit
|
||||||
|
|| (!isspace(*pszWork) && !isalpha(*pszWork))); // .. or non-alpha non-blank
|
||||||
|
|
||||||
|
memset(gszArg, 0, MAXLINE); // .. and arguments
|
||||||
|
|
||||||
|
strncpy(gszArg, pszWork, 75); // copy rest to argument
|
||||||
|
|
||||||
|
sprintf(gszOutput, (bContinue) ? FCONTFMT : FFORMAT, // format the line
|
||||||
|
gszLabel, // .. statement #
|
||||||
|
gszArg); // .. code
|
||||||
|
|
||||||
|
return gszOutput; // return formatted line
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////
|
||||||
|
// EditToWhitespace - expand tabs at 8 space intervals.
|
||||||
|
|
||||||
|
char* EditToWhitespace(char *p_pszEdit)
|
||||||
|
{
|
||||||
|
int iI; /* work integer */
|
||||||
|
char pszLine[MAXLINE]; // source line
|
||||||
|
char pszWork[WORKSZ]; // work buffer
|
||||||
|
|
||||||
|
if (p_pszEdit == NULL) // q. null request?
|
||||||
|
return AMSG; // a. yes .. return display message
|
||||||
|
|
||||||
|
strncpy(pszLine, p_pszEdit, MAXLINE-1); // copy the line local
|
||||||
|
|
||||||
|
ExpandTabs(pszLine, pszWork, gaiPlainTabs); // expand the tabs
|
||||||
|
strncpy(gszOutput, pszWork, MAXLINE-1); // copy the line back
|
||||||
|
|
||||||
|
for (iI = strlen(gszOutput); iI--;) // look at each character
|
||||||
|
{
|
||||||
|
if (*(gszOutput + iI) <= ' ') // q. space or less?
|
||||||
|
*(gszOutput + iI) = 0; // a. yes .. remove it
|
||||||
|
else // otherwise
|
||||||
|
break; // .. done. Leave loop.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return gszOutput; /* ... return buffer */
|
||||||
|
}
|
17
Ibm1130/ibm1130_fmt.h
Normal file
17
Ibm1130/ibm1130_fmt.h
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
/*
|
||||||
|
* (C) Copyright 2003, Bob Flander.
|
||||||
|
* You may freely use this program, but: it offered strictly on an AS-IS, AT YOUR OWN
|
||||||
|
* RISK basis, there is no warranty of fitness for any purpose, and the rest of the
|
||||||
|
* usual yada-yada. Please keep this notice and the copyright in any distributions
|
||||||
|
* or modifications.
|
||||||
|
*
|
||||||
|
* This is not a supported product, but I welcome bug reports and fixes.
|
||||||
|
* Mail to bob@jftr.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ibm1130_asm.h: definition of routines in ibm1130_asm.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
char* EditToAsm(char*); // convert edit format to 1130 assembler format
|
||||||
|
char* EditToFortran(char*); // convert edit format to Fortran format
|
||||||
|
char* EditToWhitespace(char*); // clean white space, tabstops every 8 positions
|
|
@ -18,7 +18,7 @@
|
||||||
* or modifications.
|
* or modifications.
|
||||||
*
|
*
|
||||||
* This is not a supported product, but I welcome bug reports and fixes.
|
* This is not a supported product, but I welcome bug reports and fixes.
|
||||||
* Mail to sim@ibm1130.org
|
* Mail to simh@ibm1130.org
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define BLIT_MODE // normally defined, undefine when debugging generate_image()
|
#define BLIT_MODE // normally defined, undefine when debugging generate_image()
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
* or modifications.
|
* or modifications.
|
||||||
*
|
*
|
||||||
* This is not a supported product, but I welcome bug reports and fixes.
|
* This is not a supported product, but I welcome bug reports and fixes.
|
||||||
* Mail to sim@ibm1130.org
|
* Mail to simh@ibm1130.org
|
||||||
*
|
*
|
||||||
* 17-May-02 BLK Pulled out of ibm1130_cpu.c
|
* 17-May-02 BLK Pulled out of ibm1130_cpu.c
|
||||||
*/
|
*/
|
||||||
|
@ -168,30 +168,30 @@ static int bmwid, bmht;
|
||||||
static struct tag_btn {
|
static struct tag_btn {
|
||||||
int x, y;
|
int x, y;
|
||||||
char *txt;
|
char *txt;
|
||||||
BOOL pushable;
|
BOOL pushable, state;
|
||||||
COLORREF clr;
|
COLORREF clr;
|
||||||
HBRUSH hbrLit, hbrDark;
|
HBRUSH hbrLit, hbrDark;
|
||||||
HWND hBtn;
|
HWND hBtn;
|
||||||
} btn[] = {
|
} btn[] = {
|
||||||
0, 0, "KEYBOARD\nSELECT", FALSE, RGB(255,255,180), NULL, NULL, NULL,
|
0, 0, "KEYBOARD\nSELECT", FALSE, FALSE, RGB(255,255,180), NULL, NULL, NULL,
|
||||||
0, 1, "DISK\nUNLOCK", FALSE, RGB(255,255,180), NULL, NULL, NULL,
|
0, 1, "DISK\nUNLOCK", FALSE, TRUE, RGB(255,255,180), NULL, NULL, NULL,
|
||||||
0, 2, "RUN", FALSE, RGB(0,255,0), NULL, NULL, NULL,
|
0, 2, "RUN", FALSE, FALSE, RGB(0,255,0), NULL, NULL, NULL,
|
||||||
0, 3, "PARITY\nCHECK", FALSE, RGB(255,0,0), NULL, NULL, NULL,
|
0, 3, "PARITY\nCHECK", FALSE, FALSE, RGB(255,0,0), NULL, NULL, NULL,
|
||||||
|
|
||||||
1, 0, "", FALSE, RGB(255,255,180), NULL, NULL, NULL,
|
1, 0, "", FALSE, FALSE, RGB(255,255,180), NULL, NULL, NULL,
|
||||||
1, 1, "FILE\nREADY", FALSE, RGB(0,255,0), NULL, NULL, NULL,
|
1, 1, "FILE\nREADY", FALSE, FALSE, RGB(0,255,0), NULL, NULL, NULL,
|
||||||
1, 2, "FORMS\nCHECK", FALSE, RGB(255,255,0), NULL, NULL, NULL,
|
1, 2, "FORMS\nCHECK", FALSE, FALSE, RGB(255,255,0), NULL, NULL, NULL,
|
||||||
1, 3, "POWER\nON", FALSE, RGB(255,255,180), NULL, NULL, NULL,
|
1, 3, "POWER\nON", FALSE, TRUE, RGB(255,255,180), NULL, NULL, NULL,
|
||||||
|
|
||||||
2, 0, "POWER", TRUE, RGB(255,255,180), NULL, NULL, NULL,
|
2, 0, "POWER", TRUE, FALSE, RGB(255,255,180), NULL, NULL, NULL,
|
||||||
2, 1, "PROGRAM\nSTART", TRUE, RGB(0,255,0), NULL, NULL, NULL,
|
2, 1, "PROGRAM\nSTART", TRUE, FALSE, RGB(0,255,0), NULL, NULL, NULL,
|
||||||
2, 2, "PROGRAM\nSTOP", TRUE, RGB(255,0,0), NULL, NULL, NULL,
|
2, 2, "PROGRAM\nSTOP", TRUE, FALSE, RGB(255,0,0), NULL, NULL, NULL,
|
||||||
2, 3, "LOAD\nIAR", TRUE, RGB(0,0,255), NULL, NULL, NULL,
|
2, 3, "LOAD\nIAR", TRUE, FALSE, RGB(0,0,255), NULL, NULL, NULL,
|
||||||
|
|
||||||
3, 0, "KEYBOARD", TRUE, RGB(255,255,180), NULL, NULL, NULL,
|
3, 0, "KEYBOARD", TRUE, FALSE, RGB(255,255,180), NULL, NULL, NULL,
|
||||||
3, 1, "IMM\nSTOP", TRUE, RGB(255,0,0), NULL, NULL, NULL,
|
3, 1, "IMM\nSTOP", TRUE, FALSE, RGB(255,0,0), NULL, NULL, NULL,
|
||||||
3, 2, "CHECK\nRESET", TRUE, RGB(0,0,255), NULL, NULL, NULL,
|
3, 2, "CHECK\nRESET", TRUE, FALSE, RGB(0,0,255), NULL, NULL, NULL,
|
||||||
3, 3, "PROGRAM\nLOAD", TRUE, RGB(0,0,255), NULL, NULL, NULL,
|
3, 3, "PROGRAM\nLOAD", TRUE, FALSE, RGB(0,0,255), NULL, NULL, NULL,
|
||||||
};
|
};
|
||||||
#define NBUTTONS (sizeof(btn) / sizeof(btn[0]))
|
#define NBUTTONS (sizeof(btn) / sizeof(btn[0]))
|
||||||
|
|
||||||
|
@ -318,7 +318,8 @@ static void RepaintRegion (HWND hWnd, int left, int top, int right, int bottom)
|
||||||
|
|
||||||
void update_gui (BOOL force)
|
void update_gui (BOOL force)
|
||||||
{
|
{
|
||||||
int i, sts;
|
int i;
|
||||||
|
BOOL state;
|
||||||
static int in_here = FALSE;
|
static int in_here = FALSE;
|
||||||
static int32 displayed = 0;
|
static int32 displayed = 0;
|
||||||
|
|
||||||
|
@ -385,25 +386,33 @@ void update_gui (BOOL force)
|
||||||
|
|
||||||
int_lamps = 0;
|
int_lamps = 0;
|
||||||
|
|
||||||
|
// this loop works with lamp buttons that are calculated on-the-fly only
|
||||||
for (i = 0; i < NBUTTONS; i++) {
|
for (i = 0; i < NBUTTONS; i++) {
|
||||||
if (btn[i].pushable)
|
if (btn[i].pushable)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case IDC_RUN: sts = hFlashTimer || (running && ! wait_state); break;
|
case IDC_RUN:
|
||||||
// case IDC_PARITY_CHECK: sts = FALSE; break;
|
state = hFlashTimer || (running && ! wait_state);
|
||||||
// case IDC_POWER_ON: sts = TRUE; break;
|
break;
|
||||||
default:
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// case IDC_FILE_READY: these windows are enabled&disabled directly
|
// this button is always off
|
||||||
|
// case IDC_PARITY_CHECK:
|
||||||
|
|
||||||
|
// these buttons are enabled/disabled directly
|
||||||
|
// case IDC_POWER_ON:
|
||||||
|
// case IDC_FILE_READY:
|
||||||
// case IDC_FORMS_CHECK:
|
// case IDC_FORMS_CHECK:
|
||||||
// case IDC_KEYBOARD_SELECT:
|
// case IDC_KEYBOARD_SELECT:
|
||||||
// case IDC_DISK_UNLOCK:
|
// case IDC_DISK_UNLOCK:
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sts != IsWindowEnabled(btn[i].hBtn)) // status has changed
|
if (state != btn[i].state) { // state has changed
|
||||||
EnableWindow(btn[i].hBtn, sts);
|
EnableWindow(btn[i].hBtn, state);
|
||||||
|
btn[i].state = state;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
in_here = FALSE;
|
in_here = FALSE;
|
||||||
|
@ -423,6 +432,7 @@ LRESULT CALLBACK ButtonProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
if (! btn[i].pushable) {
|
if (! btn[i].pushable) {
|
||||||
if (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP || uMsg == WM_LBUTTONDBLCLK)
|
if (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP || uMsg == WM_LBUTTONDBLCLK)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (uMsg == WM_CHAR)
|
if (uMsg == WM_CHAR)
|
||||||
if ((TCHAR) wParam == ' ')
|
if ((TCHAR) wParam == ' ')
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -622,9 +632,9 @@ static DWORD WINAPI Pump (LPVOID arg)
|
||||||
class_defined = TRUE;
|
class_defined = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
hbWhite = GetStockObject(WHITE_BRUSH); /* create or fetch useful GDI objects */
|
hbWhite = GetStockObject(WHITE_BRUSH); /* create or fetch useful GDI objects */
|
||||||
hbBlack = GetStockObject(BLACK_BRUSH); /* create or fetch useful GDI objects */
|
hbBlack = GetStockObject(BLACK_BRUSH); /* create or fetch useful GDI objects */
|
||||||
hbGray = GetStockObject(GRAY_BRUSH);
|
hbGray = GetStockObject(GRAY_BRUSH);
|
||||||
hSwitchPen = CreatePen(PS_SOLID, 5, RGB(255,255,255));
|
hSwitchPen = CreatePen(PS_SOLID, 5, RGB(255,255,255));
|
||||||
|
|
||||||
hWhitePen = GetStockObject(WHITE_PEN);
|
hWhitePen = GetStockObject(WHITE_PEN);
|
||||||
|
@ -633,8 +643,8 @@ static DWORD WINAPI Pump (LPVOID arg)
|
||||||
hGreyPen = CreatePen(PS_SOLID, 1, RGB(128,128,128));
|
hGreyPen = CreatePen(PS_SOLID, 1, RGB(128,128,128));
|
||||||
hDkGreyPen = CreatePen(PS_SOLID, 1, RGB(64,64,64));
|
hDkGreyPen = CreatePen(PS_SOLID, 1, RGB(64,64,64));
|
||||||
|
|
||||||
hcArrow = LoadCursor(NULL, IDC_ARROW);
|
hcArrow = LoadCursor(NULL, IDC_ARROW);
|
||||||
hcHand = LoadCursor(hInstance, MAKEINTRESOURCE(IDC_HAND));
|
hcHand = LoadCursor(hInstance, MAKEINTRESOURCE(IDC_HAND));
|
||||||
|
|
||||||
if (hBitmap == NULL)
|
if (hBitmap == NULL)
|
||||||
hBitmap = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_CONSOLE));
|
hBitmap = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_CONSOLE));
|
||||||
|
@ -656,11 +666,12 @@ static DWORD WINAPI Pump (LPVOID arg)
|
||||||
bmwid = bm.bmWidth;
|
bmwid = bm.bmWidth;
|
||||||
bmht = bm.bmHeight;
|
bmht = bm.bmHeight;
|
||||||
|
|
||||||
for (i = 0; i < NBUTTONS; i++)
|
for (i = 0; i < NBUTTONS; i++) {
|
||||||
CreateSubclassedButton(hConsoleWnd, i);
|
CreateSubclassedButton(hConsoleWnd, i);
|
||||||
|
|
||||||
EnableWindow(btn[IDC_POWER_ON].hBtn, TRUE);
|
if (! btn[i].pushable)
|
||||||
EnableWindow(btn[IDC_DISK_UNLOCK].hBtn, TRUE);
|
EnableWindow(btn[i].hBtn, btn[i].state);
|
||||||
|
}
|
||||||
|
|
||||||
GetWindowRect(hConsoleWnd, &r); /* get window size as created */
|
GetWindowRect(hConsoleWnd, &r); /* get window size as created */
|
||||||
wx = r.right - r.left + 1;
|
wx = r.right - r.left + 1;
|
||||||
|
@ -913,12 +924,19 @@ void HandleCommand (HWND hWnd, WPARAM wParam, LPARAM lParam)
|
||||||
reset_all(0);
|
reset_all(0);
|
||||||
if (running && ! power) { /* turning off */
|
if (running && ! power) { /* turning off */
|
||||||
reason = STOP_POWER_OFF;
|
reason = STOP_POWER_OFF;
|
||||||
while (running)
|
// this prevents message pump from running, which unfortunately locks up
|
||||||
Sleep(10); /* wait for execution thread to exit */
|
// the emulator thread when it calls gui_run(FALSE) which calls EnableWindow on the Run lamp
|
||||||
|
// while (running)
|
||||||
|
// Sleep(10); /* wait for execution thread to exit */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
btn[IDC_POWER_ON].state = power;
|
||||||
EnableWindow(btn[IDC_POWER_ON].hBtn, power);
|
EnableWindow(btn[IDC_POWER_ON].hBtn, power);
|
||||||
for (i = 0; i < NBUTTONS; i++)
|
|
||||||
InvalidateRect(btn[i].hBtn, NULL, TRUE);
|
for (i = 0; i < NBUTTONS; i++) /* repaint all of the lamps */
|
||||||
|
if (! btn[i].pushable)
|
||||||
|
InvalidateRect(btn[i].hBtn, NULL, TRUE);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IDC_PROGRAM_START: /* begin execution */
|
case IDC_PROGRAM_START: /* begin execution */
|
||||||
|
@ -967,8 +985,11 @@ void HandleCommand (HWND hWnd, WPARAM wParam, LPARAM lParam)
|
||||||
case IDC_IMM_STOP:
|
case IDC_IMM_STOP:
|
||||||
if (running) {
|
if (running) {
|
||||||
reason = STOP_WAIT; /* terminate execution without setting wait_mode */
|
reason = STOP_WAIT; /* terminate execution without setting wait_mode */
|
||||||
while (running)
|
|
||||||
Sleep(10); /* wait for execution thread to exit */
|
// this prevents message pump from running, which unfortunately locks up
|
||||||
|
// the emulator thread when it calls gui_run(FALSE) which calls EnableWindow on the Run lamp
|
||||||
|
// while (running)
|
||||||
|
// Sleep(10); /* wait for execution thread to exit */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1084,10 +1105,14 @@ void forms_check (int set)
|
||||||
|
|
||||||
btn[IDC_FORMS_CHECK].clr = (printerstatus & PRINT_CHECK) ? RGB(255,0,0) : RGB(255,255,0);
|
btn[IDC_FORMS_CHECK].clr = (printerstatus & PRINT_CHECK) ? RGB(255,0,0) : RGB(255,255,0);
|
||||||
|
|
||||||
EnableWindow(btn[IDC_FORMS_CHECK].hBtn, printerstatus);
|
btn[IDC_FORMS_CHECK].state = printerstatus;
|
||||||
|
|
||||||
if (btn[IDC_FORMS_CHECK].clr != oldcolor)
|
if (btn[IDC_FORMS_CHECK].hBtn != NULL) {
|
||||||
InvalidateRect(btn[IDC_FORMS_CHECK].hBtn, NULL, TRUE); // change color in any case
|
EnableWindow(btn[IDC_FORMS_CHECK].hBtn, printerstatus);
|
||||||
|
|
||||||
|
if (btn[IDC_FORMS_CHECK].clr != oldcolor)
|
||||||
|
InvalidateRect(btn[IDC_FORMS_CHECK].hBtn, NULL, TRUE); // change color in any case
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_check (int set)
|
void print_check (int set)
|
||||||
|
@ -1101,25 +1126,38 @@ void print_check (int set)
|
||||||
|
|
||||||
btn[IDC_FORMS_CHECK].clr = (printerstatus & PRINT_CHECK) ? RGB(255,0,0) : RGB(255,255,0);
|
btn[IDC_FORMS_CHECK].clr = (printerstatus & PRINT_CHECK) ? RGB(255,0,0) : RGB(255,255,0);
|
||||||
|
|
||||||
EnableWindow(btn[IDC_FORMS_CHECK].hBtn, printerstatus);
|
btn[IDC_FORMS_CHECK].state = printerstatus;
|
||||||
|
|
||||||
if (btn[IDC_FORMS_CHECK].clr != oldcolor)
|
if (btn[IDC_FORMS_CHECK].hBtn != NULL) {
|
||||||
InvalidateRect(btn[IDC_FORMS_CHECK].hBtn, NULL, TRUE); // change color in any case
|
EnableWindow(btn[IDC_FORMS_CHECK].hBtn, printerstatus);
|
||||||
|
|
||||||
|
if (btn[IDC_FORMS_CHECK].clr != oldcolor)
|
||||||
|
InvalidateRect(btn[IDC_FORMS_CHECK].hBtn, NULL, TRUE); // change color in any case
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void keyboard_selected (int select)
|
void keyboard_selected (int select)
|
||||||
{
|
{
|
||||||
EnableWindow(btn[IDC_KEYBOARD_SELECT].hBtn, select);
|
btn[IDC_KEYBOARD_SELECT].state = select;
|
||||||
|
|
||||||
|
if (btn[IDC_KEYBOARD_SELECT].hBtn != NULL)
|
||||||
|
EnableWindow(btn[IDC_KEYBOARD_SELECT].hBtn, select);
|
||||||
}
|
}
|
||||||
|
|
||||||
void disk_ready (int ready)
|
void disk_ready (int ready)
|
||||||
{
|
{
|
||||||
EnableWindow(btn[IDC_FILE_READY].hBtn, ready);
|
btn[IDC_FILE_READY].state = ready;
|
||||||
|
|
||||||
|
if (btn[IDC_FILE_READY].hBtn != NULL)
|
||||||
|
EnableWindow(btn[IDC_FILE_READY].hBtn, ready);
|
||||||
}
|
}
|
||||||
|
|
||||||
void disk_unlocked (int unlocked)
|
void disk_unlocked (int unlocked)
|
||||||
{
|
{
|
||||||
EnableWindow(btn[IDC_DISK_UNLOCK].hBtn, unlocked);
|
btn[IDC_DISK_UNLOCK].state = unlocked;
|
||||||
|
|
||||||
|
if (btn[IDC_DISK_UNLOCK].hBtn != NULL)
|
||||||
|
EnableWindow(btn[IDC_DISK_UNLOCK].hBtn, unlocked);
|
||||||
}
|
}
|
||||||
|
|
||||||
CRITICAL_SECTION critsect;
|
CRITICAL_SECTION critsect;
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
* or modifications.
|
* or modifications.
|
||||||
*
|
*
|
||||||
* This is not a supported product, but I welcome bug reports and fixes.
|
* This is not a supported product, but I welcome bug reports and fixes.
|
||||||
* Mail to sim@ibm1130.org
|
* Mail to simh@ibm1130.org
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ibm1130_defs.h"
|
#include "ibm1130_defs.h"
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -20,7 +20,7 @@
|
||||||
* or modifications.
|
* or modifications.
|
||||||
*
|
*
|
||||||
* This is not a supported product, but I welcome bug reports and fixes.
|
* This is not a supported product, but I welcome bug reports and fixes.
|
||||||
* Mail to sim@ibm1130.org
|
* Mail to simh@ibm1130.org
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ibm1130_defs.h"
|
#include "ibm1130_defs.h"
|
||||||
|
|
|
@ -58,9 +58,11 @@ ibm1130D = ./
|
||||||
ibm1130 = ${ibm1130D}ibm1130_sys.c ${ibm1130D}ibm1130_cpu.c \
|
ibm1130 = ${ibm1130D}ibm1130_sys.c ${ibm1130D}ibm1130_cpu.c \
|
||||||
${ibm1130D}ibm1130_cr.c ${ibm1130D}ibm1130_disk.c \
|
${ibm1130D}ibm1130_cr.c ${ibm1130D}ibm1130_disk.c \
|
||||||
${ibm1130D}ibm1130_stddev.c ${ibm1130D}ibm1130_gdu.c \
|
${ibm1130D}ibm1130_stddev.c ${ibm1130D}ibm1130_gdu.c \
|
||||||
${ibm1130D}ibm1130_gui.c ${ibm1130D}ibm1130_prt.c
|
${ibm1130D}ibm1130_gui.c ${ibm1130D}ibm1130_prt.c \
|
||||||
|
${ibm1130D}ibm1130_fmt.c
|
||||||
|
|
||||||
ibm1130_INC = ibm1130res.h ibm1130_conin.h ibm1130_conout.h \
|
ibm1130_INC = ibm1130res.h ibm1130_conin.h ibm1130_conout.h \
|
||||||
ibm1130_defs.h ibm1130_prtwheel.h \
|
ibm1130_defs.h ibm1130_prtwheel.h ibm1130_fmt.h \
|
||||||
dmsr2v12phases.h dmsr2v12slet.h
|
dmsr2v12phases.h dmsr2v12slet.h
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
Here's the 1130 simulator as it stands now.
|
Here's the 1130 simulator as it stands now.
|
||||||
|
|
||||||
|
Status: 22Jul2003
|
||||||
|
|
||||||
|
* Added support for APL\1130 output translations
|
||||||
|
and some bug fixes uncovered by APL.
|
||||||
|
|
||||||
Status: 13Sep2002
|
Status: 13Sep2002
|
||||||
|
|
||||||
* Added support for 1403 printer. It's MUCH faster
|
* Added support for 1403 printer. It's MUCH faster
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
Version: 18 March 2003
|
Version: 10 July 2003
|
||||||
|
|
||||||
History (partial):
|
History (partial):
|
||||||
|
|
||||||
|
2003-07-10 Fixed disk and console terminal bugs uncovered by
|
||||||
|
APL\1130. Added APL keyboard and output font support
|
||||||
|
to enable use of APL\1130. APL will be released soon.
|
||||||
|
|
||||||
2003-03-18 Fixed bug in asm1130 that produced an error message
|
2003-03-18 Fixed bug in asm1130 that produced an error message
|
||||||
with a (legal) offset of +127 in MDX instructions.
|
with a (legal) offset of +127 in MDX instructions.
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
// ASM1130 - IBM 1130 Cross Assembler
|
// ASM1130 - IBM 1130 Cross Assembler
|
||||||
//
|
//
|
||||||
// Version
|
// Version
|
||||||
|
// 1.08 - 2003Mar18 - Fixed bug that complained about valid MDX displacement of +127
|
||||||
// 1.07 - 2003Jan05 - Filenames are now left in lower case. SYMBOLS.SYS stays all upper case
|
// 1.07 - 2003Jan05 - Filenames are now left in lower case. SYMBOLS.SYS stays all upper case
|
||||||
// 1.06 - 2002May02 - Fixed bug in ebdic constants (data goes into low byte)
|
// 1.06 - 2002May02 - Fixed bug in ebdic constants (data goes into low byte)
|
||||||
// First stab at adding ISS level # info, this is iffy
|
// First stab at adding ISS level # info, this is iffy
|
||||||
|
@ -156,7 +157,7 @@
|
||||||
#define TRUE 1
|
#define TRUE 1
|
||||||
#define FALSE 0
|
#define FALSE 0
|
||||||
|
|
||||||
#define VERSION "ASM1130 CROSS ASSEMBLER V1.07"
|
#define VERSION "ASM1130 CROSS ASSEMBLER V1.08"
|
||||||
|
|
||||||
#define ISTV 0x33 // magic number from DMS R2V12 monitorm symbol @ISTV
|
#define ISTV 0x33 // magic number from DMS R2V12 monitorm symbol @ISTV
|
||||||
|
|
||||||
|
@ -3392,7 +3393,7 @@ void mdx_op (struct tag_op *op, char *label, char *mods, char *arg)
|
||||||
else
|
else
|
||||||
getexpr(tok, FALSE, &incr);
|
getexpr(tok, FALSE, &incr);
|
||||||
|
|
||||||
if (incr.value < -128 || incr.value >= 127) // displacement style
|
if (incr.value < -128 || incr.value > 127) // displacement style (fixed in ver 1.08)
|
||||||
asm_error("Invalid increment value (8 bits signed)");
|
asm_error("Invalid increment value (8 bits signed)");
|
||||||
|
|
||||||
opcode |= (incr.value & 0xFF);
|
opcode |= (incr.value & 0xFF);
|
||||||
|
|
|
@ -426,7 +426,7 @@ void show_data (void)
|
||||||
(reloc == R_LIBF) ? 'L' : '@';
|
(reloc == R_LIBF) ? 'L' : '@';
|
||||||
|
|
||||||
printf("%04x%c ", buf[9+i], ch);
|
printf("%04x%c ", buf[9+i], ch);
|
||||||
rflag << 2;
|
rflag <<= 2;
|
||||||
nout++;
|
nout++;
|
||||||
}
|
}
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
|
|
|
@ -337,7 +337,7 @@ void show_data (unsigned short *buf)
|
||||||
(reloc == R_LIBF) ? 'L' : '@';
|
(reloc == R_LIBF) ? 'L' : '@';
|
||||||
|
|
||||||
printf("%04x%c ", buf[9+i], ch);
|
printf("%04x%c ", buf[9+i], ch);
|
||||||
rflag << 2;
|
rflag <<= 2;
|
||||||
nout++;
|
nout++;
|
||||||
}
|
}
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
|
|
|
@ -15,25 +15,61 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define TRUE 1
|
||||||
|
#define FALSE 0
|
||||||
|
typedef int BOOL;
|
||||||
|
|
||||||
int hollerith_to_ascii (unsigned short h);
|
int hollerith_to_ascii (unsigned short h);
|
||||||
void bail (char *msg);
|
void bail (char *msg);
|
||||||
|
void format_coldstart (unsigned short *buf);
|
||||||
|
|
||||||
int main (int argc, char **argv)
|
int main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
FILE *fd;
|
FILE *fd;
|
||||||
char line[82];
|
char *fname = NULL, line[82], *arg;
|
||||||
|
BOOL coldstart = FALSE;
|
||||||
unsigned short buf[80];
|
unsigned short buf[80];
|
||||||
int i, lastnb;
|
int i, lastnb;
|
||||||
|
static char usestr[] =
|
||||||
|
"Usage: viewdeck [-c] deckfile\n"
|
||||||
|
"\n"
|
||||||
|
"-c: convert cold start card to 16-bit format as a C array initializer\n";
|
||||||
|
|
||||||
if (argc != 2)
|
for (i = 1; i < argc; i++) { // process command line arguments
|
||||||
bail("Usage: viewdeck deckfile");
|
arg = argv[i];
|
||||||
|
|
||||||
if ((fd = fopen(argv[1], "rb")) == NULL) {
|
if (*arg == '-') {
|
||||||
perror(argv[1]);
|
arg++;
|
||||||
|
while (*arg) {
|
||||||
|
switch (*arg++) {
|
||||||
|
case 'c':
|
||||||
|
coldstart = TRUE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
bail(usestr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (fname == NULL) // first non-switch arg is file name
|
||||||
|
fname = arg;
|
||||||
|
else
|
||||||
|
bail(usestr); // there can be only one name
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fname == NULL) // there must be a name
|
||||||
|
bail(usestr);
|
||||||
|
|
||||||
|
if ((fd = fopen(fname, "rb")) == NULL) {
|
||||||
|
perror(fname);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (fread(buf, sizeof(short), 80, fd) == 80) {
|
while (fread(buf, sizeof(short), 80, fd) == 80) {
|
||||||
|
if (coldstart) {
|
||||||
|
format_coldstart(buf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
lastnb = -1;
|
lastnb = -1;
|
||||||
for (i = 0; i < 80; i++) {
|
for (i = 0; i < 80; i++) {
|
||||||
line[i] = hollerith_to_ascii(buf[i]);
|
line[i] = hollerith_to_ascii(buf[i]);
|
||||||
|
@ -45,11 +81,39 @@ int main (int argc, char **argv)
|
||||||
fputs(line, stdout);
|
fputs(line, stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (coldstart) {
|
||||||
|
if (fread(buf, sizeof(short), 1, fd) == 1)
|
||||||
|
bail("Coldstart deck has more than one card");
|
||||||
|
}
|
||||||
|
|
||||||
fclose(fd);
|
fclose(fd);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void format_coldstart (unsigned short *buf)
|
||||||
|
{
|
||||||
|
int i, nout = 0;
|
||||||
|
unsigned short word;
|
||||||
|
|
||||||
|
for (i = 0; i < 80; i++) {
|
||||||
|
word = buf[i]; // expand 12-bit card data to 16-bit instruction
|
||||||
|
word = (word & 0xF800) | ((word & 0x0400) ? 0x00C0 : 0x0000) | ((word & 0x03F0) >> 4);
|
||||||
|
|
||||||
|
if (nout >= 8) {
|
||||||
|
fputs(",\n", stdout);
|
||||||
|
nout = 0;
|
||||||
|
}
|
||||||
|
else if (i > 0)
|
||||||
|
fputs(", ", stdout);
|
||||||
|
|
||||||
|
printf("0x%04x", word);
|
||||||
|
nout++;
|
||||||
|
}
|
||||||
|
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned short hollerith;
|
unsigned short hollerith;
|
||||||
char ascii;
|
char ascii;
|
||||||
|
@ -103,7 +167,7 @@ static CPCODE cardcode_029[] =
|
||||||
0x0120, '\'',
|
0x0120, '\'',
|
||||||
0x00A0, '=',
|
0x00A0, '=',
|
||||||
0x0060, '"',
|
0x0060, '"',
|
||||||
0x8820, 'c', // cent
|
0x8820, '\xA2', // cent, in MS-DOS encoding
|
||||||
0x8420, '.',
|
0x8420, '.',
|
||||||
0x8220, '<', // ) in 026 Fortran
|
0x8220, '<', // ) in 026 Fortran
|
||||||
0x8120, '(',
|
0x8120, '(',
|
||||||
|
@ -114,13 +178,47 @@ static CPCODE cardcode_029[] =
|
||||||
0x4220, '*',
|
0x4220, '*',
|
||||||
0x4120, ')',
|
0x4120, ')',
|
||||||
0x40A0, ';',
|
0x40A0, ';',
|
||||||
0x4060, 'n', // not
|
0x4060, '\xAC', // not, in MS-DOS encoding
|
||||||
0x2820, 'x', // what?
|
|
||||||
0x2420, ',',
|
0x2420, ',',
|
||||||
0x2220, '%', // ( in 026 Fortran
|
0x2220, '%', // ( in 026 Fortran
|
||||||
0x2120, '_',
|
0x2120, '_',
|
||||||
0x20A0, '>',
|
0x20A0, '>',
|
||||||
0x2060, '>',
|
0xB000, 'a',
|
||||||
|
0xA800, 'b',
|
||||||
|
0xA400, 'c',
|
||||||
|
0xA200, 'd',
|
||||||
|
0xA100, 'e',
|
||||||
|
0xA080, 'f',
|
||||||
|
0xA040, 'g',
|
||||||
|
0xA020, 'h',
|
||||||
|
0xA010, 'i',
|
||||||
|
0xD000, 'j',
|
||||||
|
0xC800, 'k',
|
||||||
|
0xC400, 'l',
|
||||||
|
0xC200, 'm',
|
||||||
|
0xC100, 'n',
|
||||||
|
0xC080, 'o',
|
||||||
|
0xC040, 'p',
|
||||||
|
0xC020, 'q',
|
||||||
|
0xC010, 'r',
|
||||||
|
0x6800, 's',
|
||||||
|
0x6400, 't',
|
||||||
|
0x6200, 'u',
|
||||||
|
0x6100, 'v',
|
||||||
|
0x6080, 'w',
|
||||||
|
0x6040, 'x',
|
||||||
|
0x6020, 'y',
|
||||||
|
0x6010, 'z', // these odd punch codes are used by APL:
|
||||||
|
0x1010, '\001', // no corresponding ASCII using ^A
|
||||||
|
0x0810, '\002', // SYN using ^B
|
||||||
|
0x0410, '\003', // no corresponding ASCII using ^C
|
||||||
|
0x0210, '\004', // PUNCH ON using ^D
|
||||||
|
0x0110, '\005', // READER STOP using ^E
|
||||||
|
0x0090, '\006', // UPPER CASE using ^F
|
||||||
|
0x0050, '\013', // EOT using ^K
|
||||||
|
0x0030, '\016', // no corresponding ASCII using ^N
|
||||||
|
0x1030, '\017', // no corresponding ASCII using ^O
|
||||||
|
0x0830, '\020', // no corresponding ASCII using ^P
|
||||||
};
|
};
|
||||||
|
|
||||||
int hollerith_to_ascii (unsigned short h)
|
int hollerith_to_ascii (unsigned short h)
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
in this Software without prior written authorization from Robert M Supnik.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
15-Jul-03 RMS Fixed signed/unsigned bug in get_imm
|
||||||
27-Feb-03 RMS Added relative addressing support
|
27-Feb-03 RMS Added relative addressing support
|
||||||
23-Dec-01 RMS Cloned from ID4 sources
|
23-Dec-01 RMS Cloned from ID4 sources
|
||||||
*/
|
*/
|
||||||
|
@ -481,7 +482,7 @@ return reg;
|
||||||
t_stat get_imm (char *cptr, uint32 *imm, uint32 *inst, uint32 max)
|
t_stat get_imm (char *cptr, uint32 *imm, uint32 *inst, uint32 max)
|
||||||
{
|
{
|
||||||
char *tptr;
|
char *tptr;
|
||||||
uint32 idx;
|
int32 idx;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
*imm = strtoul (cptr, &tptr, 16); /* get immed */
|
*imm = strtoul (cptr, &tptr, 16); /* get immed */
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
To: Users
|
To: Users
|
||||||
From: Bob Supnik
|
From: Bob Supnik
|
||||||
Subj: Interdata 16b/32b Simulator Usage
|
Subj: Interdata 16b/32b Simulator Usage
|
||||||
Date: 15-Mar-2003
|
Date: 15-Jul-2003
|
||||||
|
|
||||||
COPYRIGHT NOTICE
|
COPYRIGHT NOTICE
|
||||||
|
|
||||||
|
@ -39,10 +39,12 @@ This memorandum documents the Interdata 16b and 32b simulators.
|
||||||
sim/ sim_defs.h
|
sim/ sim_defs.h
|
||||||
sim_rev.h
|
sim_rev.h
|
||||||
sim_sock.h
|
sim_sock.h
|
||||||
|
sim_tape.h
|
||||||
sim_tmxr.h
|
sim_tmxr.h
|
||||||
scp.c
|
scp.c
|
||||||
scp_tty.c
|
scp_tty.c
|
||||||
sim_sock.c
|
sim_sock.c
|
||||||
|
sim_tape.c
|
||||||
sim_tmxr.c
|
sim_tmxr.c
|
||||||
|
|
||||||
sim/interdata/ id_defs.h
|
sim/interdata/ id_defs.h
|
||||||
|
@ -519,8 +521,7 @@ The programmable interval clock (PIC) implements these registers:
|
||||||
IARM 1 clock interrupt armed
|
IARM 1 clock interrupt armed
|
||||||
|
|
||||||
If the interval requested is an exact multiple of 1 msec, the
|
If the interval requested is an exact multiple of 1 msec, the
|
||||||
programmable clock auto-calibrates; if not, it simply counts
|
programmable clock auto-calibrates; if not, it counts instructions.
|
||||||
counts instructions.
|
|
||||||
|
|
||||||
2.4.7 Floppy Disk Controller (FD)
|
2.4.7 Floppy Disk Controller (FD)
|
||||||
|
|
||||||
|
@ -822,7 +823,7 @@ line switches:
|
||||||
alphabetic instruction mnemonic
|
alphabetic instruction mnemonic
|
||||||
numeric octal number
|
numeric octal number
|
||||||
|
|
||||||
2.7.1 16b Instruction Input
|
2.8.1 16b Instruction Input
|
||||||
|
|
||||||
Instruction input uses standard Interdata assembler syntax. There are
|
Instruction input uses standard Interdata assembler syntax. There are
|
||||||
seven instruction classes: short branch, extended short branch, short
|
seven instruction classes: short branch, extended short branch, short
|
||||||
|
@ -883,7 +884,7 @@ preceded by R, between 0 and F (15), the address is a hex number
|
||||||
between 0 and 0xFFFF, and the index register is a hex (decimal)
|
between 0 and 0xFFFF, and the index register is a hex (decimal)
|
||||||
number, optionally preceded by R, between 1 and F (15).
|
number, optionally preceded by R, between 1 and F (15).
|
||||||
|
|
||||||
2.7.2 32b Instruction Input
|
2.8.2 32b Instruction Input
|
||||||
|
|
||||||
Instruction input uses standard Interdata assembler syntax. There are
|
Instruction input uses standard Interdata assembler syntax. There are
|
||||||
nine instruction classes: short branch, extended short branch, short
|
nine instruction classes: short branch, extended short branch, short
|
||||||
|
|
|
@ -305,8 +305,8 @@ The clock implements these registers:
|
||||||
TIME2 24 clock frequency, select = 2
|
TIME2 24 clock frequency, select = 2
|
||||||
TIME3 24 clock frequency, select = 3
|
TIME3 24 clock frequency, select = 3
|
||||||
|
|
||||||
The real-time clock autocalibrates; the clock interval is adjusted up or
|
The real-time clock autocalibrates; the clock interval is adjusted up
|
||||||
down so that the clock tracks actual elapsed time.
|
or down so that the clock tracks actual elapsed time.
|
||||||
|
|
||||||
2.2.7 Plotter (PTP)
|
2.2.7 Plotter (PTP)
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
dsk fixed head disk
|
dsk fixed head disk
|
||||||
|
|
||||||
|
26-Jul-03 RMS Fixed bug in set size routine
|
||||||
14-Mar-03 RMS Fixed variable capacity interaction with save/restore
|
14-Mar-03 RMS Fixed variable capacity interaction with save/restore
|
||||||
03-Mar-03 RMS Fixed variable capacity and autosizing
|
03-Mar-03 RMS Fixed variable capacity and autosizing
|
||||||
03-Oct-02 RMS Added DIB
|
03-Oct-02 RMS Added DIB
|
||||||
|
@ -133,14 +134,14 @@ REG dsk_reg[] = {
|
||||||
{ NULL } };
|
{ NULL } };
|
||||||
|
|
||||||
MTAB dsk_mod[] = {
|
MTAB dsk_mod[] = {
|
||||||
{ UNIT_PLAT, 0, NULL, "1P", &dsk_set_size },
|
{ UNIT_PLAT, (0 << UNIT_V_PLAT), NULL, "1P", &dsk_set_size },
|
||||||
{ UNIT_PLAT, 1, NULL, "2P", &dsk_set_size },
|
{ UNIT_PLAT, (1 << UNIT_V_PLAT), NULL, "2P", &dsk_set_size },
|
||||||
{ UNIT_PLAT, 2, NULL, "3P", &dsk_set_size },
|
{ UNIT_PLAT, (2 << UNIT_V_PLAT), NULL, "3P", &dsk_set_size },
|
||||||
{ UNIT_PLAT, 3, NULL, "4P", &dsk_set_size },
|
{ UNIT_PLAT, (3 << UNIT_V_PLAT), NULL, "4P", &dsk_set_size },
|
||||||
{ UNIT_PLAT, 4, NULL, "5P", &dsk_set_size },
|
{ UNIT_PLAT, (4 << UNIT_V_PLAT), NULL, "5P", &dsk_set_size },
|
||||||
{ UNIT_PLAT, 5, NULL, "6P", &dsk_set_size },
|
{ UNIT_PLAT, (5 << UNIT_V_PLAT), NULL, "6P", &dsk_set_size },
|
||||||
{ UNIT_PLAT, 6, NULL, "7P", &dsk_set_size },
|
{ UNIT_PLAT, (6 << UNIT_V_PLAT), NULL, "7P", &dsk_set_size },
|
||||||
{ UNIT_PLAT, 7, NULL, "8P", &dsk_set_size },
|
{ UNIT_PLAT, (7 << UNIT_V_PLAT), NULL, "8P", &dsk_set_size },
|
||||||
{ UNIT_AUTO, UNIT_AUTO, "autosize", "AUTOSIZE", NULL },
|
{ UNIT_AUTO, UNIT_AUTO, "autosize", "AUTOSIZE", NULL },
|
||||||
{ 0 } };
|
{ 0 } };
|
||||||
|
|
||||||
|
@ -289,9 +290,9 @@ return attach_unit (uptr, cptr);
|
||||||
|
|
||||||
t_stat dsk_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
|
t_stat dsk_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||||
{
|
{
|
||||||
if ((val < 0) || (val >= DSK_NUMDK)) return SCPE_IERR;
|
if (val < 0) return SCPE_IERR;
|
||||||
if (uptr->flags & UNIT_ATT) return SCPE_ALATT;
|
if (uptr->flags & UNIT_ATT) return SCPE_ALATT;
|
||||||
uptr->capac = (val + 1) * DSK_DKSIZE;
|
uptr->capac = UNIT_GETP (val) * DSK_DKSIZE;
|
||||||
uptr->flags = uptr->flags & ~UNIT_AUTO;
|
uptr->flags = uptr->flags & ~UNIT_AUTO;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
cpu PDP-1 central processor
|
cpu PDP-1 central processor
|
||||||
|
|
||||||
|
23-Jul-03 RMS Revised to detect I/O wait hang
|
||||||
05-Dec-02 RMS Added drum support
|
05-Dec-02 RMS Added drum support
|
||||||
06-Oct-02 RMS Revised for V2.10
|
06-Oct-02 RMS Revised for V2.10
|
||||||
20-Aug-02 RMS Added DECtape support
|
20-Aug-02 RMS Added DECtape support
|
||||||
|
@ -239,6 +240,7 @@ int32 sbs = 0; /* sequence break */
|
||||||
int32 sbs_init = 0; /* seq break startup */
|
int32 sbs_init = 0; /* seq break startup */
|
||||||
int32 ioh = 0; /* I/O halt */
|
int32 ioh = 0; /* I/O halt */
|
||||||
int32 ioc = 0; /* I/O completion */
|
int32 ioc = 0; /* I/O completion */
|
||||||
|
int32 cpls = 0; /* pending completions */
|
||||||
int32 extm = 0; /* ext mem mode */
|
int32 extm = 0; /* ext mem mode */
|
||||||
int32 extm_init = 0; /* ext mem startup */
|
int32 extm_init = 0; /* ext mem startup */
|
||||||
int32 stop_inst = 0; /* stop on rsrv inst */
|
int32 stop_inst = 0; /* stop on rsrv inst */
|
||||||
|
@ -257,13 +259,13 @@ t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw);
|
||||||
t_stat cpu_reset (DEVICE *dptr);
|
t_stat cpu_reset (DEVICE *dptr);
|
||||||
t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
|
t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||||
|
|
||||||
extern int32 ptr (int32 inst, int32 dev, int32 IO);
|
extern int32 ptr (int32 inst, int32 dev, int32 dat);
|
||||||
extern int32 ptp (int32 inst, int32 dev, int32 IO);
|
extern int32 ptp (int32 inst, int32 dev, int32 dat);
|
||||||
extern int32 tti (int32 inst, int32 dev, int32 IO);
|
extern int32 tti (int32 inst, int32 dev, int32 dat);
|
||||||
extern int32 tto (int32 inst, int32 dev, int32 IO);
|
extern int32 tto (int32 inst, int32 dev, int32 dat);
|
||||||
extern int32 lpt (int32 inst, int32 dev, int32 IO);
|
extern int32 lpt (int32 inst, int32 dev, int32 dat);
|
||||||
extern int32 dt (int32 inst, int32 dev, int32 IO);
|
extern int32 dt (int32 inst, int32 dev, int32 dat);
|
||||||
extern int32 drm (int32 inst, int32 dev, int32 IO);
|
extern int32 drm (int32 inst, int32 dev, int32 dat);
|
||||||
|
|
||||||
int32 sc_map[512] = {
|
int32 sc_map[512] = {
|
||||||
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, /* 00000xxxx */
|
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, /* 00000xxxx */
|
||||||
|
@ -403,7 +405,7 @@ xct_count = 0; /* track nested XCT's */
|
||||||
sim_interval = sim_interval - 1;
|
sim_interval = sim_interval - 1;
|
||||||
|
|
||||||
xct_instr: /* label for XCT */
|
xct_instr: /* label for XCT */
|
||||||
if ((IR == 0610001) && ((MA & EPCMASK) == 0) && (sbs & SB_ON)) {
|
if ((IR == (OP_JMP+IA+1)) && ((MA & EPCMASK) == 0) && (sbs & SB_ON)) {
|
||||||
sbs = sbs & ~SB_IP; /* seq debreak */
|
sbs = sbs & ~SB_IP; /* seq debreak */
|
||||||
PCQ_ENTRY; /* save old PC */
|
PCQ_ENTRY; /* save old PC */
|
||||||
OV = (M[1] >> 17) & 1; /* restore OV */
|
OV = (M[1] >> 17) & 1; /* restore OV */
|
||||||
|
@ -432,12 +434,15 @@ switch (op) { /* decode IR<0:4> */
|
||||||
case 001: /* AND */
|
case 001: /* AND */
|
||||||
AC = AC & M[MA];
|
AC = AC & M[MA];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 002: /* IOR */
|
case 002: /* IOR */
|
||||||
AC = AC | M[MA];
|
AC = AC | M[MA];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 003: /* XOR */
|
case 003: /* XOR */
|
||||||
AC = AC ^ M[MA];
|
AC = AC ^ M[MA];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 004: /* XCT */
|
case 004: /* XCT */
|
||||||
if (xct_count >= xct_max) { /* too many XCT's? */
|
if (xct_count >= xct_max) { /* too many XCT's? */
|
||||||
reason = STOP_XCT;
|
reason = STOP_XCT;
|
||||||
|
@ -445,6 +450,7 @@ case 004: /* XCT */
|
||||||
xct_count = xct_count + 1; /* count XCT's */
|
xct_count = xct_count + 1; /* count XCT's */
|
||||||
IR = M[MA]; /* get instruction */
|
IR = M[MA]; /* get instruction */
|
||||||
goto xct_instr; /* go execute */
|
goto xct_instr; /* go execute */
|
||||||
|
|
||||||
case 007: /* CAL, JDA */
|
case 007: /* CAL, JDA */
|
||||||
MA = (PC & EPCMASK) | ((IR & IA)? (IR & DAMASK): 0100);
|
MA = (PC & EPCMASK) | ((IR & IA)? (IR & DAMASK): 0100);
|
||||||
PCQ_ENTRY;
|
PCQ_ENTRY;
|
||||||
|
@ -452,24 +458,31 @@ case 007: /* CAL, JDA */
|
||||||
AC = EPC_WORD;
|
AC = EPC_WORD;
|
||||||
PC = INCR_ADDR (MA);
|
PC = INCR_ADDR (MA);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 010: /* LAC */
|
case 010: /* LAC */
|
||||||
AC = M[MA];
|
AC = M[MA];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 011: /* LIO */
|
case 011: /* LIO */
|
||||||
IO = M[MA];
|
IO = M[MA];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 012: /* DAC */
|
case 012: /* DAC */
|
||||||
if (MEM_ADDR_OK (MA)) M[MA] = AC;
|
if (MEM_ADDR_OK (MA)) M[MA] = AC;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 013: /* DAP */
|
case 013: /* DAP */
|
||||||
if (MEM_ADDR_OK (MA)) M[MA] = (AC & DAMASK) | (M[MA] & ~DAMASK);
|
if (MEM_ADDR_OK (MA)) M[MA] = (AC & DAMASK) | (M[MA] & ~DAMASK);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 014: /* DIP */
|
case 014: /* DIP */
|
||||||
if (MEM_ADDR_OK (MA)) M[MA] = (AC & ~DAMASK) | (M[MA] & DAMASK);
|
if (MEM_ADDR_OK (MA)) M[MA] = (AC & ~DAMASK) | (M[MA] & DAMASK);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 015: /* DIO */
|
case 015: /* DIO */
|
||||||
if (MEM_ADDR_OK (MA)) M[MA] = IO;
|
if (MEM_ADDR_OK (MA)) M[MA] = IO;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 016: /* DZM */
|
case 016: /* DZM */
|
||||||
if (MEM_ADDR_OK (MA)) M[MA] = 0;
|
if (MEM_ADDR_OK (MA)) M[MA] = 0;
|
||||||
break;
|
break;
|
||||||
|
@ -498,6 +511,7 @@ case 020: /* ADD */
|
||||||
if (((~t ^ M[MA]) & (t ^ AC)) & 0400000) OV = 1;
|
if (((~t ^ M[MA]) & (t ^ AC)) & 0400000) OV = 1;
|
||||||
if (AC == 0777777) AC = 0; /* minus 0 cleanup */
|
if (AC == 0777777) AC = 0; /* minus 0 cleanup */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 021: /* SUB */
|
case 021: /* SUB */
|
||||||
t = AC ^ 0777777; /* complement AC */
|
t = AC ^ 0777777; /* complement AC */
|
||||||
AC = t + M[MA]; /* -AC + MB */
|
AC = t + M[MA]; /* -AC + MB */
|
||||||
|
@ -505,32 +519,39 @@ case 021: /* SUB */
|
||||||
if (((~t ^ M[MA]) & (t ^ AC)) & 0400000) OV = 1;
|
if (((~t ^ M[MA]) & (t ^ AC)) & 0400000) OV = 1;
|
||||||
AC = AC ^ 0777777; /* recomplement AC */
|
AC = AC ^ 0777777; /* recomplement AC */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 022: /* IDX */
|
case 022: /* IDX */
|
||||||
AC = M[MA] + 1;
|
AC = M[MA] + 1;
|
||||||
if (AC >= 0777777) AC = (AC + 1) & 0777777;
|
if (AC >= 0777777) AC = (AC + 1) & 0777777;
|
||||||
if (MEM_ADDR_OK (MA)) M[MA] = AC;
|
if (MEM_ADDR_OK (MA)) M[MA] = AC;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 023: /* ISP */
|
case 023: /* ISP */
|
||||||
AC = M[MA] + 1;
|
AC = M[MA] + 1;
|
||||||
if (AC >= 0777777) AC = (AC + 1) & 0777777;
|
if (AC >= 0777777) AC = (AC + 1) & 0777777;
|
||||||
if (MEM_ADDR_OK (MA)) M[MA] = AC;
|
if (MEM_ADDR_OK (MA)) M[MA] = AC;
|
||||||
if (AC < 0400000) PC = INCR_ADDR (PC);
|
if (AC < 0400000) PC = INCR_ADDR (PC);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 024: /* SAD */
|
case 024: /* SAD */
|
||||||
if (AC != M[MA]) PC = INCR_ADDR (PC);
|
if (AC != M[MA]) PC = INCR_ADDR (PC);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 025: /* SAS */
|
case 025: /* SAS */
|
||||||
if (AC == M[MA]) PC = INCR_ADDR (PC);
|
if (AC == M[MA]) PC = INCR_ADDR (PC);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 030: /* JMP */
|
case 030: /* JMP */
|
||||||
PCQ_ENTRY;
|
PCQ_ENTRY;
|
||||||
PC = MA;
|
PC = MA;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 031: /* JSP */
|
case 031: /* JSP */
|
||||||
AC = EPC_WORD;
|
AC = EPC_WORD;
|
||||||
PCQ_ENTRY;
|
PCQ_ENTRY;
|
||||||
PC = MA;
|
PC = MA;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 034: /* LAW */
|
case 034: /* LAW */
|
||||||
AC = (IR & 07777) ^ ((IR & IA)? 0777777: 0);
|
AC = (IR & 07777) ^ ((IR & IA)? 0777777: 0);
|
||||||
break;
|
break;
|
||||||
|
@ -691,8 +712,11 @@ case 035:
|
||||||
if (ioh) { /* I/O halt? */
|
if (ioh) { /* I/O halt? */
|
||||||
if (ioc) ioh = 0; /* comp pulse? done */
|
if (ioc) ioh = 0; /* comp pulse? done */
|
||||||
else { /* wait more */
|
else { /* wait more */
|
||||||
sim_interval = 0; /* force event */
|
PC = DECR_ADDR (PC); /* re-execute */
|
||||||
PC = DECR_ADDR (PC); } /* re-execute */
|
if (cpls == 0) { /* any pending pulses? */
|
||||||
|
reason = STOP_WAIT; /* no, CPU hangs */
|
||||||
|
break; }
|
||||||
|
sim_interval = 0; } /* force event */
|
||||||
break; } /* skip iot */
|
break; } /* skip iot */
|
||||||
ioh = 1; /* turn on halt */
|
ioh = 1; /* turn on halt */
|
||||||
PC = DECR_ADDR (PC); } /* re-execute */
|
PC = DECR_ADDR (PC); } /* re-execute */
|
||||||
|
@ -745,6 +769,7 @@ case 035:
|
||||||
if (io_data & IOT_SKP) PC = INCR_ADDR (PC); /* skip? */
|
if (io_data & IOT_SKP) PC = INCR_ADDR (PC); /* skip? */
|
||||||
if (io_data >= IOT_REASON) reason = io_data >> IOT_V_REASON;
|
if (io_data >= IOT_REASON) reason = io_data >> IOT_V_REASON;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: /* undefined */
|
default: /* undefined */
|
||||||
reason = STOP_RSRV; /* halt */
|
reason = STOP_RSRV; /* halt */
|
||||||
break; } /* end switch opcode */
|
break; } /* end switch opcode */
|
||||||
|
@ -759,7 +784,7 @@ t_stat cpu_reset (DEVICE *dptr)
|
||||||
{
|
{
|
||||||
sbs = sbs_init;
|
sbs = sbs_init;
|
||||||
extm = extm_init;
|
extm = extm_init;
|
||||||
ioh = ioc = 0;
|
ioh = ioc = cpls = 0;
|
||||||
OV = 0;
|
OV = 0;
|
||||||
PF = 0;
|
PF = 0;
|
||||||
pcq_r = find_reg ("PCQ", NULL, dptr);
|
pcq_r = find_reg ("PCQ", NULL, dptr);
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
in this Software without prior written authorization from Robert M Supnik.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
22-Jul-03 RMS Updated for "hardware" RIM loader
|
||||||
|
Revised to detect I/O wait hang
|
||||||
05-Dec-02 RMS Added IOT skip support (required by drum)
|
05-Dec-02 RMS Added IOT skip support (required by drum)
|
||||||
14-Apr-99 RMS Changed t_addr to unsigned
|
14-Apr-99 RMS Changed t_addr to unsigned
|
||||||
|
|
||||||
|
@ -34,7 +36,9 @@
|
||||||
|
|
||||||
Automatic multiply/divide Type 10
|
Automatic multiply/divide Type 10
|
||||||
Memory extension control Type 15
|
Memory extension control Type 15
|
||||||
|
Serial drum Type 24
|
||||||
Line printer control Type 62
|
Line printer control Type 62
|
||||||
|
Microtape (DECtape) control Type 550
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "sim_defs.h"
|
#include "sim_defs.h"
|
||||||
|
@ -46,7 +50,7 @@
|
||||||
#define STOP_IBKPT 3 /* breakpoint */
|
#define STOP_IBKPT 3 /* breakpoint */
|
||||||
#define STOP_XCT 4 /* nested XCT's */
|
#define STOP_XCT 4 /* nested XCT's */
|
||||||
#define STOP_IND 5 /* nested indirects */
|
#define STOP_IND 5 /* nested indirects */
|
||||||
#define STOP_WAIT 6 /* wait state */
|
#define STOP_WAIT 6 /* IO wait hang */
|
||||||
|
|
||||||
/* Memory */
|
/* Memory */
|
||||||
|
|
||||||
|
@ -59,11 +63,14 @@
|
||||||
/* Architectural constants */
|
/* Architectural constants */
|
||||||
|
|
||||||
#define DMASK 0777777 /* data mask */
|
#define DMASK 0777777 /* data mask */
|
||||||
#define DAMASK 007777 /* direct addr */
|
#define DAMASK 0007777 /* direct addr */
|
||||||
#define EPCMASK (AMASK & ~DAMASK) /* extended addr */
|
#define EPCMASK (AMASK & ~DAMASK) /* extended addr */
|
||||||
#define IA 010000 /* indirect flag */
|
#define IA 0010000 /* indirect flag */
|
||||||
#define IO_WAIT 010000 /* I/O sync wait */
|
#define IO_WAIT 0010000 /* I/O sync wait */
|
||||||
#define IO_CPLS 004000 /* completion pulse */
|
#define IO_CPLS 0004000 /* completion pulse */
|
||||||
|
#define OP_DAC 0240000 /* DAC */
|
||||||
|
#define OP_DIO 0320000 /* DIO */
|
||||||
|
#define OP_JMP 0600000 /* JMP */
|
||||||
#define GEN_CPLS(x) (((x) ^ ((x) << 1)) & IO_WAIT) /* completion pulse? */
|
#define GEN_CPLS(x) (((x) ^ ((x) << 1)) & IO_WAIT) /* completion pulse? */
|
||||||
|
|
||||||
/* IOT subroutine return codes */
|
/* IOT subroutine return codes */
|
||||||
|
@ -96,6 +103,17 @@
|
||||||
#define IOS_PNT (1 << IOS_V_PNT)
|
#define IOS_PNT (1 << IOS_V_PNT)
|
||||||
#define IOS_SPC (1 << IOS_V_SPC)
|
#define IOS_SPC (1 << IOS_V_SPC)
|
||||||
|
|
||||||
|
/* Completion pulses */
|
||||||
|
|
||||||
|
#define CPLS_V_PTR 5
|
||||||
|
#define CPLS_V_PTP 4
|
||||||
|
#define CPLS_V_TTO 3
|
||||||
|
#define CPLS_V_LPT 2
|
||||||
|
#define CPLS_PTR (1 << CPLS_V_PTR)
|
||||||
|
#define CPLS_PTP (1 << CPLS_V_PTP)
|
||||||
|
#define CPLS_TTO (1 << CPLS_V_TTO)
|
||||||
|
#define CPLS_LPT (1 << CPLS_V_LPT)
|
||||||
|
|
||||||
/* Sequence break flags */
|
/* Sequence break flags */
|
||||||
|
|
||||||
#define SB_V_IP 0 /* in progress */
|
#define SB_V_IP 0 /* in progress */
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
To: Users
|
To: Users
|
||||||
From: Bob Supnik
|
From: Bob Supnik
|
||||||
Subj: PDP-1 Simulator Usage
|
Subj: PDP-1 Simulator Usage
|
||||||
Date: 15-Dec-2002
|
Date: 15-Jul-2003
|
||||||
|
|
||||||
COPYRIGHT NOTICE
|
COPYRIGHT NOTICE
|
||||||
|
|
||||||
The following copyright notice applies to both the SIMH source and binary:
|
The following copyright notice applies to both the SIMH source and binary:
|
||||||
|
|
||||||
Original code published in 1993-2002, written by Robert M Supnik
|
Original code published in 1993-2003, written by Robert M Supnik
|
||||||
Copyright (c) 1993-2002, Robert M Supnik
|
Copyright (c) 1993-2003, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -75,8 +75,8 @@ The PDP-1 simulator implements the following unique stop conditions:
|
||||||
memory reference address decoding
|
memory reference address decoding
|
||||||
- more than XCTMAX nested executes are detected during
|
- more than XCTMAX nested executes are detected during
|
||||||
instruction execution
|
instruction execution
|
||||||
- wait state entered, and no I/O operations outstanding
|
- I/O wait, and no I/O operations outstanding (i.e, no I/O
|
||||||
(ie, no interrupt can ever occur)
|
completion will ever occur)
|
||||||
|
|
||||||
The PDP-1 loader supports RIM format tapes. The DUMP command is not
|
The PDP-1 loader supports RIM format tapes. The DUMP command is not
|
||||||
implemented.
|
implemented.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* pdp1_drm.c: drum/fixed head disk simulator
|
/* pdp1_drm.c: PDP-1 drum simulator
|
||||||
|
|
||||||
Copyright (c) 1993-2002, Robert M Supnik
|
Copyright (c) 1993-2002, Robert M Supnik
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
drm Type 24 serial drum
|
drm Type 24 serial drum
|
||||||
|
|
||||||
|
23-Jul-03 RMS Fixed incorrect logical, missing activate
|
||||||
05-Dec-02 RMS Cloned from pdp18b_drm.c
|
05-Dec-02 RMS Cloned from pdp18b_drm.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -95,45 +96,44 @@ DEVICE drm_dev = {
|
||||||
|
|
||||||
/* IOT routines */
|
/* IOT routines */
|
||||||
|
|
||||||
int32 drm (int32 IR, int32 dev, int32 IO)
|
int32 drm (int32 IR, int32 dev, int32 dat)
|
||||||
{
|
{
|
||||||
int32 t;
|
int32 t;
|
||||||
int32 pulse = (IR >> 6) & 037;
|
int32 pulse = (IR >> 6) & 037;
|
||||||
|
|
||||||
if (drm_dev.flags & DEV_DIS) /* disabled? */
|
if (drm_dev.flags & DEV_DIS) /* disabled? */
|
||||||
return (stop_inst << IOT_V_REASON) | IO; /* stop if requested */
|
return (stop_inst << IOT_V_REASON) | dat; /* stop if requested */
|
||||||
if ((pulse != 001) & (pulse != 011)) /* invalid pulse? */
|
if ((pulse != 001) && (pulse != 011)) /* invalid pulse? */
|
||||||
return (stop_inst << IOT_V_REASON) | IO; /* stop if requested */
|
return (stop_inst << IOT_V_REASON) | dat; /* stop if requested */
|
||||||
switch (dev) { /* switch on device */
|
switch (dev) { /* switch on device */
|
||||||
case 061: /* DWR, DRD */
|
case 061: /* DWR, DRD */
|
||||||
drm_ma = IO & 0177777; /* load mem addr */
|
drm_ma = dat & 0177777; /* load mem addr */
|
||||||
drm_unit.FUNC = pulse & DRM_WRITE; /* save function */
|
drm_unit.FUNC = pulse & DRM_WRITE; /* save function */
|
||||||
break;
|
break;
|
||||||
case 062: /* DBL, DCN */
|
case 062: /* DBL, DCN */
|
||||||
if (pulse & 010) drm_da = IO & DRM_SMASK; /* load sector # */
|
if (pulse & 010) drm_da = dat & DRM_SMASK; /* load sector # */
|
||||||
iosta = iosta & ~IOS_DRM; /* clear flags */
|
iosta = iosta & ~IOS_DRM; /* clear flags */
|
||||||
drm_err = 0;
|
drm_err = 0;
|
||||||
t = ((drm_da % DRM_NUMSC) * DRM_NUMWDS) - GET_POS (drm_time);
|
t = ((drm_da % DRM_NUMSC) * DRM_NUMWDS) - GET_POS (drm_time);
|
||||||
if (t <= 0) t = t + DRM_NUMWDT; /* wrap around? */
|
if (t <= 0) t = t + DRM_NUMWDT; /* wrap around? */
|
||||||
|
sim_activate (&drm_unit, t); /* start operation */
|
||||||
break;
|
break;
|
||||||
case 063: /* DTD */
|
case 063: /* DTD */
|
||||||
if (iosta & IOS_DRM) return (IO | IOT_SKP); /* skip if done */
|
if (pulse == 011) return (stop_inst << IOT_V_REASON) | dat;
|
||||||
|
if (iosta & IOS_DRM) return (dat | IOT_SKP); /* skip if done */
|
||||||
|
break;
|
||||||
case 064: /* DSE, DSP */
|
case 064: /* DSE, DSP */
|
||||||
if ((drm_err == 0) || (pulse & 010)) /* no error, par test? */
|
if ((drm_err == 0) || (pulse & 010)) /* no error, par test? */
|
||||||
return (IO | IOT_SKP);
|
return (dat | IOT_SKP);
|
||||||
}
|
}
|
||||||
return IO;
|
return dat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unit service
|
/* Unit service - this code assumes the entire drum is buffered */
|
||||||
|
|
||||||
This code assumes the entire drum is buffered.
|
|
||||||
*/
|
|
||||||
|
|
||||||
t_stat drm_svc (UNIT *uptr)
|
t_stat drm_svc (UNIT *uptr)
|
||||||
{
|
{
|
||||||
int32 i;
|
uint32 i, da;
|
||||||
uint32 da;
|
|
||||||
|
|
||||||
if ((uptr->flags & UNIT_BUF) == 0) { /* not buf? abort */
|
if ((uptr->flags & UNIT_BUF) == 0) { /* not buf? abort */
|
||||||
drm_err = 1; /* set error */
|
drm_err = 1; /* set error */
|
||||||
|
|
|
@ -334,23 +334,23 @@ DEVICE dt_dev = {
|
||||||
NULL, &dt_attach, &dt_detach,
|
NULL, &dt_attach, &dt_detach,
|
||||||
NULL, DEV_DISABLE };
|
NULL, DEV_DISABLE };
|
||||||
|
|
||||||
int32 dt (int32 IR, int32 dev, int32 IO)
|
int32 dt (int32 IR, int32 dev, int32 dat)
|
||||||
{
|
{
|
||||||
int32 pulse = (IR >> 6) & 037;
|
int32 pulse = (IR >> 6) & 037;
|
||||||
int32 fnc, mot, unum;
|
int32 fnc, mot, unum;
|
||||||
UNIT *uptr = NULL;
|
UNIT *uptr = NULL;
|
||||||
|
|
||||||
if (dt_dev.flags & DEV_DIS) /* disabled? */
|
if (dt_dev.flags & DEV_DIS) /* disabled? */
|
||||||
return (stop_inst << IOT_V_REASON) | IO; /* stop if requested */
|
return (stop_inst << IOT_V_REASON) | dat; /* stop if requested */
|
||||||
unum = DTA_GETUNIT (dtsa); /* get unit no */
|
unum = DTA_GETUNIT (dtsa); /* get unit no */
|
||||||
if (unum >= 0) uptr = dt_dev.units + unum; /* get unit */
|
if (unum >= 0) uptr = dt_dev.units + unum; /* get unit */
|
||||||
|
|
||||||
if (pulse == 003) { /* MSE */
|
if (pulse == 003) { /* MSE */
|
||||||
if ((dtsa ^ IO) & DTA_UNIT) dt_deselect (dtsa); /* new unit? */
|
if ((dtsa ^ dat) & DTA_UNIT) dt_deselect (dtsa); /* new unit? */
|
||||||
dtsa = (dtsa & ~DTA_UNIT) | (IO & DTA_UNIT);
|
dtsa = (dtsa & ~DTA_UNIT) | (dat & DTA_UNIT);
|
||||||
dtsb = dtsb & ~(DTB_DTF | DTB_BEF | DTB_ERF | DTB_ALLERR); }
|
dtsb = dtsb & ~(DTB_DTF | DTB_BEF | DTB_ERF | DTB_ALLERR); }
|
||||||
if (pulse == 004) { /* MLC */
|
if (pulse == 004) { /* MLC */
|
||||||
dtsa = (dtsa & ~DTA_RW) | (IO & DTA_RW); /* load dtsa */
|
dtsa = (dtsa & ~DTA_RW) | (dat & DTA_RW); /* load dtsa */
|
||||||
dtsb = dtsb & ~(DTB_DTF | DTB_BEF | DTB_ERF | DTB_ALLERR);
|
dtsb = dtsb & ~(DTB_DTF | DTB_BEF | DTB_ERF | DTB_ALLERR);
|
||||||
fnc = DTA_GETFNC (dtsa); /* get fnc */
|
fnc = DTA_GETFNC (dtsa); /* get fnc */
|
||||||
if ((uptr == NULL) || /* invalid? */
|
if ((uptr == NULL) || /* invalid? */
|
||||||
|
@ -361,10 +361,10 @@ if (pulse == 004) { /* MLC */
|
||||||
dt_seterr (uptr, DTB_SEL); /* select err */
|
dt_seterr (uptr, DTB_SEL); /* select err */
|
||||||
else dt_newsa (dtsa); }
|
else dt_newsa (dtsa); }
|
||||||
if (pulse == 005) { /* MRD */
|
if (pulse == 005) { /* MRD */
|
||||||
IO = (IO & ~DMASK) | dtdb;
|
dat = (dat & ~DMASK) | dtdb;
|
||||||
dtsb = dtsb & ~(DTB_DTF | DTB_BEF); }
|
dtsb = dtsb & ~(DTB_DTF | DTB_BEF); }
|
||||||
if (pulse == 006) { /* MWR */
|
if (pulse == 006) { /* MWR */
|
||||||
dtdb = IO & DMASK;
|
dtdb = dat & DMASK;
|
||||||
dtsb = dtsb & ~(DTB_DTF | DTB_BEF); }
|
dtsb = dtsb & ~(DTB_DTF | DTB_BEF); }
|
||||||
if (pulse == 007) { /* MRS */
|
if (pulse == 007) { /* MRS */
|
||||||
dtsb = dtsb & ~(DTB_REV | DTB_GO); /* clr rev, go */
|
dtsb = dtsb & ~(DTB_REV | DTB_GO); /* clr rev, go */
|
||||||
|
@ -373,9 +373,9 @@ if (pulse == 007) { /* MRS */
|
||||||
if (mot & DTS_DIR) dtsb = dtsb | DTB_REV; /* rev? set */
|
if (mot & DTS_DIR) dtsb = dtsb | DTB_REV; /* rev? set */
|
||||||
if ((mot >= DTS_ACCF) || (uptr->STATE & 0777700))
|
if ((mot >= DTS_ACCF) || (uptr->STATE & 0777700))
|
||||||
dtsb = dtsb | DTB_GO; } /* accel? go */
|
dtsb = dtsb | DTB_GO; } /* accel? go */
|
||||||
IO = (IO & ~DMASK) | dtsb; }
|
dat = (dat & ~DMASK) | dtsb; }
|
||||||
DT_UPDINT;
|
DT_UPDINT;
|
||||||
return IO;
|
return dat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unit deselect */
|
/* Unit deselect */
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
|
|
||||||
lpt Type 62 line printer for the PDP-1
|
lpt Type 62 line printer for the PDP-1
|
||||||
|
|
||||||
|
23-Jul-03 RMS Fixed bugs in instruction decoding, overprinting
|
||||||
|
Revised to detect I/O wait hang
|
||||||
25-Apr-03 RMS Revised for extended file support
|
25-Apr-03 RMS Revised for extended file support
|
||||||
30-May-02 RMS Widened POS to 32b
|
30-May-02 RMS Widened POS to 32b
|
||||||
13-Apr-01 RMS Revised for register arrays
|
13-Apr-01 RMS Revised for register arrays
|
||||||
|
@ -36,10 +38,10 @@
|
||||||
#define LPT_BSIZE (BPTR_MAX * 3) /* line size */
|
#define LPT_BSIZE (BPTR_MAX * 3) /* line size */
|
||||||
#define BPTR_MASK 077 /* buf ptr mask */
|
#define BPTR_MASK 077 /* buf ptr mask */
|
||||||
|
|
||||||
extern int32 ioc, sbs, iosta;
|
int32 lpt_spc = 0; /* print (0) vs spc */
|
||||||
extern int32 stop_inst;
|
int32 lpt_ovrpr = 0; /* overprint */
|
||||||
|
int32 lpt_stopioe = 0; /* stop on error */
|
||||||
int32 lpt_rpls = 0, lpt_iot = 0, lpt_stopioe = 0, bptr = 0;
|
int32 lpt_bptr = 0; /* buffer ptr */
|
||||||
char lpt_buf[LPT_BSIZE + 1] = { 0 };
|
char lpt_buf[LPT_BSIZE + 1] = { 0 };
|
||||||
static const unsigned char lpt_trans[64] = {
|
static const unsigned char lpt_trans[64] = {
|
||||||
' ','1','2','3','4','5','6','7','8','9','\'','~','#','V','^','<',
|
' ','1','2','3','4','5','6','7','8','9','\'','~','#','V','^','<',
|
||||||
|
@ -47,6 +49,9 @@ static const unsigned char lpt_trans[64] = {
|
||||||
'@','J','K','L','M','N','O','P','Q','R','$','=','-',')','-','(',
|
'@','J','K','L','M','N','O','P','Q','R','$','=','-',')','-','(',
|
||||||
'_','A','B','C','D','E','F','G','H','I','*','.','+',']','|','[' };
|
'_','A','B','C','D','E','F','G','H','I','*','.','+',']','|','[' };
|
||||||
|
|
||||||
|
extern int32 ioc, cpls, sbs, iosta;
|
||||||
|
extern int32 stop_inst;
|
||||||
|
|
||||||
t_stat lpt_svc (UNIT *uptr);
|
t_stat lpt_svc (UNIT *uptr);
|
||||||
t_stat lpt_reset (DEVICE *dptr);
|
t_stat lpt_reset (DEVICE *dptr);
|
||||||
|
|
||||||
|
@ -64,9 +69,10 @@ REG lpt_reg[] = {
|
||||||
{ ORDATA (BUF, lpt_unit.buf, 8) },
|
{ ORDATA (BUF, lpt_unit.buf, 8) },
|
||||||
{ FLDATA (PNT, iosta, IOS_V_PNT) },
|
{ FLDATA (PNT, iosta, IOS_V_PNT) },
|
||||||
{ FLDATA (SPC, iosta, IOS_V_SPC) },
|
{ FLDATA (SPC, iosta, IOS_V_SPC) },
|
||||||
{ FLDATA (RPLS, lpt_rpls, 0) },
|
{ FLDATA (RPLS, cpls, CPLS_V_LPT) },
|
||||||
{ DRDATA (BPTR, bptr, 6) },
|
{ DRDATA (BPTR, lpt_bptr, 6) },
|
||||||
{ ORDATA (LPT_STATE, lpt_iot, 6), REG_HRO },
|
{ ORDATA (LPT_STATE, lpt_spc, 6), REG_HRO },
|
||||||
|
{ FLDATA (LPT_OVRPR, lpt_ovrpr, 0), REG_HRO },
|
||||||
{ DRDATA (POS, lpt_unit.pos, T_ADDR_W), PV_LEFT },
|
{ DRDATA (POS, lpt_unit.pos, T_ADDR_W), PV_LEFT },
|
||||||
{ DRDATA (TIME, lpt_unit.wait, 24), PV_LEFT },
|
{ DRDATA (TIME, lpt_unit.wait, 24), PV_LEFT },
|
||||||
{ FLDATA (STOP_IOE, lpt_stopioe, 0) },
|
{ FLDATA (STOP_IOE, lpt_stopioe, 0) },
|
||||||
|
@ -82,38 +88,39 @@ DEVICE lpt_dev = {
|
||||||
|
|
||||||
/* Line printer IOT routine */
|
/* Line printer IOT routine */
|
||||||
|
|
||||||
int32 lpt (int32 inst, int32 dev, int32 data)
|
int32 lpt (int32 inst, int32 dev, int32 dat)
|
||||||
{
|
{
|
||||||
int32 i;
|
int32 i;
|
||||||
|
|
||||||
if (lpt_dev.flags & DEV_DIS) /* disabled? */
|
if (lpt_dev.flags & DEV_DIS) /* disabled? */
|
||||||
return (stop_inst << IOT_V_REASON) | data; /* stop if requested */
|
return (stop_inst << IOT_V_REASON) | dat; /* stop if requested */
|
||||||
if ((inst & 0700) == 0100) { /* fill buf */
|
if ((inst & 07000) == 01000) { /* fill buf */
|
||||||
if (bptr < BPTR_MAX) { /* limit test ptr */
|
if (lpt_bptr < BPTR_MAX) { /* limit test ptr */
|
||||||
i = bptr * 3; /* cvt to chr ptr */
|
i = lpt_bptr * 3; /* cvt to chr ptr */
|
||||||
lpt_buf[i] = lpt_trans[(data >> 12) & 077];
|
lpt_buf[i] = lpt_trans[(dat >> 12) & 077];
|
||||||
lpt_buf[i + 1] = lpt_trans[(data >> 6) & 077];
|
lpt_buf[i + 1] = lpt_trans[(dat >> 6) & 077];
|
||||||
lpt_buf[i + 2] = lpt_trans[data & 077]; }
|
lpt_buf[i + 2] = lpt_trans[dat & 077]; }
|
||||||
bptr = (bptr + 1) & BPTR_MASK;
|
lpt_bptr = (lpt_bptr + 1) & BPTR_MASK;
|
||||||
return data; }
|
return dat; }
|
||||||
lpt_rpls = 0;
|
if ((inst & 07000) == 02000) { /* space */
|
||||||
if ((inst & 0700) == 0200) { /* space */
|
|
||||||
iosta = iosta & ~IOS_SPC; /* space, clear flag */
|
iosta = iosta & ~IOS_SPC; /* space, clear flag */
|
||||||
lpt_iot = (inst >> 6) & 077; } /* state = space n */
|
lpt_spc = (inst >> 6) & 077; } /* state = space n */
|
||||||
else { iosta = iosta & ~IOS_PNT; /* clear flag */
|
else if ((inst & 07000) == 00000) { /* print */
|
||||||
lpt_iot = 0; } /* state = print */
|
iosta = iosta & ~IOS_PNT; /* clear flag */
|
||||||
|
lpt_spc = 0; } /* state = print */
|
||||||
|
else return (stop_inst << IOT_V_REASON) | dat; /* not implemented */
|
||||||
if (GEN_CPLS (inst)) { /* comp pulse? */
|
if (GEN_CPLS (inst)) { /* comp pulse? */
|
||||||
ioc = 0; /* clear flop */
|
ioc = 0; /* clear flop */
|
||||||
lpt_rpls = 1; } /* request completion */
|
cpls = cpls | CPLS_LPT; } /* request completion */
|
||||||
|
else cpls = cpls & ~CPLS_LPT;
|
||||||
sim_activate (&lpt_unit, lpt_unit.wait); /* activate */
|
sim_activate (&lpt_unit, lpt_unit.wait); /* activate */
|
||||||
return data;
|
return dat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unit service, printer is in one of three states
|
/* Unit service, printer is in one of three states
|
||||||
|
|
||||||
lpt_iot = 000 write buffer to file, set state to
|
lpt_spc = 000 write buffer to file, set overprint
|
||||||
lpt_iot = 010 write cr, then write buffer to file
|
lpt_iot = 02x space command x, clear overprint
|
||||||
lpt_iot = 02x space command x, then set state to 0
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
t_stat lpt_svc (UNIT *uptr)
|
t_stat lpt_svc (UNIT *uptr)
|
||||||
|
@ -129,30 +136,32 @@ static const char *lpt_cc[] = {
|
||||||
"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",
|
"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",
|
||||||
"\f" };
|
"\f" };
|
||||||
|
|
||||||
|
if (cpls & CPLS_LPT) { /* completion pulse? */
|
||||||
|
ioc = 1; /* restart */
|
||||||
|
cpls = cpls & ~CPLS_LPT; } /* clr pulse pending */
|
||||||
sbs = sbs | SB_RQ; /* req seq break */
|
sbs = sbs | SB_RQ; /* req seq break */
|
||||||
ioc = ioc | lpt_rpls; /* restart */
|
if (lpt_spc) { /* space? */
|
||||||
if (lpt_iot & 020) { /* space? */
|
|
||||||
iosta = iosta | IOS_SPC; /* set flag */
|
iosta = iosta | IOS_SPC; /* set flag */
|
||||||
if ((lpt_unit.flags & UNIT_ATT) == 0) /* attached? */
|
if ((lpt_unit.flags & UNIT_ATT) == 0) /* attached? */
|
||||||
return IORETURN (lpt_stopioe, SCPE_UNATT);
|
return IORETURN (lpt_stopioe, SCPE_UNATT);
|
||||||
fputs (lpt_cc[lpt_iot & 07], lpt_unit.fileref); /* print cctl */
|
fputs (lpt_cc[lpt_spc & 07], lpt_unit.fileref); /* print cctl */
|
||||||
if (ferror (lpt_unit.fileref)) { /* error? */
|
if (ferror (lpt_unit.fileref)) { /* error? */
|
||||||
perror ("LPT I/O error");
|
perror ("LPT I/O error");
|
||||||
clearerr (lpt_unit.fileref);
|
clearerr (lpt_unit.fileref);
|
||||||
return SCPE_IOERR; }
|
return SCPE_IOERR; }
|
||||||
lpt_iot = 0; } /* clear state */
|
lpt_ovrpr = 0; } /* dont overprint */
|
||||||
else { iosta = iosta | IOS_PNT; /* print */
|
else { iosta = iosta | IOS_PNT; /* print */
|
||||||
if ((lpt_unit.flags & UNIT_ATT) == 0) /* attached? */
|
if ((lpt_unit.flags & UNIT_ATT) == 0) /* attached? */
|
||||||
return IORETURN (lpt_stopioe, SCPE_UNATT);
|
return IORETURN (lpt_stopioe, SCPE_UNATT);
|
||||||
if (lpt_iot & 010) fputc ('\r', lpt_unit.fileref);
|
if (lpt_ovrpr) fputc ('\r', lpt_unit.fileref); /* overprint? */
|
||||||
fputs (lpt_buf, lpt_unit.fileref); /* print buffer */
|
fputs (lpt_buf, lpt_unit.fileref); /* print buffer */
|
||||||
if (ferror (lpt_unit.fileref)) { /* test error */
|
if (ferror (lpt_unit.fileref)) { /* test error */
|
||||||
perror ("LPT I/O error");
|
perror ("LPT I/O error");
|
||||||
clearerr (lpt_unit.fileref);
|
clearerr (lpt_unit.fileref);
|
||||||
return SCPE_IOERR; }
|
return SCPE_IOERR; }
|
||||||
bptr = 0;
|
lpt_bptr = 0;
|
||||||
for (i = 0; i <= LPT_BSIZE; i++) lpt_buf[i] = 0; /* clear buffer */
|
for (i = 0; i <= LPT_BSIZE; i++) lpt_buf[i] = 0; /* clear buffer */
|
||||||
lpt_iot = 010; } /* set state */
|
lpt_ovrpr = 1; } /* set overprint */
|
||||||
lpt_unit.pos = ftell (lpt_unit.fileref); /* update position */
|
lpt_unit.pos = ftell (lpt_unit.fileref); /* update position */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
@ -163,11 +172,12 @@ t_stat lpt_reset (DEVICE *dptr)
|
||||||
{
|
{
|
||||||
int32 i;
|
int32 i;
|
||||||
|
|
||||||
iosta = iosta & ~(IOS_PNT | IOS_SPC); /* clear flags */
|
lpt_bptr = 0; /* clear buffer ptr */
|
||||||
bptr = 0; /* clear buffer ptr */
|
|
||||||
for (i = 0; i <= LPT_BSIZE; i++) lpt_buf[i] = 0; /* clear buffer */
|
for (i = 0; i <= LPT_BSIZE; i++) lpt_buf[i] = 0; /* clear buffer */
|
||||||
lpt_iot = 0; /* clear state */
|
lpt_spc = 0; /* clear state */
|
||||||
lpt_rpls = 0;
|
lpt_ovrpr = 0; /* clear overprint */
|
||||||
|
cpls = cpls & ~CPLS_LPT;
|
||||||
|
iosta = iosta & ~(IOS_PNT | IOS_SPC); /* clear flags */
|
||||||
sim_cancel (&lpt_unit); /* deactivate unit */
|
sim_cancel (&lpt_unit); /* deactivate unit */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
tti keyboard
|
tti keyboard
|
||||||
tto teleprinter
|
tto teleprinter
|
||||||
|
|
||||||
|
23-Jul-03 RMS Revised to detect I/O wait hang
|
||||||
25-Apr-03 RMS Revised for extended file support
|
25-Apr-03 RMS Revised for extended file support
|
||||||
22-Dec-02 RMS Added break support
|
22-Dec-02 RMS Added break support
|
||||||
29-Nov-02 RMS Fixed output flag initialization (found by Derek Peschel)
|
29-Nov-02 RMS Fixed output flag initialization (found by Derek Peschel)
|
||||||
|
@ -52,16 +53,16 @@
|
||||||
#define TTI 0
|
#define TTI 0
|
||||||
#define TTO 1
|
#define TTO 1
|
||||||
|
|
||||||
extern int32 sbs, ioc, iosta, PF, IO, PC;
|
int32 ptr_state = 0;
|
||||||
extern int32 M[];
|
int32 ptr_stopioe = 0;
|
||||||
|
int32 ptp_stopioe = 0;
|
||||||
int32 ptr_rpls = 0, ptr_stopioe = 0, ptr_state = 0;
|
|
||||||
int32 ptp_rpls = 0, ptp_stopioe = 0;
|
|
||||||
int32 tti_hold = 0; /* tti hold buf */
|
int32 tti_hold = 0; /* tti hold buf */
|
||||||
int32 tto_rpls = 0; /* tto restart */
|
|
||||||
int32 tty_buf = 0; /* tty buffer */
|
int32 tty_buf = 0; /* tty buffer */
|
||||||
int32 tty_uc = 0; /* tty uc/lc */
|
int32 tty_uc = 0; /* tty uc/lc */
|
||||||
|
|
||||||
|
extern int32 sbs, ioc, cpls, iosta, PF, IO, PC;
|
||||||
|
extern int32 M[];
|
||||||
|
|
||||||
t_stat ptr_svc (UNIT *uptr);
|
t_stat ptr_svc (UNIT *uptr);
|
||||||
t_stat ptp_svc (UNIT *uptr);
|
t_stat ptp_svc (UNIT *uptr);
|
||||||
t_stat tti_svc (UNIT *uptr);
|
t_stat tti_svc (UNIT *uptr);
|
||||||
|
@ -123,7 +124,7 @@ UNIT ptr_unit = {
|
||||||
REG ptr_reg[] = {
|
REG ptr_reg[] = {
|
||||||
{ ORDATA (BUF, ptr_unit.buf, 18) },
|
{ ORDATA (BUF, ptr_unit.buf, 18) },
|
||||||
{ FLDATA (DONE, iosta, IOS_V_PTR) },
|
{ FLDATA (DONE, iosta, IOS_V_PTR) },
|
||||||
{ FLDATA (RPLS, ptr_rpls, 0) },
|
{ FLDATA (RPLS, cpls, CPLS_V_PTR) },
|
||||||
{ ORDATA (STATE, ptr_state, 5), REG_HRO },
|
{ ORDATA (STATE, ptr_state, 5), REG_HRO },
|
||||||
{ DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT },
|
{ DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT },
|
||||||
{ DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT },
|
{ DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT },
|
||||||
|
@ -150,7 +151,7 @@ UNIT ptp_unit = {
|
||||||
REG ptp_reg[] = {
|
REG ptp_reg[] = {
|
||||||
{ ORDATA (BUF, ptp_unit.buf, 8) },
|
{ ORDATA (BUF, ptp_unit.buf, 8) },
|
||||||
{ FLDATA (DONE, iosta, IOS_V_PTP) },
|
{ FLDATA (DONE, iosta, IOS_V_PTP) },
|
||||||
{ FLDATA (RPLS, ptp_rpls, 0) },
|
{ FLDATA (RPLS, cpls, CPLS_V_PTP) },
|
||||||
{ DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT },
|
{ DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT },
|
||||||
{ DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT },
|
{ DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT },
|
||||||
{ FLDATA (STOP_IOE, ptp_stopioe, 0) },
|
{ FLDATA (STOP_IOE, ptp_stopioe, 0) },
|
||||||
|
@ -177,7 +178,7 @@ UNIT tty_unit[] = {
|
||||||
REG tty_reg[] = {
|
REG tty_reg[] = {
|
||||||
{ ORDATA (BUF, tty_buf, 6) },
|
{ ORDATA (BUF, tty_buf, 6) },
|
||||||
{ FLDATA (UC, tty_uc, UC_V) },
|
{ FLDATA (UC, tty_uc, UC_V) },
|
||||||
{ FLDATA (RPLS, tto_rpls, 0) },
|
{ FLDATA (RPLS, cpls, CPLS_V_TTO) },
|
||||||
{ ORDATA (HOLD, tti_hold, 9), REG_HRO },
|
{ ORDATA (HOLD, tti_hold, 9), REG_HRO },
|
||||||
{ FLDATA (KDONE, iosta, IOS_V_TTI) },
|
{ FLDATA (KDONE, iosta, IOS_V_TTI) },
|
||||||
{ DRDATA (KPOS, tty_unit[TTI].pos, T_ADDR_W), PV_LEFT },
|
{ DRDATA (KPOS, tty_unit[TTI].pos, T_ADDR_W), PV_LEFT },
|
||||||
|
@ -196,18 +197,18 @@ DEVICE tty_dev = {
|
||||||
|
|
||||||
/* Paper tape reader: IOT routine */
|
/* Paper tape reader: IOT routine */
|
||||||
|
|
||||||
int32 ptr (int32 inst, int32 dev, int32 data)
|
int32 ptr (int32 inst, int32 dev, int32 dat)
|
||||||
{
|
{
|
||||||
iosta = iosta & ~IOS_PTR; /* clear flag */
|
iosta = iosta & ~IOS_PTR; /* clear flag */
|
||||||
if (dev == 0030) return ptr_unit.buf; /* RRB */
|
if (dev == 0030) return ptr_unit.buf; /* RRB */
|
||||||
ptr_state = (dev == 0002)? 18: 0; /* mode = bin/alp */
|
ptr_state = (dev == 0002)? 18: 0; /* mode = bin/alp */
|
||||||
ptr_rpls = 0;
|
|
||||||
ptr_unit.buf = 0; /* clear buffer */
|
ptr_unit.buf = 0; /* clear buffer */
|
||||||
sim_activate (&ptr_unit, ptr_unit.wait);
|
|
||||||
if (GEN_CPLS (inst)) { /* comp pulse? */
|
if (GEN_CPLS (inst)) { /* comp pulse? */
|
||||||
ioc = 0;
|
ioc = 0;
|
||||||
ptr_rpls = 1; }
|
cpls = cpls | CPLS_PTR; }
|
||||||
return data;
|
else cpls = cpls & ~CPLS_PTR;
|
||||||
|
sim_activate (&ptr_unit, ptr_unit.wait);
|
||||||
|
return dat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unit service */
|
/* Unit service */
|
||||||
|
@ -231,10 +232,12 @@ else if (temp & 0200) { /* binary */
|
||||||
ptr_state = ptr_state - 6;
|
ptr_state = ptr_state - 6;
|
||||||
ptr_unit.buf = ptr_unit.buf | ((temp & 077) << ptr_state); }
|
ptr_unit.buf = ptr_unit.buf | ((temp & 077) << ptr_state); }
|
||||||
if (ptr_state == 0) { /* done? */
|
if (ptr_state == 0) { /* done? */
|
||||||
if (ptr_rpls) IO = ptr_unit.buf; /* restart? fill IO */
|
if (cpls & CPLS_PTR) { /* completion pulse? */
|
||||||
|
IO = ptr_unit.buf; /* fill IO */
|
||||||
|
ioc = 1; /* restart */
|
||||||
|
cpls = cpls & ~CPLS_PTR; }
|
||||||
iosta = iosta | IOS_PTR; /* set flag */
|
iosta = iosta | IOS_PTR; /* set flag */
|
||||||
sbs = sbs | SB_RQ; /* req seq break */
|
sbs = sbs | SB_RQ; } /* req seq break */
|
||||||
ioc = ioc | ptr_rpls; } /* restart */
|
|
||||||
else sim_activate (&ptr_unit, ptr_unit.wait); /* get next char */
|
else sim_activate (&ptr_unit, ptr_unit.wait); /* get next char */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
@ -245,7 +248,7 @@ t_stat ptr_reset (DEVICE *dptr)
|
||||||
{
|
{
|
||||||
ptr_state = 0; /* clear state */
|
ptr_state = 0; /* clear state */
|
||||||
ptr_unit.buf = 0;
|
ptr_unit.buf = 0;
|
||||||
ptr_rpls = 0;
|
cpls = cpls & ~CPLS_PTR;
|
||||||
iosta = iosta & ~IOS_PTR; /* clear flag */
|
iosta = iosta & ~IOS_PTR; /* clear flag */
|
||||||
sim_cancel (&ptr_unit); /* deactivate unit */
|
sim_cancel (&ptr_unit); /* deactivate unit */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
@ -253,48 +256,61 @@ return SCPE_OK;
|
||||||
|
|
||||||
/* Bootstrap routine */
|
/* Bootstrap routine */
|
||||||
|
|
||||||
#define BOOT_START 07772
|
int32 ptr_getw (UNIT *uptr)
|
||||||
#define BOOT_LEN (sizeof (boot_rom) / sizeof (int))
|
{
|
||||||
|
int32 i, tmp, word;
|
||||||
|
|
||||||
static const int32 boot_rom[] = {
|
for (i = word = 0; i < 3;) {
|
||||||
0730002, /* r, rpb + wait */
|
if ((tmp = getc (uptr->fileref)) == EOF) return -1;
|
||||||
0327776, /* dio x */
|
uptr->pos = uptr->pos + 1;
|
||||||
0107776, /* xct x */
|
if (tmp & 0200) {
|
||||||
0730002, /* rpb + wait */
|
word = (word << 6) | (tmp & 077);
|
||||||
0760400, /* x, halt */
|
i++; } }
|
||||||
0607772 /* jmp r */
|
return word;
|
||||||
};
|
}
|
||||||
|
|
||||||
t_stat ptr_boot (int32 unitno, DEVICE *dptr)
|
t_stat ptr_boot (int32 unitno, DEVICE *dptr)
|
||||||
{
|
{
|
||||||
int32 i;
|
int32 origin, val;
|
||||||
|
|
||||||
for (i = 0; i < BOOT_LEN; i++) M[BOOT_START + i] = boot_rom[i];
|
for (;;) {
|
||||||
PC = BOOT_START;
|
if ((val = ptr_getw (&ptr_unit)) < 0) return SCPE_FMT;
|
||||||
return SCPE_OK;
|
if (((val & 0760000) == OP_DIO) || /* DIO? */
|
||||||
|
((val & 0760000) == OP_DAC)) { /* hack - Macro1 err */
|
||||||
|
origin = val & 07777;
|
||||||
|
if ((val = ptr_getw (&ptr_unit)) < 0) return SCPE_FMT;
|
||||||
|
M[origin] = val; }
|
||||||
|
else if ((val & 0760000) == OP_JMP) { /* JMP? */
|
||||||
|
PC = val & 007777;
|
||||||
|
break; }
|
||||||
|
else return SCPE_FMT; /* bad instr */
|
||||||
|
}
|
||||||
|
return SCPE_OK; /* done */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Paper tape punch: IOT routine */
|
/* Paper tape punch: IOT routine */
|
||||||
|
|
||||||
int32 ptp (int32 inst, int32 dev, int32 data)
|
int32 ptp (int32 inst, int32 dev, int32 dat)
|
||||||
{
|
{
|
||||||
iosta = iosta & ~IOS_PTP; /* clear flag */
|
iosta = iosta & ~IOS_PTP; /* clear flag */
|
||||||
ptp_rpls = 0;
|
ptp_unit.buf = (dev == 0006)? ((dat >> 12) | 0200): (dat & 0377);
|
||||||
ptp_unit.buf = (dev == 0006)? ((data >> 12) | 0200): (data & 0377);
|
|
||||||
sim_activate (&ptp_unit, ptp_unit.wait); /* start unit */
|
|
||||||
if (GEN_CPLS (inst)) { /* comp pulse? */
|
if (GEN_CPLS (inst)) { /* comp pulse? */
|
||||||
ioc = 0;
|
ioc = 0;
|
||||||
ptp_rpls = 1; }
|
cpls = cpls | CPLS_PTP; }
|
||||||
return data;
|
else cpls = cpls & ~CPLS_PTP;
|
||||||
|
sim_activate (&ptp_unit, ptp_unit.wait); /* start unit */
|
||||||
|
return dat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unit service */
|
/* Unit service */
|
||||||
|
|
||||||
t_stat ptp_svc (UNIT *uptr)
|
t_stat ptp_svc (UNIT *uptr)
|
||||||
{
|
{
|
||||||
|
if (cpls & CPLS_PTP) { /* completion pulse? */
|
||||||
|
ioc = 1; /* restart */
|
||||||
|
cpls = cpls & ~CPLS_PTP; }
|
||||||
iosta = iosta | IOS_PTP; /* set flag */
|
iosta = iosta | IOS_PTP; /* set flag */
|
||||||
sbs = sbs | SB_RQ; /* req seq break */
|
sbs = sbs | SB_RQ; /* req seq break */
|
||||||
ioc = ioc | ptp_rpls; /* process restart */
|
|
||||||
if ((ptp_unit.flags & UNIT_ATT) == 0) /* not attached? */
|
if ((ptp_unit.flags & UNIT_ATT) == 0) /* not attached? */
|
||||||
return IORETURN (ptp_stopioe, SCPE_UNATT);
|
return IORETURN (ptp_stopioe, SCPE_UNATT);
|
||||||
if (putc (ptp_unit.buf, ptp_unit.fileref) == EOF) { /* I/O error? */
|
if (putc (ptp_unit.buf, ptp_unit.fileref) == EOF) { /* I/O error? */
|
||||||
|
@ -310,7 +326,7 @@ return SCPE_OK;
|
||||||
t_stat ptp_reset (DEVICE *dptr)
|
t_stat ptp_reset (DEVICE *dptr)
|
||||||
{
|
{
|
||||||
ptp_unit.buf = 0; /* clear state */
|
ptp_unit.buf = 0; /* clear state */
|
||||||
ptp_rpls = 0;
|
cpls = cpls & ~CPLS_PTP;
|
||||||
iosta = iosta & ~IOS_PTP; /* clear flag */
|
iosta = iosta & ~IOS_PTP; /* clear flag */
|
||||||
sim_cancel (&ptp_unit); /* deactivate unit */
|
sim_cancel (&ptp_unit); /* deactivate unit */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
@ -318,7 +334,7 @@ return SCPE_OK;
|
||||||
|
|
||||||
/* Typewriter IOT routines */
|
/* Typewriter IOT routines */
|
||||||
|
|
||||||
int32 tti (int32 inst, int32 dev, int32 data)
|
int32 tti (int32 inst, int32 dev, int32 dat)
|
||||||
{
|
{
|
||||||
iosta = iosta & ~IOS_TTI; /* clear flag */
|
iosta = iosta & ~IOS_TTI; /* clear flag */
|
||||||
if (inst & (IO_WAIT | IO_CPLS)) /* wait or sync? */
|
if (inst & (IO_WAIT | IO_CPLS)) /* wait or sync? */
|
||||||
|
@ -326,16 +342,16 @@ if (inst & (IO_WAIT | IO_CPLS)) /* wait or sync? */
|
||||||
return tty_buf & 077;
|
return tty_buf & 077;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 tto (int32 inst, int32 dev, int32 data)
|
int32 tto (int32 inst, int32 dev, int32 dat)
|
||||||
{
|
{
|
||||||
iosta = iosta & ~IOS_TTO; /* clear flag */
|
iosta = iosta & ~IOS_TTO; /* clear flag */
|
||||||
tto_rpls = 0;
|
tty_buf = dat & TT_WIDTH; /* load buffer */
|
||||||
tty_buf = data & TT_WIDTH; /* load buffer */
|
|
||||||
sim_activate (&tty_unit[TTO], tty_unit[TTO].wait); /* activate unit */
|
|
||||||
if (GEN_CPLS (inst)) { /* comp pulse? */
|
if (GEN_CPLS (inst)) { /* comp pulse? */
|
||||||
ioc = 0;
|
ioc = 0;
|
||||||
tto_rpls = 1; }
|
cpls = cpls | CPLS_TTO; }
|
||||||
return data;
|
else cpls = cpls & ~CPLS_TTO;
|
||||||
|
sim_activate (&tty_unit[TTO], tty_unit[TTO].wait); /* activate unit */
|
||||||
|
return dat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unit service routines */
|
/* Unit service routines */
|
||||||
|
@ -373,9 +389,11 @@ t_stat tto_svc (UNIT *uptr)
|
||||||
{
|
{
|
||||||
int32 out;
|
int32 out;
|
||||||
|
|
||||||
|
if (cpls & CPLS_TTO) { /* completion pulse? */
|
||||||
|
ioc = 1; /* restart */
|
||||||
|
cpls = cpls & ~CPLS_TTO; }
|
||||||
iosta = iosta | IOS_TTO; /* set flag */
|
iosta = iosta | IOS_TTO; /* set flag */
|
||||||
sbs = sbs | SB_RQ; /* req seq break */
|
sbs = sbs | SB_RQ; /* req seq break */
|
||||||
ioc = ioc | tto_rpls; /* process restart */
|
|
||||||
if (tty_buf == FIODEC_UC) { /* upper case? */
|
if (tty_buf == FIODEC_UC) { /* upper case? */
|
||||||
tty_uc = UC;
|
tty_uc = UC;
|
||||||
return SCPE_OK; }
|
return SCPE_OK; }
|
||||||
|
@ -399,7 +417,7 @@ t_stat tty_reset (DEVICE *dptr)
|
||||||
tty_buf = 0; /* clear buffer */
|
tty_buf = 0; /* clear buffer */
|
||||||
tty_uc = 0; /* clear case */
|
tty_uc = 0; /* clear case */
|
||||||
tti_hold = 0; /* clear hold buf */
|
tti_hold = 0; /* clear hold buf */
|
||||||
tto_rpls = 0; /* clear reset pulse */
|
cpls = cpls & ~CPLS_TTO;
|
||||||
iosta = (iosta & ~IOS_TTI) | IOS_TTO; /* clear flag */
|
iosta = (iosta & ~IOS_TTI) | IOS_TTO; /* clear flag */
|
||||||
sim_activate (&tty_unit[TTI], tty_unit[TTI].wait); /* activate keyboard */
|
sim_activate (&tty_unit[TTI], tty_unit[TTI].wait); /* activate keyboard */
|
||||||
sim_cancel (&tty_unit[TTO]); /* stop printer */
|
sim_cancel (&tty_unit[TTO]); /* stop printer */
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
in this Software without prior written authorization from Robert M Supnik.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
22-Jul-03 RMS Updated for "hardware" RIM loader
|
||||||
05-Dec-02 RMS Added drum support
|
05-Dec-02 RMS Added drum support
|
||||||
21-Nov-02 RMS Changed typewriter to half duplex
|
21-Nov-02 RMS Changed typewriter to half duplex
|
||||||
20-Aug-02 RMS Added DECtape support
|
20-Aug-02 RMS Added DECtape support
|
||||||
|
@ -52,6 +53,7 @@ extern int32 M[];
|
||||||
extern int32 PC;
|
extern int32 PC;
|
||||||
extern int32 ascii_to_fiodec[], fiodec_to_ascii[];
|
extern int32 ascii_to_fiodec[], fiodec_to_ascii[];
|
||||||
extern int32 sc_map[];
|
extern int32 sc_map[];
|
||||||
|
extern int32 sim_switches;
|
||||||
|
|
||||||
/* SCP data structures and interface routines
|
/* SCP data structures and interface routines
|
||||||
|
|
||||||
|
@ -86,44 +88,83 @@ const char *sim_stop_messages[] = {
|
||||||
"Breakpoint",
|
"Breakpoint",
|
||||||
"Nested XCT's",
|
"Nested XCT's",
|
||||||
"Nested indirect addresses",
|
"Nested indirect addresses",
|
||||||
"Infinite wait state" };
|
"Infinite I/O wait state" };
|
||||||
|
|
||||||
/* Binary loader
|
/* Binary loader - supports both RIM format and Macro block format */
|
||||||
|
|
||||||
At the moment, implements RIM loader format
|
int32 getw (FILE *inf)
|
||||||
*/
|
|
||||||
|
|
||||||
int32 getword (FILE *fileref)
|
|
||||||
{
|
{
|
||||||
int32 i, tmp, word;
|
int32 i, tmp, word;
|
||||||
|
|
||||||
word = 0;
|
word = 0;
|
||||||
for (i = 0; i < 3;) {
|
for (i = 0; i < 3;) {
|
||||||
if ((tmp = getc (fileref)) == EOF) return -1;
|
if ((tmp = getc (inf)) == EOF) return -1;
|
||||||
if (tmp & 0200) {
|
if (tmp & 0200) {
|
||||||
word = (word << 6) | (tmp & 077);
|
word = (word << 6) | (tmp & 077);
|
||||||
i++; } }
|
i++; } }
|
||||||
return word;
|
return word;
|
||||||
}
|
}
|
||||||
|
|
||||||
t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag)
|
t_stat rim_load (FILE *inf)
|
||||||
{
|
{
|
||||||
int32 origin, val;
|
int32 origin, val;
|
||||||
|
|
||||||
if ((*cptr != 0) || (flag != 0)) return SCPE_ARG;
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if ((val = getword (fileref)) < 0) return SCPE_FMT;
|
if ((val = getw (inf)) < 0) return SCPE_FMT;
|
||||||
if (((val & 0770000) == 0320000) || /* DIO? */
|
if (((val & 0760000) == OP_DIO) || /* DIO? */
|
||||||
((val & 0770000) == 0240000)) { /* DAC? - incorrect */
|
((val & 0760000) == OP_DAC)) { /* hack - Macro1 err */
|
||||||
origin = val & 07777;
|
origin = val & 07777;
|
||||||
if ((val = getword (fileref)) < 0) return SCPE_FMT;
|
if ((val = getw (inf)) < 0) return SCPE_FMT;
|
||||||
if (MEM_ADDR_OK (origin)) M[origin++] = val; }
|
M[origin] = val; }
|
||||||
else if ((val & 0770000) == 0600000) { /* JMP? */
|
else if ((val & 0760000) == OP_JMP) { /* JMP? */
|
||||||
PC = val & 007777;
|
PC = val & 007777;
|
||||||
break; }
|
break; }
|
||||||
|
else return SCPE_FMT; /* bad instr */
|
||||||
}
|
}
|
||||||
return SCPE_OK; /* done */
|
return SCPE_OK; /* done */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t_stat blk_load (FILE *inf)
|
||||||
|
{
|
||||||
|
int32 val, start, count, csum;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
if ((val = getw (inf)) < 0) return SCPE_FMT; /* get word, EOF? */
|
||||||
|
if ((val & 0760000) == OP_DIO) { /* DIO? */
|
||||||
|
csum = val; /* init checksum */
|
||||||
|
start = val & 07777; /* starting addr */
|
||||||
|
if ((val = getw (inf)) < 0) return SCPE_FMT;
|
||||||
|
if ((val & 0760000) != OP_DIO) return SCPE_FMT;
|
||||||
|
csum = csum + val;
|
||||||
|
if (csum > 0777777) csum = (csum + 1) & 0777777;
|
||||||
|
count = (val & 07777) - start + 1; /* block count */
|
||||||
|
if (count <= 0) return SCPE_FMT;
|
||||||
|
while (count--) { /* loop on data */
|
||||||
|
if ((val = getw (inf)) < 0) return SCPE_FMT;
|
||||||
|
csum = csum + val;
|
||||||
|
if (csum > 0777777) csum = (csum + 1) & 0777777;
|
||||||
|
M[start++] = val; }
|
||||||
|
if ((val = getw (inf)) < 0) return SCPE_FMT;
|
||||||
|
if (val != csum) return SCPE_CSUM; }
|
||||||
|
else if ((val & 0760000) == OP_JMP) { /* JMP? */
|
||||||
|
PC = val & 007777;
|
||||||
|
break; }
|
||||||
|
else return SCPE_FMT; /* bad instr */
|
||||||
|
}
|
||||||
|
return SCPE_OK; /* done */
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag)
|
||||||
|
{
|
||||||
|
t_stat sta;
|
||||||
|
|
||||||
|
if ((*cptr != 0) || (flag != 0)) return SCPE_ARG;
|
||||||
|
sta = rim_load (fileref);
|
||||||
|
if (sta != SCPE_OK) return sta;
|
||||||
|
if ((sim_switches & SWMASK ('B')) || match_ext (fnam, "BIN"))
|
||||||
|
return blk_load (fileref);
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/* Symbol tables */
|
/* Symbol tables */
|
||||||
|
|
||||||
|
|
|
@ -40,15 +40,17 @@ To compile the PDP-10, you must define VM_PDP10 and USE_INT64 as part of the
|
||||||
compilation command line.
|
compilation command line.
|
||||||
|
|
||||||
sim/ sim_defs.h
|
sim/ sim_defs.h
|
||||||
|
sim_ether.h
|
||||||
sim_rev.h
|
sim_rev.h
|
||||||
sim_sock.h
|
sim_sock.h
|
||||||
|
sim_tape.h
|
||||||
sim_tmxr.h
|
sim_tmxr.h
|
||||||
sim_ether.h
|
|
||||||
scp.c
|
scp.c
|
||||||
scp_tty.c
|
scp_tty.c
|
||||||
sim_sock.c
|
|
||||||
sim_tmxr.c
|
|
||||||
sim_ether.c
|
sim_ether.c
|
||||||
|
sim_sock.c
|
||||||
|
sim_tape.c
|
||||||
|
sim_tmxr.c
|
||||||
|
|
||||||
sim/pdp10/ pdp10_defs.h
|
sim/pdp10/ pdp10_defs.h
|
||||||
pdp10_cpu.c
|
pdp10_cpu.c
|
||||||
|
@ -117,11 +119,14 @@ the file format to try to determine the file type.
|
||||||
|
|
||||||
The CPU options allow the user to specify standard microcode, standard
|
The CPU options allow the user to specify standard microcode, standard
|
||||||
microcode with a bug fix for a boostrap problem in TOPS-20 V4.1, or ITS
|
microcode with a bug fix for a boostrap problem in TOPS-20 V4.1, or ITS
|
||||||
microcode
|
microcode:
|
||||||
|
|
||||||
SET CPU STANDARD Standard microcode
|
SET CPU STANDARD Standard microcode
|
||||||
SET CPU TOPS20V41 Standard microcode with TOPS-20 V4.1 bug fix
|
SET CPU TOPS20V41 Standard microcode with TOPS-20 V4.1 bug fix
|
||||||
SET CPU ITS ITS compatible microcode
|
SET CPU ITS ITS compatible microcode
|
||||||
|
|
||||||
|
The CPU implements a SHOW command to display the I/O space address map:
|
||||||
|
|
||||||
SHOW CPU IOSPACE show I/O space address map
|
SHOW CPU IOSPACE show I/O space address map
|
||||||
|
|
||||||
CPU registers include the visible state of the processor as well as the
|
CPU registers include the visible state of the processor as well as the
|
||||||
|
@ -200,7 +205,7 @@ The front end is the system console. The keyboard input is unit 0,
|
||||||
the console output is unit 1. It supports two options:
|
the console output is unit 1. It supports two options:
|
||||||
|
|
||||||
SET FE STOP halts the PDP-10 operating system
|
SET FE STOP halts the PDP-10 operating system
|
||||||
SET FE CTLC simulates typing ^C (for Windoze)
|
SET FE CTLC simulates typing ^C
|
||||||
|
|
||||||
The front end has the following registers:
|
The front end has the following registers:
|
||||||
|
|
||||||
|
@ -333,7 +338,10 @@ the port to be used:
|
||||||
where port is a decimal number between 1 and 65535 that is not being used
|
where port is a decimal number between 1 and 65535 that is not being used
|
||||||
for other TCP/IP activities. The optional switch -m turns on the DZ11's
|
for other TCP/IP activities. The optional switch -m turns on the DZ11's
|
||||||
modem controls; the optional switch -a turns on active disconnects
|
modem controls; the optional switch -a turns on active disconnects
|
||||||
(disconnect session if computer clears Data Terminal Ready).
|
(disconnect session if computer clears Data Terminal Ready). Without
|
||||||
|
modem control, the DZ behaves as though terminals were directly connected;
|
||||||
|
disconnecting the Telnet session does not cause any operating system-
|
||||||
|
visible change in line status.
|
||||||
|
|
||||||
Once the DZ is attached and the simulator is running, the DZ will listen
|
Once the DZ is attached and the simulator is running, the DZ will listen
|
||||||
for connections on the specified port. It assumes that the incoming
|
for connections on the specified port. It assumes that the incoming
|
||||||
|
@ -526,8 +534,6 @@ locked, single or double density, or autosized:
|
||||||
SET RYn DOUBLE set unit n double density (default)
|
SET RYn DOUBLE set unit n double density (default)
|
||||||
SET RYn AUTOSIZE set unit n autosized
|
SET RYn AUTOSIZE set unit n autosized
|
||||||
|
|
||||||
The RX211 supports the BOOT command, but only for double density.
|
|
||||||
|
|
||||||
The floppy disk requires an unsupported driver under TOPS-10 and
|
The floppy disk requires an unsupported driver under TOPS-10 and
|
||||||
is not supported under TOPS-20 or ITS.
|
is not supported under TOPS-20 or ITS.
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
rp RH/RP/RM moving head disks
|
rp RH/RP/RM moving head disks
|
||||||
|
|
||||||
|
23-Jul-03 RMS Fixed bug in read header stub
|
||||||
25-Apr-03 RMS Revised for extended file support
|
25-Apr-03 RMS Revised for extended file support
|
||||||
21-Nov-02 RMS Fixed bug in bootstrap (reported by Michael Thompson)
|
21-Nov-02 RMS Fixed bug in bootstrap (reported by Michael Thompson)
|
||||||
29-Sep-02 RMS Added variable vector support
|
29-Sep-02 RMS Added variable vector support
|
||||||
|
@ -834,14 +835,14 @@ case FNC_READH: /* read headers */
|
||||||
vpn = PAG_GETVPN (pa10); /* map addr */
|
vpn = PAG_GETVPN (pa10); /* map addr */
|
||||||
if ((vpn >= UMAP_MEMSIZE) || (ba & XBA_MBZ) || (rpwc & XWC_MBZ) ||
|
if ((vpn >= UMAP_MEMSIZE) || (ba & XBA_MBZ) || (rpwc & XWC_MBZ) ||
|
||||||
((ubmap[0][vpn] & (UMAP_VLD | UMAP_DSB | UMAP_RRV)) != UMAP_VLD)) {
|
((ubmap[0][vpn] & (UMAP_VLD | UMAP_DSB | UMAP_RRV)) != UMAP_VLD)) {
|
||||||
rpcs2 = rpcs2 | CS2_NEM; /* set error */
|
rpcs2 = rpcs2 | CS2_NEM; /* set error */
|
||||||
ubcs[0] = ubcs[0] | UBCS_TMO; /* UBA times out */
|
ubcs[0] = ubcs[0] | UBCS_TMO; /* UBA times out */
|
||||||
break; }
|
break; }
|
||||||
mpa10 = (ubmap[0][vpn] + PAG_GETOFF (pa10)) & PAMASK;
|
mpa10 = (ubmap[0][vpn] + PAG_GETOFF (pa10)) & PAMASK;
|
||||||
if (MEM_ADDR_NXM (mpa10)) { /* nx memory? */
|
if (MEM_ADDR_NXM (mpa10)) { /* nx memory? */
|
||||||
rpcs2 = rpcs2 | CS2_NEM; /* set error */
|
rpcs2 = rpcs2 | CS2_NEM; /* set error */
|
||||||
ubcs[0] = ubcs[0] | UBCS_TMO; /* UBA times out */
|
ubcs[0] = ubcs[0] | UBCS_TMO; /* UBA times out */
|
||||||
break; }
|
break; }
|
||||||
dbuf[twc10] = M[mpa10]; /* write to disk */
|
dbuf[twc10] = M[mpa10]; /* write to disk */
|
||||||
if ((rpcs2 & CS2_UAI) == 0) ba = ba + 4; }
|
if ((rpcs2 & CS2_UAI) == 0) ba = ba + 4; }
|
||||||
if (fc10 = twc10 & (RP_NUMWD - 1)) { /* fill? */
|
if (fc10 = twc10 & (RP_NUMWD - 1)) { /* fill? */
|
||||||
|
@ -850,7 +851,7 @@ case FNC_READH: /* read headers */
|
||||||
fxwrite (dbuf, sizeof (d10), twc10 + fc10, uptr->fileref);
|
fxwrite (dbuf, sizeof (d10), twc10 + fc10, uptr->fileref);
|
||||||
err = ferror (uptr->fileref);
|
err = ferror (uptr->fileref);
|
||||||
} /* end if */
|
} /* end if */
|
||||||
else { /* read, wchk */
|
else { /* read, wchk, readh */
|
||||||
awc10 = fxread (dbuf, sizeof (d10), wc10, uptr->fileref);
|
awc10 = fxread (dbuf, sizeof (d10), wc10, uptr->fileref);
|
||||||
err = ferror (uptr->fileref);
|
err = ferror (uptr->fileref);
|
||||||
for ( ; awc10 < wc10; awc10++) dbuf[awc10] = 0;
|
for ( ; awc10 < wc10; awc10++) dbuf[awc10] = 0;
|
||||||
|
@ -859,18 +860,20 @@ case FNC_READH: /* read headers */
|
||||||
vpn = PAG_GETVPN (pa10); /* map addr */
|
vpn = PAG_GETVPN (pa10); /* map addr */
|
||||||
if ((vpn >= UMAP_MEMSIZE) || (ba & XBA_MBZ) || (rpwc & XWC_MBZ) ||
|
if ((vpn >= UMAP_MEMSIZE) || (ba & XBA_MBZ) || (rpwc & XWC_MBZ) ||
|
||||||
((ubmap[0][vpn] & (UMAP_VLD | UMAP_DSB | UMAP_RRV)) != UMAP_VLD)) {
|
((ubmap[0][vpn] & (UMAP_VLD | UMAP_DSB | UMAP_RRV)) != UMAP_VLD)) {
|
||||||
rpcs2 = rpcs2 | CS2_NEM; /* set error */
|
rpcs2 = rpcs2 | CS2_NEM; /* set error */
|
||||||
ubcs[0] = ubcs[0] | UBCS_TMO; /* UBA times out */
|
ubcs[0] = ubcs[0] | UBCS_TMO; /* UBA times out */
|
||||||
break; }
|
break; }
|
||||||
mpa10 = (ubmap[0][vpn] + PAG_GETOFF (pa10)) & PAMASK;
|
mpa10 = (ubmap[0][vpn] + PAG_GETOFF (pa10)) & PAMASK;
|
||||||
if (MEM_ADDR_NXM (mpa10)) { /* nx memory? */
|
if (MEM_ADDR_NXM (mpa10)) { /* nx memory? */
|
||||||
rpcs2 = rpcs2 | CS2_NEM; /* set error */
|
rpcs2 = rpcs2 | CS2_NEM; /* set error */
|
||||||
ubcs[0] = ubcs[0] | UBCS_TMO; /* UBA times out */
|
ubcs[0] = ubcs[0] | UBCS_TMO; /* UBA times out */
|
||||||
break; }
|
break; }
|
||||||
if (uptr->FUNC == FNC_READ) M[mpa10] = dbuf[twc10];
|
if ((uptr->FUNC == FNC_READ) || /* read or */
|
||||||
else if (M[mpa10] != dbuf[twc10]) {
|
(uptr->FUNC == FNC_READH)) /* read header */
|
||||||
rpcs2 = rpcs2 | CS2_WCE; /* set error */
|
M[mpa10] = dbuf[twc10];
|
||||||
break; }
|
else if (M[mpa10] != dbuf[twc10]) { /* wchk, mismatch? */
|
||||||
|
rpcs2 = rpcs2 | CS2_WCE; /* set error */
|
||||||
|
break; }
|
||||||
if ((rpcs2 & CS2_UAI) == 0) ba = ba + 4; }
|
if ((rpcs2 & CS2_UAI) == 0) ba = ba + 4; }
|
||||||
} /* end else */
|
} /* end else */
|
||||||
|
|
||||||
|
|
|
@ -678,7 +678,7 @@ if (trap_req) { /* check traps, ints */
|
||||||
if (t = trap_req & TRAP_ALL) { /* if a trap */
|
if (t = trap_req & TRAP_ALL) { /* if a trap */
|
||||||
for (trapnum = 0; trapnum < TRAP_V_MAX; trapnum++) {
|
for (trapnum = 0; trapnum < TRAP_V_MAX; trapnum++) {
|
||||||
if ((t >> trapnum) & 1) { /* trap set? */
|
if ((t >> trapnum) & 1) { /* trap set? */
|
||||||
trapea = trap_vec[trapnum]; /* get vec, clr */
|
trapea = trap_vec[trapnum]; /* get vec, clr */
|
||||||
trap_req = trap_req & ~trap_clear[trapnum];
|
trap_req = trap_req & ~trap_clear[trapnum];
|
||||||
if ((stop_trap >> trapnum) & 1) /* stop on trap? */
|
if ((stop_trap >> trapnum) & 1) /* stop on trap? */
|
||||||
reason = trapnum + 1;
|
reason = trapnum + 1;
|
||||||
|
@ -785,7 +785,7 @@ case 000:
|
||||||
setCPUERR (CPUE_HALT); }
|
setCPUERR (CPUE_HALT); }
|
||||||
break;
|
break;
|
||||||
case 1: /* WAIT */
|
case 1: /* WAIT */
|
||||||
if (cm == MD_KER && wait_enable) wait_state = 1;
|
if ((cm == MD_KER) && wait_enable) wait_state = 1;
|
||||||
break;
|
break;
|
||||||
case 3: /* BPT */
|
case 3: /* BPT */
|
||||||
setTRAP (TRAP_BPT);
|
setTRAP (TRAP_BPT);
|
||||||
|
@ -838,8 +838,8 @@ case 000:
|
||||||
if ((IR == 000002) && tbit) setTRAP (TRAP_TRC);
|
if ((IR == 000002) && tbit) setTRAP (TRAP_TRC);
|
||||||
break;
|
break;
|
||||||
case 7: /* MFPT */
|
case 7: /* MFPT */
|
||||||
R[0] = 5; /* report J-11 */
|
R[0] = 5; /* report J-11 */
|
||||||
break; } /* end switch no ops */
|
break; } /* end switch no ops */
|
||||||
break; /* end case no ops */
|
break; /* end case no ops */
|
||||||
|
|
||||||
/* Opcode 0: specials, continued */
|
/* Opcode 0: specials, continued */
|
||||||
|
@ -1378,7 +1378,7 @@ case 007:
|
||||||
case 5: /* FIS - not impl */
|
case 5: /* FIS - not impl */
|
||||||
setTRAP (TRAP_ILL);
|
setTRAP (TRAP_ILL);
|
||||||
break;
|
break;
|
||||||
case 6: /* CIS - not impl */
|
case 6: /* CIS */
|
||||||
if (cpu_unit.flags & UNIT_CIS) cis11 (IR);
|
if (cpu_unit.flags & UNIT_CIS) cis11 (IR);
|
||||||
else setTRAP (TRAP_ILL);
|
else setTRAP (TRAP_ILL);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
To: Users
|
To: Users
|
||||||
From: Bob Supnik
|
From: Bob Supnik
|
||||||
Subj: PDP-11 Simulator Usage
|
Subj: PDP-11 Simulator Usage
|
||||||
Date: 15-Mar-2003
|
Date: 15-Jul-2003
|
||||||
|
|
||||||
COPYRIGHT NOTICE
|
COPYRIGHT NOTICE
|
||||||
|
|
||||||
|
@ -40,11 +40,13 @@ sim/ sim_defs.h
|
||||||
sim_ether.h
|
sim_ether.h
|
||||||
sim_rev.h
|
sim_rev.h
|
||||||
sim_sock.h
|
sim_sock.h
|
||||||
|
sim_tape.h
|
||||||
sim_tmxr.h
|
sim_tmxr.h
|
||||||
scp.c
|
scp.c
|
||||||
scp_tty.c
|
scp_tty.c
|
||||||
sim_ether.c
|
sim_ether.c
|
||||||
sim_sock.c
|
sim_sock.c
|
||||||
|
sim_tape.c
|
||||||
sim_tmxr.c
|
sim_tmxr.c
|
||||||
|
|
||||||
sim/pdp11/ pdp11_defs.h
|
sim/pdp11/ pdp11_defs.h
|
||||||
|
@ -154,6 +156,9 @@ with RH70-style controllers, 22b Unibus with RH11 style controllers, and
|
||||||
SET CPU 2048K (or 2M) set memory size = 2048KB
|
SET CPU 2048K (or 2M) set memory size = 2048KB
|
||||||
SET CPU 3072K (or 3M) set memory size = 3072KB
|
SET CPU 3072K (or 3M) set memory size = 3072KB
|
||||||
SET CPU 4096K (or 4M) set memory size = 4096KB
|
SET CPU 4096K (or 4M) set memory size = 4096KB
|
||||||
|
|
||||||
|
The CPU implements a show command to display the I/O address space map:
|
||||||
|
|
||||||
SHOW CPU IOSPACE show I/O space address map
|
SHOW CPU IOSPACE show I/O space address map
|
||||||
|
|
||||||
If memory size is being reduced, and the memory being truncated contains
|
If memory size is being reduced, and the memory being truncated contains
|
||||||
|
@ -486,7 +491,7 @@ clock is disabled by default.
|
||||||
The DZ11 is an 8-line terminal multiplexor. Up to 4 DZ11's (32 lines)
|
The DZ11 is an 8-line terminal multiplexor. Up to 4 DZ11's (32 lines)
|
||||||
are supported. The number of lines can be changed with the command
|
are supported. The number of lines can be changed with the command
|
||||||
|
|
||||||
SET DZ LINES=n set line count to n
|
SET DZ LINES=n set line count to n
|
||||||
|
|
||||||
The line count must be a multiple of 8, with a maximum of 32.
|
The line count must be a multiple of 8, with a maximum of 32.
|
||||||
|
|
||||||
|
@ -501,12 +506,15 @@ The terminal lines perform input and output through Telnet sessions
|
||||||
connected to a user-specified port. The ATTACH command specifies
|
connected to a user-specified port. The ATTACH command specifies
|
||||||
the port to be used:
|
the port to be used:
|
||||||
|
|
||||||
ATTACH {-am} DZ <port> set up listening port
|
ATTACH {-am} DZ <port> set up listening port
|
||||||
|
|
||||||
where port is a decimal number between 1 and 65535 that is not being used
|
where port is a decimal number between 1 and 65535 that is not being used
|
||||||
for other TCP/IP activities. The optional switch -m turns on the DZ11's
|
for other TCP/IP activities. The optional switch -m turns on the DZ11's
|
||||||
modem controls; the optional switch -a turns on active disconnects
|
modem controls; the optional switch -a turns on active disconnects
|
||||||
(disconnect session if computer clears Data Terminal Ready).
|
(disconnect session if computer clears Data Terminal Ready). Without
|
||||||
|
modem control, the DZ behaves as though terminals were directly connected;
|
||||||
|
disconnecting the Telnet session does not cause any operating system-
|
||||||
|
visible change in line status.
|
||||||
|
|
||||||
Once the DZ is attached and the simulator is running, the DZ will listen
|
Once the DZ is attached and the simulator is running, the DZ will listen
|
||||||
for connections on the specified port. It assumes that the incoming
|
for connections on the specified port. It assumes that the incoming
|
||||||
|
@ -876,6 +884,10 @@ of many disk types:
|
||||||
SET RQn RAUSER{=n} set type to RA81 with n LBNs
|
SET RQn RAUSER{=n} set type to RA81 with n LBNs
|
||||||
|
|
||||||
The type options can be used only when a unit is not attached to a file.
|
The type options can be used only when a unit is not attached to a file.
|
||||||
|
RAUSER is a "user specified" disk; the user can specify the size of the
|
||||||
|
disk in logical block numbers (LBN's, 512 bytes each). The minimum size
|
||||||
|
is 50MB; the maximum size is 2GB.
|
||||||
|
|
||||||
Units can also be set ONLINE or OFFLINE. Each RQ controller supports the
|
Units can also be set ONLINE or OFFLINE. Each RQ controller supports the
|
||||||
BOOT command. In a Unibus system, an RQ supports 18b addressing. In
|
BOOT command. In a Unibus system, an RQ supports 18b addressing. In
|
||||||
a Qbus (22B) system, an RQ supports 22b addressing.
|
a Qbus (22B) system, an RQ supports 22b addressing.
|
||||||
|
@ -928,13 +940,13 @@ crash on boot or to hang during operation.
|
||||||
|
|
||||||
Error handling is as follows:
|
Error handling is as follows:
|
||||||
|
|
||||||
error processed as
|
error processed as
|
||||||
|
|
||||||
not attached disk not ready
|
not attached disk not ready
|
||||||
|
|
||||||
end of file assume rest of disk is zero
|
end of file assume rest of disk is zero
|
||||||
|
|
||||||
OS I/O error report error and stop
|
OS I/O error report error and stop
|
||||||
|
|
||||||
2.8 TC11/TU56 DECtape (DT)
|
2.8 TC11/TU56 DECtape (DT)
|
||||||
|
|
||||||
|
@ -1227,18 +1239,18 @@ controller will behave as though the ethernet cable were unplugged.
|
||||||
|
|
||||||
XQ has the following registers:
|
XQ has the following registers:
|
||||||
|
|
||||||
name size comments
|
name size comments
|
||||||
|
|
||||||
SA0 16 station address word 0
|
SA0 16 station address word 0
|
||||||
SA1 16 station address word 1
|
SA1 16 station address word 1
|
||||||
SA2 16 station address word 2
|
SA2 16 station address word 2
|
||||||
SA3 16 station address word 3
|
SA3 16 station address word 3
|
||||||
SA4 16 station address word 4
|
SA4 16 station address word 4
|
||||||
SA5 16 station address word 5
|
SA5 16 station address word 5
|
||||||
CSR 16 control status register
|
CSR 16 control status register
|
||||||
VAR 16 vector address register
|
VAR 16 vector address register
|
||||||
RBDL 32 receive buffer descriptor list
|
RBDL 32 receive buffer descriptor list
|
||||||
XBDL 32 trans(X)mit buffer descriptorlList
|
XBDL 32 trans(X)mit buffer descriptorlList
|
||||||
|
|
||||||
One final note: because of it's asynchronous nature, the XQ controller is
|
One final note: because of it's asynchronous nature, the XQ controller is
|
||||||
not limited to the ~1.5Mbit/sec of the real DEQNA/DELQA controllers,
|
not limited to the ~1.5Mbit/sec of the real DEQNA/DELQA controllers,
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
rq RQDX3 disk controller
|
rq RQDX3 disk controller
|
||||||
|
|
||||||
|
11-Jul-03 RMS Fixed bug in user disk size (found by Chaskiel M Grundman)
|
||||||
19-May-03 RMS Revised for new conditional compilation scheme
|
19-May-03 RMS Revised for new conditional compilation scheme
|
||||||
25-Apr-03 RMS Revised for extended file support
|
25-Apr-03 RMS Revised for extended file support
|
||||||
14-Mar-03 RMS Fixed variable size interaction with save/restore
|
14-Mar-03 RMS Fixed variable size interaction with save/restore
|
||||||
|
@ -2009,7 +2010,7 @@ if ((val < 0) || (val > RA8U_DTYPE) || ((val != RA8U_DTYPE) && cptr))
|
||||||
return SCPE_ARG;
|
return SCPE_ARG;
|
||||||
if (uptr->flags & UNIT_ATT) return SCPE_ALATT;
|
if (uptr->flags & UNIT_ATT) return SCPE_ALATT;
|
||||||
if (cptr) {
|
if (cptr) {
|
||||||
cap = (int32) get_uint (cptr, 10, RA8U_MAXC, &r);
|
cap = (int32) get_uint (cptr, 10, max, &r);
|
||||||
if ((r != SCPE_OK) || (cap < RA8U_MINC)) return SCPE_ARG;
|
if ((r != SCPE_OK) || (cap < RA8U_MINC)) return SCPE_ARG;
|
||||||
drv_tab[val].lbn = cap << (20 - 9); }
|
drv_tab[val].lbn = cap << (20 - 9); }
|
||||||
uptr->flags = (uptr->flags & ~UNIT_DTYPE) | (val << UNIT_V_DTYPE);
|
uptr->flags = (uptr->flags & ~UNIT_DTYPE) | (val << UNIT_V_DTYPE);
|
||||||
|
|
1211
PDP18B/pdp18b_cpu.c
1211
PDP18B/pdp18b_cpu.c
File diff suppressed because it is too large
Load diff
|
@ -23,6 +23,9 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
in this Software without prior written authorization from Robert M Supnik.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
18-Jul-03 RMS Added FP15 support
|
||||||
|
Added XVM support
|
||||||
|
Added EAE option for PDP-4
|
||||||
25-Apr-03 RMS Revised for extended file support
|
25-Apr-03 RMS Revised for extended file support
|
||||||
04-Feb-03 RMS Added RB09, LP09 support
|
04-Feb-03 RMS Added RB09, LP09 support
|
||||||
22-Nov-02 RMS Added PDP-4 drum support
|
22-Nov-02 RMS Added PDP-4 drum support
|
||||||
|
@ -48,7 +51,7 @@
|
||||||
|
|
||||||
model memory CPU options I/O options
|
model memory CPU options I/O options
|
||||||
|
|
||||||
PDP4 8K ??Type 18 EAE Type 65 KSR-28 Teletype (Baudot)
|
PDP4 8K Type 18 EAE Type 65 KSR-28 Teletype (Baudot)
|
||||||
integral paper tape reader
|
integral paper tape reader
|
||||||
Type 75 paper tape punch
|
Type 75 paper tape punch
|
||||||
integral real time clock
|
integral real time clock
|
||||||
|
@ -79,19 +82,19 @@
|
||||||
KA15 auto pri intr PC15 paper tape reader and punch
|
KA15 auto pri intr PC15 paper tape reader and punch
|
||||||
KF15 power detection KW15 real time clock
|
KF15 power detection KW15 real time clock
|
||||||
KM15 mem protection LP09 line printer
|
KM15 mem protection LP09 line printer
|
||||||
??KT15 mem relocation LP15 line printer
|
KT15 mem relocation LP15 line printer
|
||||||
RP15 disk pack
|
FP15 floating point RP15 disk pack
|
||||||
RF15/RF09 fixed head disk
|
XVM option RF15/RF09 fixed head disk
|
||||||
TC59D magnetic tape
|
TC59D magnetic tape
|
||||||
TC15/TU56 DECtape
|
TC15/TU56 DECtape
|
||||||
LT15 second Teletype
|
LT15 second Teletype
|
||||||
|
|
||||||
??Indicates not implemented. The PDP-4 manual refers to both an EAE
|
??Indicates not implemented. The PDP-4 manual refers to a memory
|
||||||
??and a memory extension control; there is no documentation on either.
|
??extension control; there is no documentation on it.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined (PDP4) && !defined (PDP7) && !defined (PDP9) && !defined (PDP15)
|
#if !defined (PDP4) && !defined (PDP7) && !defined (PDP9) && !defined (PDP15)
|
||||||
#define PDP9 0 /* default to PDP-9 */
|
#define PDP15 0 /* default to PDP-15 */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Simulator stop codes */
|
/* Simulator stop codes */
|
||||||
|
@ -102,6 +105,7 @@
|
||||||
#define STOP_XCT 4 /* nested XCT's */
|
#define STOP_XCT 4 /* nested XCT's */
|
||||||
#define STOP_API 5 /* invalid API int */
|
#define STOP_API 5 /* invalid API int */
|
||||||
#define STOP_NONSTD 6 /* non-std dev num */
|
#define STOP_NONSTD 6 /* non-std dev num */
|
||||||
|
#define STOP_MME 7 /* mem mgt error */
|
||||||
|
|
||||||
/* Peripheral configuration */
|
/* Peripheral configuration */
|
||||||
|
|
||||||
|
@ -136,17 +140,49 @@
|
||||||
#define TC02 0 /* DECtape */
|
#define TC02 0 /* DECtape */
|
||||||
#define TTY1 0 /* second Teletype */
|
#define TTY1 0 /* second Teletype */
|
||||||
#define BRMASK 0377400 /* bounds mask */
|
#define BRMASK 0377400 /* bounds mask */
|
||||||
|
#define BRMASK_XVM 0777400 /* bounds mask, XVM */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Memory */
|
/* Memory */
|
||||||
|
|
||||||
#define ADDRMASK ((1 << ADDRSIZE) - 1) /* address mask */
|
#define AMASK ((1 << ADDRSIZE) - 1) /* address mask */
|
||||||
#define IAMASK 077777 /* ind address mask */
|
#define IAMASK 077777 /* ind address mask */
|
||||||
#define BLKMASK (ADDRMASK & (~IAMASK)) /* block mask */
|
#define BLKMASK (AMASK & (~IAMASK)) /* block mask */
|
||||||
#define MAXMEMSIZE (1 << ADDRSIZE) /* max memory size */
|
#define MAXMEMSIZE (1 << ADDRSIZE) /* max memory size */
|
||||||
#define MEMSIZE (cpu_unit.capac) /* actual memory size */
|
#define MEMSIZE (cpu_unit.capac) /* actual memory size */
|
||||||
#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
|
#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
|
||||||
|
|
||||||
|
/* Instructions */
|
||||||
|
|
||||||
|
#define I_V_OP 14 /* opcode */
|
||||||
|
#define I_M_OP 017
|
||||||
|
#define I_V_IND 13 /* indirect */
|
||||||
|
#define I_V_IDX 12 /* index */
|
||||||
|
#define I_IND (1 << I_V_IND)
|
||||||
|
#define I_IDX (1 << I_V_IDX)
|
||||||
|
#define B_DAMASK 017777 /* bank mode address */
|
||||||
|
#define B_EPCMASK (AMASK & ~B_DAMASK)
|
||||||
|
#define P_DAMASK 007777 /* page mode address */
|
||||||
|
#define P_EPCMASK (AMASK & ~P_DAMASK)
|
||||||
|
|
||||||
|
/* Memory cycles */
|
||||||
|
|
||||||
|
#define FE 0
|
||||||
|
#define DF 1
|
||||||
|
#define RD 2
|
||||||
|
#define WR 3
|
||||||
|
|
||||||
|
/* Memory status codes */
|
||||||
|
|
||||||
|
#define MM_OK 0
|
||||||
|
#define MM_ERR 1
|
||||||
|
|
||||||
|
/* Memory management relocation checks (PDP-15 KT15 and XVM only) */
|
||||||
|
|
||||||
|
#define REL_C -1 /* console */
|
||||||
|
#define REL_R 0 /* read */
|
||||||
|
#define REL_W 1 /* write */
|
||||||
|
|
||||||
/* Architectural constants */
|
/* Architectural constants */
|
||||||
|
|
||||||
#define DMASK 0777777 /* data mask */
|
#define DMASK 0777777 /* data mask */
|
||||||
|
@ -165,6 +201,39 @@
|
||||||
#define IOT_REASON (1 << IOT_V_REASON)
|
#define IOT_REASON (1 << IOT_V_REASON)
|
||||||
|
|
||||||
#define IORETURN(f,v) ((f)? (v): SCPE_OK) /* stop on error */
|
#define IORETURN(f,v) ((f)? (v): SCPE_OK) /* stop on error */
|
||||||
|
|
||||||
|
/* PC change queue */
|
||||||
|
|
||||||
|
#define PCQ_SIZE 64 /* must be 2**n */
|
||||||
|
#define PCQ_MASK (PCQ_SIZE - 1)
|
||||||
|
#define PCQ_ENTRY pcq[pcq_p = (pcq_p - 1) & PCQ_MASK] = PC
|
||||||
|
|
||||||
|
/* XVM memory management registers */
|
||||||
|
|
||||||
|
#define MM_RDIS 0400000 /* reloc disabled */
|
||||||
|
#define MM_V_GM 15 /* G mode */
|
||||||
|
#define MM_M_GM 03
|
||||||
|
#define MM_GM (MM_M_GM << MM_V_GM)
|
||||||
|
#define MM_G_W0 0077777 /* virt addr width */
|
||||||
|
#define MM_G_W1 0177777
|
||||||
|
#define MM_G_W2 0777777
|
||||||
|
#define MM_G_W3 0377777
|
||||||
|
#define MM_G_B0 0060000 /* SAS base */
|
||||||
|
#define MM_G_B1 0160000
|
||||||
|
#define MM_G_B2 0760000
|
||||||
|
#define MM_G_B3 0360000
|
||||||
|
#define MM_UIOT 0040000 /* user mode IOT's */
|
||||||
|
#define MM_WP 0020000 /* share write prot */
|
||||||
|
#define MM_SH 0010000 /* share enabled */
|
||||||
|
#define MM_V_SLR 10 /* segment length reg */
|
||||||
|
#define MM_M_SLR 03
|
||||||
|
#define MM_SLR_L0 001000 /* SAS length */
|
||||||
|
#define MM_SLR_L1 002000
|
||||||
|
#define MM_SLR_L2 010000
|
||||||
|
#define MM_SLR_L3 020000
|
||||||
|
#define MM_SBR_MASK 01777 /* share base reg */
|
||||||
|
#define MM_GETGM(x) (((x) >> MM_V_GM) & MM_M_GM)
|
||||||
|
#define MM_GETSLR(x) (((x) >> MM_V_SLR) & MM_M_SLR)
|
||||||
|
|
||||||
/* Device information block */
|
/* Device information block */
|
||||||
|
|
||||||
|
@ -239,6 +308,15 @@ typedef struct pdp18b_dib DIB;
|
||||||
37 -
|
37 -
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define API_ML0 0200 /* API masks: level 0 */
|
||||||
|
#define API_ML1 0100
|
||||||
|
#define API_ML2 0040
|
||||||
|
#define API_ML3 0020
|
||||||
|
#define API_ML4 0010
|
||||||
|
#define API_ML5 0004
|
||||||
|
#define API_ML6 0002
|
||||||
|
#define API_ML7 0001 /* level 7 */
|
||||||
|
|
||||||
#define API_HLVL 4 /* hwre levels */
|
#define API_HLVL 4 /* hwre levels */
|
||||||
#define ACH_SWRE 040 /* swre int vec */
|
#define ACH_SWRE 040 /* swre int vec */
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
To: Users
|
To: Users
|
||||||
From: Bob Supnik
|
From: Bob Supnik
|
||||||
Subj: 18b PDP Simulator Usage
|
Subj: 18b PDP Simulator Usage
|
||||||
Date: 01-Feb-2003
|
Date: 25-Jul-2003
|
||||||
|
|
||||||
COPYRIGHT NOTICE
|
COPYRIGHT NOTICE
|
||||||
|
|
||||||
|
@ -44,29 +44,33 @@ PDP-7/ PDP7
|
||||||
PDP-9/ PDP9
|
PDP-9/ PDP9
|
||||||
PDP-15/ PDP15
|
PDP-15/ PDP15
|
||||||
|
|
||||||
If no model is specified, the default is the PDP-9.
|
If no model is specified, the default is the PDP-15.
|
||||||
|
|
||||||
sim/ sim_defs.h
|
PDP-4 PDP-7 PDP-9 PDP-15
|
||||||
sim_rev.h
|
sim/ sim_defs.h x x x x
|
||||||
sim_sock.h
|
sim_rev.h x x x x
|
||||||
sim_tmxr.h
|
sim_sock.h x x x x
|
||||||
scp.c
|
sim_tape.h x x
|
||||||
scp_tty.c
|
sim_tmxr.h x x x x
|
||||||
sim_sock.c
|
scp.c x x x x
|
||||||
sim_tmxr.c
|
scp_tty.c x x x x
|
||||||
|
sim_sock.c x x x x
|
||||||
|
sim_tape.c x x
|
||||||
|
sim_tmxr.c x x x x
|
||||||
|
|
||||||
sim/pdp18b/ pdp18b_defs.h
|
sim/pdp18b/ pdp18b_defs.h x x x x
|
||||||
pdp18b_cpu.c
|
pdp18b_cpu.c x x x x
|
||||||
pdp18b_drm.c
|
pdp18b_drm.c x x
|
||||||
pdp18b_dt.c
|
pdp18b_dt.c x x x x
|
||||||
pdp18b_lp.c
|
pdp18b_fpp.c x
|
||||||
pdp18b_mt.c
|
pdp18b_lp.c x x x x
|
||||||
pdp18b_rb.c
|
pdp18b_mt.c x x
|
||||||
pdp18b_rf.c
|
pdp18b_rb.c x
|
||||||
pdp18b_rp.c
|
pdp18b_rf.c x x
|
||||||
pdp18b_stddev.c
|
pdp18b_rp.c x
|
||||||
pdp18b_sys.c
|
pdp18b_stddev.c x x x x
|
||||||
pdp18b_tt1.c
|
pdp18b_sys.c x x x x
|
||||||
|
pdp18b_tt1.c x x
|
||||||
|
|
||||||
2. 18b PDP Features
|
2. 18b PDP Features
|
||||||
|
|
||||||
|
@ -77,6 +81,7 @@ system device simulates
|
||||||
name(s)
|
name(s)
|
||||||
|
|
||||||
PDP-4 CPU PDP-4 CPU with 8KW of memory
|
PDP-4 CPU PDP-4 CPU with 8KW of memory
|
||||||
|
- Type 18 extended arithmetic element (EAE)
|
||||||
PTR,PTP integral paper tape/Type 75 punch
|
PTR,PTP integral paper tape/Type 75 punch
|
||||||
TTI,TTO KSR28 console terminal (Baudot code)
|
TTI,TTO KSR28 console terminal (Baudot code)
|
||||||
LPT Type 62 line printer (Hollerith code)
|
LPT Type 62 line printer (Hollerith code)
|
||||||
|
@ -116,6 +121,9 @@ PDP-15 CPU PDP-15 CPU with 32KW of memory
|
||||||
- KA15 automatic priority interrupt (API)
|
- KA15 automatic priority interrupt (API)
|
||||||
- KF15 power detection
|
- KF15 power detection
|
||||||
- KM15 memory protection
|
- KM15 memory protection
|
||||||
|
- KT15 memory relocation and protection
|
||||||
|
- XVM memory relocation and protection
|
||||||
|
FPP FP15 floating point processor
|
||||||
PTR,PTP PC15 paper tape reader/punch
|
PTR,PTP PC15 paper tape reader/punch
|
||||||
TTI,TTO KSR 35 console terminal
|
TTI,TTO KSR 35 console terminal
|
||||||
TTI1,TTO1 LT15 second console terminal
|
TTI1,TTO1 LT15 second console terminal
|
||||||
|
@ -145,36 +153,58 @@ The 18b PDP simulators implement several unique stop conditions:
|
||||||
- more than XCTMAX nested executes are detected during
|
- more than XCTMAX nested executes are detected during
|
||||||
instruction execution
|
instruction execution
|
||||||
|
|
||||||
The PDP-4 and PDP-7 loaders support only RIM format tapes. The PDP-9
|
The PDP-4 and PDP-7 LOAD command supports only "second stage" RIM format
|
||||||
and PDP-15 support both RIM and BIN format tapes. If the file extension
|
files (alternating DAC address instructions and data):
|
||||||
is .RIM, or the -r switch is specified with LOAD, the file is assumed to
|
|
||||||
be RIM format; if the file extension is not .RIM, or if the -b switch is
|
LOAD file load PDP-4/PDP-7 RIM format file
|
||||||
specified, the file is assumed to be BIN format. RIM loading requires
|
|
||||||
that the loading address be specified on the command line.
|
The PDP-9 and PDP-15 LOAD commands upports hardware RIM format (data only),
|
||||||
|
PDP-4/PDP-7 RIM loader format (for compatability with Macro7), and BIN
|
||||||
|
loader format:
|
||||||
|
|
||||||
|
LOAD -S file load PDP-4/PDP-7 RIM format file
|
||||||
|
LOAD -R file address load PDP-9/PDP-15 RIM format
|
||||||
|
file starting at address
|
||||||
|
LOAD file.RIM address assume file is PDP-9/PDP-15
|
||||||
|
RIM format
|
||||||
|
LOAD -B file load PDP-9/PDP-15 BIN format file
|
||||||
|
LOAD file.BIN assume file is PDP-9/PDP-15
|
||||||
|
BIN format
|
||||||
|
|
||||||
|
If no address is given for a RIM format load, a starting address of 200
|
||||||
|
(octal) is assumed. If no switch is specified, and the file extension is
|
||||||
|
neither RIM nor BIN, the file format is assumed to be BIN.
|
||||||
|
|
||||||
2.1 CPU
|
2.1 CPU
|
||||||
|
|
||||||
The CPU options are the presence of the EAE, the presense of the API (for
|
The CPU options are the presence of the EAE, the presense of the API and
|
||||||
the PDP-9 and PDP-15), and the size of main memory.
|
memory protection (for the PDP-9 and PDP-15), the presense of relocation
|
||||||
|
or XVM (PDP-15 only), and the size of main memory.
|
||||||
|
|
||||||
SET CPU EAE enable EAE
|
system option comment
|
||||||
SET CPU NOEAE disable EAE
|
|
||||||
SET CPU API enable API
|
all SET CPU EAE enable EAE
|
||||||
SET CPU NOAPI disable API
|
all SET CPU NOEAE disable EAE
|
||||||
SET CPU 4K set memory size = 4K
|
9,15 SET CPU API enable API
|
||||||
SET CPU 8K set memory size = 8K
|
9,15 SET CPU NOAPI disable API
|
||||||
SET CPU 12K set memory size = 12K
|
9,15 SET CPU PROT enable memory protection
|
||||||
SET CPU 16K set memory size = 16K
|
15 SET CPU RELOC enable memory relocation
|
||||||
SET CPU 20K set memory size = 20K
|
15 SET CPU XVM enable XVM relocation
|
||||||
SET CPU 24K set memory size = 24K
|
9,15 SET CPU NOPROT disable protection, relocation, XVM
|
||||||
SET CPU 28K set memory size = 28K
|
4 SET CPU 4K set memory size = 4K
|
||||||
SET CPU 32K set memory size = 32K
|
all SET CPU 8K set memory size = 8K
|
||||||
SET CPU 48K set memory size = 48K
|
all SET CPU 12K set memory size = 12K
|
||||||
SET CPU 64K set memory size = 64K
|
all SET CPU 16K set memory size = 16K
|
||||||
SET CPU 80K set memory size = 80K
|
all SET CPU 20K set memory size = 20K
|
||||||
SET CPU 96K set memory size = 96K
|
all SET CPU 24K set memory size = 24K
|
||||||
SET CPU 112K set memory size = 112K
|
all SET CPU 28K set memory size = 28K
|
||||||
SET CPU 128K set memory size = 128K
|
all SET CPU 32K set memory size = 32K
|
||||||
|
15 SET CPU 48K set memory size = 48K
|
||||||
|
15 SET CPU 64K set memory size = 64K
|
||||||
|
15 SET CPU 80K set memory size = 80K
|
||||||
|
15 SET CPU 96K set memory size = 96K
|
||||||
|
15 SET CPU 112K set memory size = 112K
|
||||||
|
15 SET CPU 128K set memory size = 128K
|
||||||
|
|
||||||
Memory sizes greater than 8K are only available on the PDP-7, PDP-9, and
|
Memory sizes greater than 8K are only available on the PDP-7, PDP-9, and
|
||||||
PDP-15; memory sizes greater than 32KW are only available on the PDP-15.
|
PDP-15; memory sizes greater than 32KW are only available on the PDP-15.
|
||||||
|
@ -183,6 +213,12 @@ non-zero data, the simulator asks for confirmation. Data in the truncated
|
||||||
portion of memory is lost. Initial memory size is 8K for the PDP-4, 32K
|
portion of memory is lost. Initial memory size is 8K for the PDP-4, 32K
|
||||||
for the PDP-7 and PDP-9, and 128K for the PDP-15.
|
for the PDP-7 and PDP-9, and 128K for the PDP-15.
|
||||||
|
|
||||||
|
The PROT option corresponds to the KX09A on the PDP-9 and the KM15 for the
|
||||||
|
PDP-15. The PROT option is required to run the Foreground/Background
|
||||||
|
Monitor. The RELOC option corresponds to the KT15 on the PDP-15, and the
|
||||||
|
XVM option corresponds to the XM15 on the PDP-15. ADSS-15, ADSS-15 Foreground/
|
||||||
|
Background, and standard DOS-15 will <not> run if these options are enabled.
|
||||||
|
|
||||||
CPU registers include the visible state of the processor as well as the
|
CPU registers include the visible state of the processor as well as the
|
||||||
control registers for the interrupt system.
|
control registers for the interrupt system.
|
||||||
|
|
||||||
|
@ -191,10 +227,11 @@ control registers for the interrupt system.
|
||||||
all PC addr program counter
|
all PC addr program counter
|
||||||
all AC 18 accumulator
|
all AC 18 accumulator
|
||||||
all L 1 link
|
all L 1 link
|
||||||
7,9,15 MQ 18 multiplier-quotient
|
all MQ 18 multiplier-quotient
|
||||||
7,9,15 SC 6 shift counter
|
all SC 6 shift counter
|
||||||
7,9,15 EAE_AC_SIGN 1 EAE AC sign
|
all EAE_AC_SIGN 1 EAE AC sign
|
||||||
all SR 18 front panel switches
|
all SR 18 front panel switches
|
||||||
|
all ASW addr address switches for RIM load
|
||||||
all INT[0:4] 32 interrupt requests,
|
all INT[0:4] 32 interrupt requests,
|
||||||
0:3 = API levels 0-3
|
0:3 = API levels 0-3
|
||||||
4 = PI level
|
4 = PI level
|
||||||
|
@ -204,12 +241,15 @@ control registers for the interrupt system.
|
||||||
9,15 APIENB 1 API enable
|
9,15 APIENB 1 API enable
|
||||||
9,15 APIREQ 8 API requesting levels
|
9,15 APIREQ 8 API requesting levels
|
||||||
9,15 APIACT 8 API active levels
|
9,15 APIACT 8 API active levels
|
||||||
9,15 BR addr memory protection bounds
|
9,15 BR 18 memory protection bounds
|
||||||
15 XR 18 index register
|
15 XR 18 index register
|
||||||
15 LR 18 limit register
|
15 LR 18 limit register
|
||||||
15 BR 17 memory protection bounds
|
9,15 BR 18 memory protection bounds
|
||||||
|
15 RR 18 memory protection relocation
|
||||||
|
15 MMR 18 memory protection control
|
||||||
9,15 USMD 1 user mode
|
9,15 USMD 1 user mode
|
||||||
9,15 USMDBUF 1 user mode buffer
|
9,15 USMDBUF 1 user mode buffer
|
||||||
|
9,15 USMDDEF 1 user mode load defer
|
||||||
9,15 NEXM 1 non-existent memory violation
|
9,15 NEXM 1 non-existent memory violation
|
||||||
9,15 PRVN 1 privilege violation
|
9,15 PRVN 1 privilege violation
|
||||||
7,9 EXTM 1 extend mode
|
7,9 EXTM 1 extend mode
|
||||||
|
@ -229,18 +269,49 @@ control registers for the interrupt system.
|
||||||
"addr" signifies the address width of the system (13b for the PDP-4, 15b for
|
"addr" signifies the address width of the system (13b for the PDP-4, 15b for
|
||||||
the PDP-7 and PDP-9, 17b for the PDP-15).
|
the PDP-7 and PDP-9, 17b for the PDP-15).
|
||||||
|
|
||||||
2.2 Programmed I/O Devices
|
2.2 Floating Point Processor (FPP)
|
||||||
|
|
||||||
2.2.1 Paper Tape Reader (PTR)
|
The PDP-15 features an optional floating point processor, the FP15 (FPP).
|
||||||
|
The FPP can be enabled and disabled; by default it is disabled.
|
||||||
|
|
||||||
|
The FPP implements these registers:
|
||||||
|
|
||||||
|
name size comments
|
||||||
|
|
||||||
|
FIR 12 floating instruction register
|
||||||
|
EPA 18 EPA (A exponent)
|
||||||
|
FMAS 1 FMA sign
|
||||||
|
FMAH 17 FMA<1:17>
|
||||||
|
FMAL 18 FMA<18:35>
|
||||||
|
EPB 18 EPB (B exponent)
|
||||||
|
FMBS 1 FMB sign
|
||||||
|
FMBH 17 FMB<1:17>
|
||||||
|
FMBL 18 FMB<18:35>
|
||||||
|
FGUARD 1 guard bit
|
||||||
|
FMQH 17 FMQ<1:17>
|
||||||
|
FMQL 18 FMQ<18:35>
|
||||||
|
JEA 18 exception address register
|
||||||
|
|
||||||
|
2.3 Programmed I/O Devices
|
||||||
|
|
||||||
|
2.3.1 Paper Tape Reader (PTR)
|
||||||
|
|
||||||
The paper tape reader (PTR) reads data from a disk file. The POS
|
The paper tape reader (PTR) reads data from a disk file. The POS
|
||||||
register specifies the number of the next data item to be read. Thus,
|
register specifies the number of the next data item to be read. Thus,
|
||||||
by changing POS, the user can backspace or advance the reader.
|
by changing POS, the user can backspace or advance the reader.
|
||||||
|
|
||||||
On the PDP-4 and PDP-7, the paper tape reader supports the BOOT command.
|
The paper tape reader supports the BOOT command. The specific forms
|
||||||
BOOT PTR copies the RIM loader into memory and starts it running, while
|
recognized vary from system to system:
|
||||||
BOOT -F PTR copies the funny format binary loader into memory and starts
|
|
||||||
it running.
|
BOOT PTR PDP-4, PDP-7: load RIM loader and start it running
|
||||||
|
BOOT -F PTR PDP-4, PDP-7: load funny format loader and start
|
||||||
|
it running
|
||||||
|
BOOT -H PTR PDP-7: start hardware RIM load at address given
|
||||||
|
by address switches (ASW)
|
||||||
|
BOOT {-H} PTR PDP-9, PDP-15: start hardware RIM load at addrss
|
||||||
|
given by address switches (ASW)
|
||||||
|
|
||||||
|
The PDP-4 did not have a hardware read-in mode load capability.
|
||||||
|
|
||||||
The PTR ATTACH command recognizes one switch, -A for ASCII mode. In
|
The PTR ATTACH command recognizes one switch, -A for ASCII mode. In
|
||||||
ASCII mode, data returned by the read alphabetic command has even parity.
|
ASCII mode, data returned by the read alphabetic command has even parity.
|
||||||
|
@ -270,7 +341,7 @@ Error handling is as follows:
|
||||||
|
|
||||||
OS I/O error x report error and stop
|
OS I/O error x report error and stop
|
||||||
|
|
||||||
2.2.2 Paper Tape Punch (PTP)
|
2.3.2 Paper Tape Punch (PTP)
|
||||||
|
|
||||||
The paper tape punch (PTP) writes data to a disk file. The POS
|
The paper tape punch (PTP) writes data to a disk file. The POS
|
||||||
register specifies the number of the next data item to be written.
|
register specifies the number of the next data item to be written.
|
||||||
|
@ -302,7 +373,7 @@ Error handling is as follows:
|
||||||
|
|
||||||
OS I/O error x report error and stop
|
OS I/O error x report error and stop
|
||||||
|
|
||||||
2.2.3 Terminal Input (TTI)
|
2.3.3 Terminal Input (TTI)
|
||||||
|
|
||||||
On the PDP-7, PDP-9, and PDP-15, the terminal interfaces (TTI, TTO)
|
On the PDP-7, PDP-9, and PDP-15, the terminal interfaces (TTI, TTO)
|
||||||
can be set to one of three modes: KSR, 7B, or 8B. In KSR mode, lower
|
can be set to one of three modes: KSR, 7B, or 8B. In KSR mode, lower
|
||||||
|
@ -333,7 +404,7 @@ to simulate typing ^C:
|
||||||
|
|
||||||
SET TTI CTRL-C
|
SET TTI CTRL-C
|
||||||
|
|
||||||
2.2.4 Terminal Output (TTO)
|
2.3.4 Terminal Output (TTO)
|
||||||
|
|
||||||
The terminal output (TTO) writes to the simulator console window. It
|
The terminal output (TTO) writes to the simulator console window. It
|
||||||
implements these registers:
|
implements these registers:
|
||||||
|
@ -346,7 +417,7 @@ implements these registers:
|
||||||
POS 32 number of chararacters output
|
POS 32 number of chararacters output
|
||||||
TIME 24 time from I/O initiation to interrupt
|
TIME 24 time from I/O initiation to interrupt
|
||||||
|
|
||||||
2.2.5 Line Printers (LPT, LP9)
|
2.3.5 Line Printers (LPT, LP9)
|
||||||
|
|
||||||
The line printers (LPT, LP9) write data to a disk file. The POS
|
The line printers (LPT, LP9) write data to a disk file. The POS
|
||||||
register specifies the number of the next data item to be written.
|
register specifies the number of the next data item to be written.
|
||||||
|
@ -423,7 +494,7 @@ For all printers, error handling is as follows:
|
||||||
|
|
||||||
OS I/O error x report error and stop
|
OS I/O error x report error and stop
|
||||||
|
|
||||||
2.2.6 Real-Time Clock (CLK)
|
2.3.6 Real-Time Clock (CLK)
|
||||||
|
|
||||||
The real-time clock (CLK) frequency can be adjusted as follows:
|
The real-time clock (CLK) frequency can be adjusted as follows:
|
||||||
|
|
||||||
|
@ -444,7 +515,7 @@ The clock implements these registers:
|
||||||
The real-time clock autocalibrates; the clock interval is adjusted up or
|
The real-time clock autocalibrates; the clock interval is adjusted up or
|
||||||
down so that the clock tracks actual elapsed time.
|
down so that the clock tracks actual elapsed time.
|
||||||
|
|
||||||
2.2.7 Second Terminal (TTI1, TTO1)
|
2.3.7 Second Terminal (TTI1, TTO1)
|
||||||
|
|
||||||
The second terminal consists of two independent devices, TTI1 and TTO1.
|
The second terminal consists of two independent devices, TTI1 and TTO1.
|
||||||
The second terminal performs input and output through a Telnet session
|
The second terminal performs input and output through a Telnet session
|
||||||
|
@ -491,7 +562,7 @@ The second terminal output implements these registers:
|
||||||
DONE 1 device done flag
|
DONE 1 device done flag
|
||||||
TIME 24 time from I/O initiation to interrupt
|
TIME 24 time from I/O initiation to interrupt
|
||||||
|
|
||||||
2.3 RP15/RP02 Disk Pack (RP)
|
2.4 RP15/RP02 Disk Pack (RP)
|
||||||
|
|
||||||
RP15 options include the ability to make units write enabled or write locked:
|
RP15 options include the ability to make units write enabled or write locked:
|
||||||
|
|
||||||
|
@ -526,7 +597,7 @@ Error handling is as follows:
|
||||||
|
|
||||||
OS I/O error x report error and stop
|
OS I/O error x report error and stop
|
||||||
|
|
||||||
2.4 Type 24 Serial Drum (DRM)
|
2.5 Type 24 Serial Drum (DRM)
|
||||||
|
|
||||||
The serial drum (DRM) implements these registers:
|
The serial drum (DRM) implements these registers:
|
||||||
|
|
||||||
|
@ -551,7 +622,7 @@ Error handling is as follows:
|
||||||
Drum data files are buffered in memory; therefore, end of file and OS
|
Drum data files are buffered in memory; therefore, end of file and OS
|
||||||
I/O errors cannot occur.
|
I/O errors cannot occur.
|
||||||
|
|
||||||
2.5 RB09 Fixed Head Disk (RB)
|
2.6 RB09 Fixed Head Disk (RB)
|
||||||
|
|
||||||
The RB09 was an early fixed-head disk for the PDP-9. It was superceded
|
The RB09 was an early fixed-head disk for the PDP-9. It was superceded
|
||||||
by the RF09/RS09. It is disabled by default.
|
by the RF09/RS09. It is disabled by default.
|
||||||
|
@ -585,7 +656,7 @@ Error handling is as follows:
|
||||||
RB09 data files are buffered in memory; therefore, end of file and OS
|
RB09 data files are buffered in memory; therefore, end of file and OS
|
||||||
I/O errors cannot occur.
|
I/O errors cannot occur.
|
||||||
|
|
||||||
2.5 RF09/RF15/RS09 Fixed Head Disk (RF)
|
2.7 RF09/RF15/RS09 Fixed Head Disk (RF)
|
||||||
|
|
||||||
RF09/RF15 options include the ability to set the number of platters
|
RF09/RF15 options include the ability to set the number of platters
|
||||||
to a fixed value between 1 and 8, or to autosize the number of platters
|
to a fixed value between 1 and 8, or to autosize the number of platters
|
||||||
|
@ -632,7 +703,7 @@ Error handling is as follows:
|
||||||
RF15/RF09 data files are buffered in memory; therefore, end of file and OS
|
RF15/RF09 data files are buffered in memory; therefore, end of file and OS
|
||||||
I/O errors cannot occur.
|
I/O errors cannot occur.
|
||||||
|
|
||||||
2.6 Type 550/555, TC02/TU55, and TC15/TU56 DECtape (DT)
|
2.8 Type 550/555, TC02/TU55, and TC15/TU56 DECtape (DT)
|
||||||
|
|
||||||
The PDP-4 and PDP-7 use the Type 550 DECtape, a programmed I/O controller.
|
The PDP-4 and PDP-7 use the Type 550 DECtape, a programmed I/O controller.
|
||||||
The PDP-9 uses the TC02, and the PDP-15 uses the TC15. The TC02 and TC15
|
The PDP-9 uses the TC02, and the PDP-15 uses the TC15. The TC02 and TC15
|
||||||
|
@ -693,7 +764,7 @@ operate correctly.
|
||||||
- ACTIME must be less than DCTIME, and both need to be at
|
- ACTIME must be less than DCTIME, and both need to be at
|
||||||
least 100 times LTIME
|
least 100 times LTIME
|
||||||
|
|
||||||
2.7 TC59/TU10 Magnetic Tape (MT)
|
2.9 TC59/TU10 Magnetic Tape (MT)
|
||||||
|
|
||||||
Magnetic tape options include the ability to make units write enabled or
|
Magnetic tape options include the ability to make units write enabled or
|
||||||
or write locked.
|
or write locked.
|
||||||
|
@ -727,7 +798,7 @@ Error handling is as follows:
|
||||||
|
|
||||||
OS I/O error parity error; if STOP_IOE, stop
|
OS I/O error parity error; if STOP_IOE, stop
|
||||||
|
|
||||||
2.8 Symbolic Display and Input
|
2.10 Symbolic Display and Input
|
||||||
|
|
||||||
The 18b PDP simulators implement symbolic display and input. Display is
|
The 18b PDP simulators implement symbolic display and input. Display is
|
||||||
controlled by command line switches:
|
controlled by command line switches:
|
||||||
|
@ -754,15 +825,18 @@ The PDP-15 also recognizes an additional input mode:
|
||||||
# or -p five character packed ASCII string in
|
# or -p five character packed ASCII string in
|
||||||
two 18b words
|
two 18b words
|
||||||
|
|
||||||
Instruction input uses standard 18b PDP assembler syntax. There are six
|
Instruction input uses standard 18b PDP assembler syntax. There are eight
|
||||||
instruction classes: memory reference, EAE, index (PDP-15 only), IOT,
|
instruction classes: memory reference, EAE, index (PDP-15 only), IOT,
|
||||||
operate, and LAW.
|
operate, LAW, FP15 memory reference (PDP-15 only), and FP15 no operand
|
||||||
|
(PDP-15 only).
|
||||||
|
|
||||||
Memory reference instructions have the format
|
Memory reference instructions have the format
|
||||||
|
|
||||||
memref {I/@} address{,X}
|
PDP-4, PDP-7: memref {I} address
|
||||||
|
PDP-9: memref{*} address
|
||||||
|
PDP-15: memref{*} address{,X}
|
||||||
|
|
||||||
where I (PDP-4, PDP-7, PDP-9) /@ (PDP-15) signifies indirect reference,
|
where I (PDP-4, PDP-7) /* (PDP-9, PDP-15) signifies indirect reference,
|
||||||
and X signifies indexing (PDP-15 in page mode only). The address is an
|
and X signifies indexing (PDP-15 in page mode only). The address is an
|
||||||
octal number in the range 0 - 017777 (PDP-4, PDP-7, PDP-9, and PDP-15 in
|
octal number in the range 0 - 017777 (PDP-4, PDP-7, PDP-9, and PDP-15 in
|
||||||
bank mode) or 0 - 07777 (PDP-15 in page mode).
|
bank mode) or 0 - 07777 (PDP-15 in page mode).
|
||||||
|
@ -805,13 +879,27 @@ Operate instructions have the format
|
||||||
The simulator does not check the legality of the proposed combination. The
|
The simulator does not check the legality of the proposed combination. The
|
||||||
operands for MUY and DVI must be deposited explicitly.
|
operands for MUY and DVI must be deposited explicitly.
|
||||||
|
|
||||||
Finally, the LAW instruction has the format
|
The LAW instruction has the format
|
||||||
|
|
||||||
LAW immediate
|
LAW immediate
|
||||||
|
|
||||||
where immediate is in the range of 0 to 017777.
|
where immediate is in the range of 0 to 017777.
|
||||||
|
|
||||||
2.9 Character Sets
|
FP15 memory reference instructions occupy two successive words and have
|
||||||
|
the format
|
||||||
|
|
||||||
|
fpmem{*} address
|
||||||
|
|
||||||
|
where * signifies indirect addressing. The address is a number in the range
|
||||||
|
0 - 0377777.
|
||||||
|
|
||||||
|
FP15 no operand instructions occupy two successive words and have the format
|
||||||
|
|
||||||
|
fpop
|
||||||
|
|
||||||
|
The second word is ignored on output and set to 0 on input.
|
||||||
|
|
||||||
|
2.11 Character Sets
|
||||||
|
|
||||||
The PDP-4's console was an ASR-28 Teletype; its character encoding was
|
The PDP-4's console was an ASR-28 Teletype; its character encoding was
|
||||||
Baudot. The PDP-4's line printer used a modified Hollerith character
|
Baudot. The PDP-4's line printer used a modified Hollerith character
|
||||||
|
|
|
@ -221,10 +221,10 @@ static const int32 boot_rom[] = {
|
||||||
t_stat drm_boot (int32 unitno, DEVICE *dptr)
|
t_stat drm_boot (int32 unitno, DEVICE *dptr)
|
||||||
{
|
{
|
||||||
int32 i;
|
int32 i;
|
||||||
extern int32 saved_PC;
|
extern int32 PC;
|
||||||
|
|
||||||
if (drm_dib.dev != DEV_DRM) return STOP_NONSTD; /* non-std addr? */
|
if (drm_dib.dev != DEV_DRM) return STOP_NONSTD; /* non-std addr? */
|
||||||
for (i = 0; i < BOOT_LEN; i++) M[BOOT_START + i] = boot_rom[i];
|
for (i = 0; i < BOOT_LEN; i++) M[BOOT_START + i] = boot_rom[i];
|
||||||
saved_PC = BOOT_START;
|
PC = BOOT_START;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -327,8 +327,8 @@ static const int32 map_unit[16] = { /* Type 550 unit map */
|
||||||
0, -1, -1, -1, -1, -1, -1, -1 };
|
0, -1, -1, -1, -1, -1, -1, -1 };
|
||||||
|
|
||||||
DEVICE dt_dev;
|
DEVICE dt_dev;
|
||||||
int32 dt75 (int32 pulse, int32 AC);
|
int32 dt75 (int32 pulse, int32 dat);
|
||||||
int32 dt76 (int32 pulse, int32 AC);
|
int32 dt76 (int32 pulse, int32 dat);
|
||||||
int32 dt_iors (void);
|
int32 dt_iors (void);
|
||||||
t_stat dt_svc (UNIT *uptr);
|
t_stat dt_svc (UNIT *uptr);
|
||||||
t_stat dt_reset (DEVICE *dptr);
|
t_stat dt_reset (DEVICE *dptr);
|
||||||
|
@ -423,18 +423,18 @@ DEVICE dt_dev = {
|
||||||
/* IOT routines */
|
/* IOT routines */
|
||||||
|
|
||||||
#if defined (TC02) /* TC02/TC15 */
|
#if defined (TC02) /* TC02/TC15 */
|
||||||
int32 dt75 (int32 pulse, int32 AC)
|
int32 dt75 (int32 pulse, int32 dat)
|
||||||
{
|
{
|
||||||
int32 old_dtsa = dtsa, fnc;
|
int32 old_dtsa = dtsa, fnc;
|
||||||
UNIT *uptr;
|
UNIT *uptr;
|
||||||
|
|
||||||
if (((pulse & 060) == 040) && (pulse & 05)) { /* select */
|
if (((pulse & 060) == 040) && (pulse & 05)) { /* select */
|
||||||
if (pulse & 01) dtsa = 0; /* DTCA */
|
if (pulse & 01) dtsa = 0; /* DTCA */
|
||||||
if (pulse & 02) AC = dtsa; /* DTRA!... */
|
if (pulse & 02) dat = dtsa; /* DTRA!... */
|
||||||
if (pulse & 04) { /* DTXA */
|
if (pulse & 04) { /* DTXA */
|
||||||
if ((AC & DTA_CERF) == 0) dtsb = dtsb & ~DTB_ALLERR;
|
if ((dat & DTA_CERF) == 0) dtsb = dtsb & ~DTB_ALLERR;
|
||||||
if ((AC & DTA_CDTF) == 0) dtsb = dtsb & ~DTB_DTF;
|
if ((dat & DTA_CDTF) == 0) dtsb = dtsb & ~DTB_DTF;
|
||||||
dtsa = dtsa ^ (AC & DTA_RW); }
|
dtsa = dtsa ^ (dat & DTA_RW); }
|
||||||
if ((old_dtsa ^ dtsa) & DTA_UNIT) dt_deselect (old_dtsa);
|
if ((old_dtsa ^ dtsa) & DTA_UNIT) dt_deselect (old_dtsa);
|
||||||
uptr = dt_dev.units + DTA_GETUNIT (dtsa); /* get unit */
|
uptr = dt_dev.units + DTA_GETUNIT (dtsa); /* get unit */
|
||||||
fnc = DTA_GETFNC (dtsa); /* get fnc */
|
fnc = DTA_GETFNC (dtsa); /* get fnc */
|
||||||
|
@ -445,41 +445,41 @@ if (((pulse & 060) == 040) && (pulse & 05)) { /* select */
|
||||||
dt_seterr (uptr, DTB_SEL); /* select err */
|
dt_seterr (uptr, DTB_SEL); /* select err */
|
||||||
else dt_newsa (dtsa); /* new func */
|
else dt_newsa (dtsa); /* new func */
|
||||||
DT_UPDINT;
|
DT_UPDINT;
|
||||||
return AC; }
|
return dat; }
|
||||||
if ((pulse & 067) == 042) return dtsa; /* DTRA */
|
if ((pulse & 067) == 042) return dtsa; /* DTRA */
|
||||||
if ((pulse & 067) == 061) /* DTEF */
|
if ((pulse & 067) == 061) /* DTEF */
|
||||||
return ((dtsb & DTB_ERF)? IOT_SKP + AC: AC);
|
return ((dtsb & DTB_ERF)? IOT_SKP + dat: dat);
|
||||||
if ((pulse & 067) == 062) return dtsb; /* DTRB */
|
if ((pulse & 067) == 062) return dtsb; /* DTRB */
|
||||||
if ((pulse & 067) == 063) /* DTEF!DTRB */
|
if ((pulse & 067) == 063) /* DTEF!DTRB */
|
||||||
return ((dtsb & DTB_ERF)? IOT_SKP + dtsb: dtsb);
|
return ((dtsb & DTB_ERF)? IOT_SKP + dtsb: dtsb);
|
||||||
return AC;
|
return dat;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 dt76 (int32 pulse, int32 AC)
|
int32 dt76 (int32 pulse, int32 dat)
|
||||||
{
|
{
|
||||||
if ((pulse & 01) && (dtsb & DTB_DTF)) /* DTDF */
|
if ((pulse & 01) && (dtsb & DTB_DTF)) /* DTDF */
|
||||||
return IOT_SKP + AC;
|
return IOT_SKP + dat;
|
||||||
return AC;
|
return dat;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* Type 550 */
|
#else /* Type 550 */
|
||||||
int32 dt75 (int32 pulse, int32 AC)
|
int32 dt75 (int32 pulse, int32 dat)
|
||||||
{
|
{
|
||||||
if (((pulse & 041) == 001) && (dtsb & DTB_DTF)) /* MMDF */
|
if (((pulse & 041) == 001) && (dtsb & DTB_DTF)) /* MMDF */
|
||||||
AC = AC | IOT_SKP;
|
dat = dat | IOT_SKP;
|
||||||
else if (((pulse & 041) == 041) && (dtsb & DTB_ERF)) /* MMEF */
|
else if (((pulse & 041) == 041) && (dtsb & DTB_ERF)) /* MMEF */
|
||||||
AC = AC | IOT_SKP;
|
dat = dat | IOT_SKP;
|
||||||
if (pulse & 002) { /* MMRD */
|
if (pulse & 002) { /* MMRD */
|
||||||
AC = (AC & ~DMASK) | dtdb;
|
dat = (dat & ~DMASK) | dtdb;
|
||||||
dtsb = dtsb & ~(DTB_DTF | DTB_BEF); }
|
dtsb = dtsb & ~(DTB_DTF | DTB_BEF); }
|
||||||
if (pulse & 004) { /* MMWR */
|
if (pulse & 004) { /* MMWR */
|
||||||
dtdb = AC & DMASK;
|
dtdb = dat & DMASK;
|
||||||
dtsb = dtsb & ~(DTB_DTF | DTB_BEF); }
|
dtsb = dtsb & ~(DTB_DTF | DTB_BEF); }
|
||||||
DT_UPDINT;
|
DT_UPDINT;
|
||||||
return AC;
|
return dat;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 dt76 (int32 pulse, int32 AC)
|
int32 dt76 (int32 pulse, int32 dat)
|
||||||
{
|
{
|
||||||
int32 fnc, mot, unum;
|
int32 fnc, mot, unum;
|
||||||
UNIT *uptr = NULL;
|
UNIT *uptr = NULL;
|
||||||
|
@ -487,7 +487,7 @@ UNIT *uptr = NULL;
|
||||||
unum = DTA_GETUNIT (dtsa); /* get unit no */
|
unum = DTA_GETUNIT (dtsa); /* get unit no */
|
||||||
if (unum >= 0) uptr = dt_dev.units + unum; /* get unit */
|
if (unum >= 0) uptr = dt_dev.units + unum; /* get unit */
|
||||||
if ((pulse & 001) && (dtsb & DTB_BEF)) /* MMBF */
|
if ((pulse & 001) && (dtsb & DTB_BEF)) /* MMBF */
|
||||||
AC = AC | IOT_SKP;
|
dat = dat | IOT_SKP;
|
||||||
if (pulse & 002) { /* MMRS */
|
if (pulse & 002) { /* MMRS */
|
||||||
dtsb = dtsb & ~(DTB_REV | DTB_GO); /* clr rev, go */
|
dtsb = dtsb & ~(DTB_REV | DTB_GO); /* clr rev, go */
|
||||||
if (uptr) { /* valid unit? */
|
if (uptr) { /* valid unit? */
|
||||||
|
@ -495,13 +495,13 @@ if (pulse & 002) { /* MMRS */
|
||||||
if (mot & DTS_DIR) dtsb = dtsb | DTB_REV; /* rev? set */
|
if (mot & DTS_DIR) dtsb = dtsb | DTB_REV; /* rev? set */
|
||||||
if ((mot >= DTS_ACCF) || (uptr->STATE & 0777700))
|
if ((mot >= DTS_ACCF) || (uptr->STATE & 0777700))
|
||||||
dtsb = dtsb | DTB_GO; } /* accel? go */
|
dtsb = dtsb | DTB_GO; } /* accel? go */
|
||||||
AC = (AC & ~DMASK) | dtsb; }
|
dat = (dat & ~DMASK) | dtsb; }
|
||||||
if ((pulse & 044) == 044) { /* MMSE */
|
if ((pulse & 044) == 044) { /* MMSE */
|
||||||
if ((dtsa ^ AC) & DTA_UNIT) dt_deselect (dtsa); /* new unit? */
|
if ((dtsa ^ dat) & DTA_UNIT) dt_deselect (dtsa); /* new unit? */
|
||||||
dtsa = (dtsa & ~DTA_UNIT) | (AC & DTA_UNIT);
|
dtsa = (dtsa & ~DTA_UNIT) | (dat & DTA_UNIT);
|
||||||
dtsb = dtsb & ~(DTB_DTF | DTB_BEF | DTB_ERF | DTB_ALLERR); }
|
dtsb = dtsb & ~(DTB_DTF | DTB_BEF | DTB_ERF | DTB_ALLERR); }
|
||||||
else if ((pulse & 044) == 004) { /* MMLC */
|
else if ((pulse & 044) == 004) { /* MMLC */
|
||||||
dtsa = (dtsa & ~DTA_RW) | (AC & DTA_RW); /* load dtsa */
|
dtsa = (dtsa & ~DTA_RW) | (dat & DTA_RW); /* load dtsa */
|
||||||
dtsb = dtsb & ~(DTB_DTF | DTB_BEF | DTB_ERF | DTB_ALLERR);
|
dtsb = dtsb & ~(DTB_DTF | DTB_BEF | DTB_ERF | DTB_ALLERR);
|
||||||
fnc = DTA_GETFNC (dtsa); /* get fnc */
|
fnc = DTA_GETFNC (dtsa); /* get fnc */
|
||||||
if ((uptr == NULL) || /* invalid? */
|
if ((uptr == NULL) || /* invalid? */
|
||||||
|
@ -512,7 +512,7 @@ else if ((pulse & 044) == 004) { /* MMLC */
|
||||||
dt_seterr (uptr, DTB_SEL); /* select err */
|
dt_seterr (uptr, DTB_SEL); /* select err */
|
||||||
else dt_newsa (dtsa); }
|
else dt_newsa (dtsa); }
|
||||||
DT_UPDINT;
|
DT_UPDINT;
|
||||||
return AC;
|
return dat;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -836,7 +836,7 @@ case FNC_SRCH: /* search */
|
||||||
return SCPE_OK; }
|
return SCPE_OK; }
|
||||||
sim_activate (uptr, DTU_LPERB (uptr) * dt_ltime);/* sched next block */
|
sim_activate (uptr, DTU_LPERB (uptr) * dt_ltime);/* sched next block */
|
||||||
M[DT_WC] = (M[DT_WC] + 1) & DMASK; /* inc WC */
|
M[DT_WC] = (M[DT_WC] + 1) & DMASK; /* inc WC */
|
||||||
ma = M[DT_CA] & ADDRMASK; /* get mem addr */
|
ma = M[DT_CA] & AMASK; /* get mem addr */
|
||||||
if (MEM_ADDR_OK (ma)) M[ma] = blk; /* store block # */
|
if (MEM_ADDR_OK (ma)) M[ma] = blk; /* store block # */
|
||||||
if (((dtsa & DTA_MODE) == 0) || (M[DT_WC] == 0))
|
if (((dtsa & DTA_MODE) == 0) || (M[DT_WC] == 0))
|
||||||
dtsb = dtsb | DTB_DTF; /* set DTF */
|
dtsb = dtsb | DTB_DTF; /* set DTF */
|
||||||
|
@ -870,7 +870,7 @@ case FNC_READ: /* read */
|
||||||
case 0: /* normal read */
|
case 0: /* normal read */
|
||||||
M[DT_WC] = (M[DT_WC] + 1) & DMASK; /* incr WC, CA */
|
M[DT_WC] = (M[DT_WC] + 1) & DMASK; /* incr WC, CA */
|
||||||
M[DT_CA] = (M[DT_CA] + 1) & DMASK;
|
M[DT_CA] = (M[DT_CA] + 1) & DMASK;
|
||||||
ma = M[DT_CA] & ADDRMASK; /* mem addr */
|
ma = M[DT_CA] & AMASK; /* mem addr */
|
||||||
ba = (blk * DTU_BSIZE (uptr)) + wrd; /* buffer ptr */
|
ba = (blk * DTU_BSIZE (uptr)) + wrd; /* buffer ptr */
|
||||||
dtdb = bptr[ba]; /* get tape word */
|
dtdb = bptr[ba]; /* get tape word */
|
||||||
if (dir) dtdb = dt_comobv (dtdb); /* rev? comp obv */
|
if (dir) dtdb = dt_comobv (dtdb); /* rev? comp obv */
|
||||||
|
@ -920,7 +920,7 @@ case FNC_WRIT: /* write */
|
||||||
M[DT_WC] = (M[DT_WC] + 1) & DMASK; /* incr WC, CA */
|
M[DT_WC] = (M[DT_WC] + 1) & DMASK; /* incr WC, CA */
|
||||||
M[DT_CA] = (M[DT_CA] + 1) & DMASK;
|
M[DT_CA] = (M[DT_CA] + 1) & DMASK;
|
||||||
case DTO_WCO: /* wc ovflo */
|
case DTO_WCO: /* wc ovflo */
|
||||||
ma = M[DT_CA] & ADDRMASK; /* mem addr */
|
ma = M[DT_CA] & AMASK; /* mem addr */
|
||||||
ba = (blk * DTU_BSIZE (uptr)) + wrd; /* buffer ptr */
|
ba = (blk * DTU_BSIZE (uptr)) + wrd; /* buffer ptr */
|
||||||
dtdb = dt_substate? 0: M[ma]; /* get word */
|
dtdb = dt_substate? 0: M[ma]; /* get word */
|
||||||
if (dir) dtdb = dt_comobv (dtdb); /* rev? comp obv */
|
if (dir) dtdb = dt_comobv (dtdb); /* rev? comp obv */
|
||||||
|
@ -955,7 +955,7 @@ case FNC_RALL:
|
||||||
relpos = DT_LIN2OF (uptr->pos, uptr); /* cur pos in blk */
|
relpos = DT_LIN2OF (uptr->pos, uptr); /* cur pos in blk */
|
||||||
M[DT_WC] = (M[DT_WC] + 1) & DMASK; /* incr WC, CA */
|
M[DT_WC] = (M[DT_WC] + 1) & DMASK; /* incr WC, CA */
|
||||||
M[DT_CA] = (M[DT_CA] + 1) & DMASK;
|
M[DT_CA] = (M[DT_CA] + 1) & DMASK;
|
||||||
ma = M[DT_CA] & ADDRMASK; /* mem addr */
|
ma = M[DT_CA] & AMASK; /* mem addr */
|
||||||
if ((relpos >= DT_HTLIN) && /* in data zone? */
|
if ((relpos >= DT_HTLIN) && /* in data zone? */
|
||||||
(relpos < (DTU_LPERB (uptr) - DT_HTLIN))) {
|
(relpos < (DTU_LPERB (uptr) - DT_HTLIN))) {
|
||||||
wrd = DT_LIN2WD (uptr->pos, uptr);
|
wrd = DT_LIN2WD (uptr->pos, uptr);
|
||||||
|
@ -989,7 +989,7 @@ case FNC_WALL:
|
||||||
relpos = DT_LIN2OF (uptr->pos, uptr); /* cur pos in blk */
|
relpos = DT_LIN2OF (uptr->pos, uptr); /* cur pos in blk */
|
||||||
M[DT_WC] = (M[DT_WC] + 1) & DMASK; /* incr WC, CA */
|
M[DT_WC] = (M[DT_WC] + 1) & DMASK; /* incr WC, CA */
|
||||||
M[DT_CA] = (M[DT_CA] + 1) & DMASK;
|
M[DT_CA] = (M[DT_CA] + 1) & DMASK;
|
||||||
ma = M[DT_CA] & ADDRMASK; /* mem addr */
|
ma = M[DT_CA] & AMASK; /* mem addr */
|
||||||
if ((relpos >= DT_HTLIN) && /* in data zone? */
|
if ((relpos >= DT_HTLIN) && /* in data zone? */
|
||||||
(relpos < (DTU_LPERB (uptr) - DT_HTLIN))) {
|
(relpos < (DTU_LPERB (uptr) - DT_HTLIN))) {
|
||||||
dtdb = M[ma]; /* get mem word */
|
dtdb = M[ma]; /* get mem word */
|
||||||
|
@ -1122,7 +1122,7 @@ return;
|
||||||
|
|
||||||
int32 dt_comobv (int32 dat)
|
int32 dt_comobv (int32 dat)
|
||||||
{
|
{
|
||||||
dat = dat ^ 0777777; /* compl obverse */
|
dat = dat ^ DMASK; /* compl obverse */
|
||||||
dat = ((dat >> 15) & 07) | ((dat >> 9) & 070) |
|
dat = ((dat >> 15) & 07) | ((dat >> 9) & 070) |
|
||||||
((dat >> 3) & 0700) | ((dat & 0700) << 3) |
|
((dat >> 3) & 0700) | ((dat & 0700) << 3) |
|
||||||
((dat & 070) << 9) | ((dat & 07) << 15);
|
((dat & 070) << 9) | ((dat & 07) << 15);
|
||||||
|
@ -1140,16 +1140,16 @@ int32 i, csum, wrd;
|
||||||
#if defined (TC02) /* TC02/TC15 */
|
#if defined (TC02) /* TC02/TC15 */
|
||||||
csum = 077; /* init csum */
|
csum = 077; /* init csum */
|
||||||
for (i = 0; i < DTU_BSIZE (uptr); i++) { /* loop thru buf */
|
for (i = 0; i < DTU_BSIZE (uptr); i++) { /* loop thru buf */
|
||||||
wrd = bptr[ba + i] ^ 0777777; /* get ~word */
|
wrd = bptr[ba + i] ^ DMASK; /* get ~word */
|
||||||
csum = csum ^ (wrd >> 12) ^ (wrd >> 6) ^ wrd; }
|
csum = csum ^ (wrd >> 12) ^ (wrd >> 6) ^ wrd; }
|
||||||
return (csum & 077);
|
return (csum & 077);
|
||||||
#else /* Type 550 */
|
#else /* Type 550 */
|
||||||
csum = 0777777;
|
csum = DMASK;
|
||||||
for (i = 0; i < DTU_BSIZE (uptr); i++) { /* loop thru buf */
|
for (i = 0; i < DTU_BSIZE (uptr); i++) { /* loop thru buf */
|
||||||
wrd = bptr[ba + i]; /* get word */
|
wrd = bptr[ba + i]; /* get word */
|
||||||
csum = csum + wrd; /* 1's comp add */
|
csum = csum + wrd; /* 1's comp add */
|
||||||
if (csum > 0777777) csum = (csum + 1) & 0777777; }
|
if (csum > DMASK) csum = (csum + 1) & DMASK; }
|
||||||
return (csum ^ 0777777); /* 1's comp res */
|
return (csum ^ DMASK); /* 1's comp res */
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1164,7 +1164,7 @@ if (wrd == DT_BLKWD) return blk; /* fwd blknum */
|
||||||
if (wrd == (2 * DT_HTWRD + DTU_BSIZE (uptr) - DT_CSMWD - 1)) /* fwd csum */
|
if (wrd == (2 * DT_HTWRD + DTU_BSIZE (uptr) - DT_CSMWD - 1)) /* fwd csum */
|
||||||
return (dt_csum (uptr, blk) << 12);
|
return (dt_csum (uptr, blk) << 12);
|
||||||
#else
|
#else
|
||||||
if (wrd == DT_CSMWD) return 0777777; /* rev csum */
|
if (wrd == DT_CSMWD) return DMASK; /* rev csum */
|
||||||
if (wrd == (2 * DT_HTWRD + DTU_BSIZE (uptr) - DT_CSMWD - 1)) /* fwd csum */
|
if (wrd == (2 * DT_HTWRD + DTU_BSIZE (uptr) - DT_CSMWD - 1)) /* fwd csum */
|
||||||
return (dt_csum (uptr, blk));
|
return (dt_csum (uptr, blk));
|
||||||
#endif /* Type 550 */
|
#endif /* Type 550 */
|
||||||
|
|
774
PDP18B/pdp18b_fpp.c
Normal file
774
PDP18B/pdp18b_fpp.c
Normal file
|
@ -0,0 +1,774 @@
|
||||||
|
/* pdp18b_fpp.c: FP15 floating point processor simulator
|
||||||
|
|
||||||
|
Copyright (c) 2003, 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"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
Except as contained in this notice, the name of Robert M Supnik shall not
|
||||||
|
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
fpp PDP-15 floating point processor
|
||||||
|
|
||||||
|
The FP15 instruction format is:
|
||||||
|
|
||||||
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
||||||
|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||||
|
| 1 1 1 0 0 1| subop | microcoded modifiers | floating point
|
||||||
|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||||
|
|in| address |
|
||||||
|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||||
|
|
||||||
|
Indirection is always single level.
|
||||||
|
|
||||||
|
The FP15 supports four data formats:
|
||||||
|
|
||||||
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
||||||
|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||||
|
| S| 2's complement integer | A: integer
|
||||||
|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||||
|
|
||||||
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
||||||
|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||||
|
| S| 2's complement integer (high) | A: extended integer
|
||||||
|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||||
|
| 2's complement integer (low) | A+1
|
||||||
|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||||
|
|
||||||
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
||||||
|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||||
|
| fraction (low) |SE|2's complement exponent| A: single floating
|
||||||
|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||||
|
|SF| fraction (high) | A+1
|
||||||
|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||||
|
|
||||||
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
||||||
|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||||
|
|SE| 2's complement exponent | A: double floating
|
||||||
|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||||
|
|SF| fraction (high) | A+1
|
||||||
|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||||
|
| fraction (low) | A+2
|
||||||
|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pdp18b_defs.h"
|
||||||
|
|
||||||
|
/* Instruction */
|
||||||
|
|
||||||
|
#define FI_V_OP 8 /* subopcode */
|
||||||
|
#define FI_M_OP 017
|
||||||
|
#define FI_GETOP(x) (((x) >> FI_V_OP) & FI_M_OP)
|
||||||
|
#define FI_NOLOAD 0200 /* don't load */
|
||||||
|
#define FI_DP 0100 /* single/double */
|
||||||
|
#define FI_FP 0040 /* int/flt point */
|
||||||
|
#define FI_NONORM 0020 /* don't normalize */
|
||||||
|
#define FI_NORND 0010 /* don't round */
|
||||||
|
#define FI_V_SGNOP 0 /* A sign change */
|
||||||
|
#define FI_M_SGNOP 03
|
||||||
|
#define FI_GETSGNOP(x) (((x) >> FI_V_SGNOP) & FI_M_SGNOP)
|
||||||
|
|
||||||
|
/* Exception register */
|
||||||
|
|
||||||
|
#define JEA_V_SIGN 17 /* A sign */
|
||||||
|
#define JEA_V_GUARD 16 /* guard */
|
||||||
|
#define JEA_EAMASK 077777 /* exc address */
|
||||||
|
#define JEA_OFF_OVF 0 /* ovf offset */
|
||||||
|
#define JEA_OFF_UNF 2 /* unf offset */
|
||||||
|
#define JEA_OFF_DIV 4 /* div offset */
|
||||||
|
#define JEA_OFF_MM 6 /* mem mgt offset */
|
||||||
|
|
||||||
|
/* Status codes - must relate directly to JEA offsets */
|
||||||
|
|
||||||
|
#define FP_OK 0 /* no error - mbz */
|
||||||
|
#define FP_OVF (JEA_OFF_OVF + 1) /* overflow */
|
||||||
|
#define FP_UNF (JEA_OFF_UNF + 1) /* underflow */
|
||||||
|
#define FP_DIV (JEA_OFF_DIV + 1) /* divide exception */
|
||||||
|
#define FP_MM (JEA_OFF_MM + 1) /* mem mgt error */
|
||||||
|
|
||||||
|
/* Unpacked floating point fraction */
|
||||||
|
|
||||||
|
#define UFP_FH_CARRY 0400000 /* carry out */
|
||||||
|
#define UFP_FH_NORM 0200000 /* normalized */
|
||||||
|
#define UFP_FH_MASK 0377777 /* hi mask */
|
||||||
|
#define UFP_FL_MASK 0777777 /* low mask */
|
||||||
|
#define UFP_FL_SMASK 0777000 /* low mask, single */
|
||||||
|
#define UFP_FL_SRND 0000400 /* round bit, single */
|
||||||
|
|
||||||
|
#define GET_SIGN(x) (((x) >> 17) & 1)
|
||||||
|
#define SEXT18(x) (((x) & SIGN)? ((x) | ~DMASK): ((x) & DMASK))
|
||||||
|
#define SEXT9(x) (((x) & 0400)? ((x) | ~0377): ((x) & 0377))
|
||||||
|
|
||||||
|
enum fop {
|
||||||
|
FOP_TST, FOP_SUB, FOP_RSUB, FOP_MUL,
|
||||||
|
FOP_DIV, FOP_RDIV, FOP_LD, FOP_ST,
|
||||||
|
FOP_FLT, FOP_FIX, FOP_LFMQ, FOP_JEA,
|
||||||
|
FOP_ADD, FOP_BR, FOP_DIAG, FOP_UND };
|
||||||
|
|
||||||
|
struct ufp {
|
||||||
|
int32 exp; /* exponent */
|
||||||
|
int32 sign; /* sign */
|
||||||
|
int32 hi; /* hi frac, 17b */
|
||||||
|
int32 lo; }; /* lo frac, 18b */
|
||||||
|
|
||||||
|
typedef struct ufp UFP;
|
||||||
|
|
||||||
|
static int32 fir; /* instruction */
|
||||||
|
static int32 jea; /* exc address */
|
||||||
|
static int32 fguard; /* guard bit */
|
||||||
|
static UFP fma; /* FMA */
|
||||||
|
static UFP fmb; /* FMB */
|
||||||
|
static UFP fmq; /* FMQ - hi,lo only */
|
||||||
|
|
||||||
|
extern int32 M[MAXMEMSIZE];
|
||||||
|
extern int32 pcq[PCQ_SIZE];
|
||||||
|
extern int32 pcq_p;
|
||||||
|
extern int32 PC;
|
||||||
|
extern int32 trap_pending, usmd;
|
||||||
|
|
||||||
|
t_stat fp15_reset (DEVICE *dptr);
|
||||||
|
t_stat fp15_opnd (int32 ir, int32 addr, UFP *a);
|
||||||
|
t_stat fp15_store (int32 ir, int32 addr, UFP *a);
|
||||||
|
t_stat fp15_iadd (int32 ir, UFP *a, UFP *b, t_bool sub);
|
||||||
|
t_stat fp15_imul (int32 ir, UFP *a, UFP *b);
|
||||||
|
t_stat fp15_idiv (int32 ir, UFP *a, UFP *b);
|
||||||
|
t_stat fp15_fadd (int32 ir, UFP *a, UFP *b, t_bool sub);
|
||||||
|
t_stat fp15_fmul (int32 ir, UFP *a, UFP *b);
|
||||||
|
t_stat fp15_fdiv (int32 ir, UFP *a, UFP *b);
|
||||||
|
t_stat fp15_fix (int32 ir, UFP *a);
|
||||||
|
t_stat fp15_norm (int32 ir, UFP *a, UFP *b, t_bool rnd);
|
||||||
|
t_stat fp15_exc (int32 sta);
|
||||||
|
void fp15_asign (int32 ir, UFP *a);
|
||||||
|
void dp_add (UFP *a, UFP *b);
|
||||||
|
void dp_sub (UFP *a, UFP *b);
|
||||||
|
void dp_inc (UFP *a);
|
||||||
|
int32 dp_cmp (UFP *a, UFP *b);
|
||||||
|
void dp_mul (UFP *a, UFP *b);
|
||||||
|
void dp_lsh_1 (UFP *a, UFP *b);
|
||||||
|
void dp_rsh_1 (UFP *a, UFP *b);
|
||||||
|
void dp_dnrm_r (int32 ir, UFP *a, int32 sc);
|
||||||
|
void dp_swap (UFP *a, UFP *b);
|
||||||
|
|
||||||
|
extern t_stat Read (int32 ma, int32 *dat, int32 cyc);
|
||||||
|
extern t_stat Write (int32 ma, int32 dat, int32 cyc);
|
||||||
|
extern t_stat Ia (int32 ma, int32 *ea, t_bool jmp);
|
||||||
|
extern int32 Incr_addr (int32 addr);
|
||||||
|
extern int32 Jms_word (int32 t);
|
||||||
|
|
||||||
|
/* FPP data structures
|
||||||
|
|
||||||
|
fpp_dev FPP device descriptor
|
||||||
|
fpp_unit FPP unit
|
||||||
|
fpp_reg FPP register list
|
||||||
|
fpp_mod FPP modifier list
|
||||||
|
*/
|
||||||
|
|
||||||
|
UNIT fpp_unit = { UDATA (NULL, 0, 0) };
|
||||||
|
|
||||||
|
REG fpp_reg[] = {
|
||||||
|
{ ORDATA (FIR, fir, 12) },
|
||||||
|
{ ORDATA (EPA, fma.exp, 18) },
|
||||||
|
{ FLDATA (FMAS, fma.sign, 0) },
|
||||||
|
{ ORDATA (FMAH, fma.hi, 17) },
|
||||||
|
{ ORDATA (FMAL, fma.lo, 18) },
|
||||||
|
{ ORDATA (EPB, fmb.exp, 18) },
|
||||||
|
{ FLDATA (FMBS, fmb.sign, 0) },
|
||||||
|
{ ORDATA (FMBH, fmb.hi, 17) },
|
||||||
|
{ ORDATA (FMBL, fmb.lo, 18) },
|
||||||
|
{ FLDATA (FGUARD, fguard, 0) },
|
||||||
|
{ ORDATA (FMQH, fmq.hi, 17) },
|
||||||
|
{ ORDATA (FMQL, fmq.lo, 18) },
|
||||||
|
{ ORDATA (JEA, jea, 18) },
|
||||||
|
{ NULL } };
|
||||||
|
|
||||||
|
DEVICE fpp_dev = {
|
||||||
|
"FPP", &fpp_unit, fpp_reg, NULL,
|
||||||
|
1, 8, 1, 1, 8, 18,
|
||||||
|
NULL, NULL, &fp15_reset,
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
NULL, DEV_DISABLE | DEV_DIS };
|
||||||
|
|
||||||
|
/* Instruction decode for FP15
|
||||||
|
|
||||||
|
The CPU actually fetches the instruction and the word after. If the
|
||||||
|
instruction is 71XXXX, the CPU executes it as a NOP, and the FP15 fools
|
||||||
|
the CPU into thinking that the second word is also a NOP.
|
||||||
|
|
||||||
|
Indirect addresses are resolved during fetch, unless the NOLOAD modifier
|
||||||
|
is set and the instruction is not a store. */
|
||||||
|
|
||||||
|
t_stat fp15 (int32 ir)
|
||||||
|
{
|
||||||
|
int32 ar, ma, fop, dat;
|
||||||
|
t_stat sta = FP_OK;
|
||||||
|
|
||||||
|
if (fpp_dev.flags & DEV_DIS) return MM_OK; /* disabled? */
|
||||||
|
fir = ir & 07777; /* save subop + mods */
|
||||||
|
ma = PC; /* fetch next word */
|
||||||
|
PC = Incr_addr (PC);
|
||||||
|
if (Read (ma, &ar, RD)) return fp15_exc (FP_MM); /* error? MM exc */
|
||||||
|
fop = FI_GETOP (fir); /* get subopcode */
|
||||||
|
if ((ar & SIGN) && /* indirect? */
|
||||||
|
((fop == FOP_ST) || !(ir & FI_NOLOAD))) { /* store or load? */
|
||||||
|
ma = ar & AMASK; /* fetch indirect */
|
||||||
|
if (Read (ma, &ar, RD)) return fp15_exc (FP_MM); }
|
||||||
|
fma.exp = SEXT18 (fma.exp); /* sext exponents */
|
||||||
|
fmb.exp = SEXT18 (fmb.exp);
|
||||||
|
switch (fop) { /* case on subop */
|
||||||
|
|
||||||
|
case FOP_TST: /* NOP */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FOP_SUB: /* subtract */
|
||||||
|
if (sta = fp15_opnd (fir, ar, &fmb)) break; /* fetch op to FMB */
|
||||||
|
if (fir & FI_FP) sta = fp15_fadd (fir, &fma, &fmb, 1); /* fp? */
|
||||||
|
else sta = fp15_iadd (fir, &fma, &fmb, 1); /* no, int sub */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FOP_RSUB: /* reverse sub */
|
||||||
|
fmb = fma; /* FMB <- FMA */
|
||||||
|
if (sta = fp15_opnd (fir, ar, &fma)) break; /* fetch op to FMA */
|
||||||
|
if (fir & FI_FP) sta = fp15_fadd (fir, &fma, &fmb, 1); /* fp? */
|
||||||
|
else sta = fp15_iadd (fir, &fma, &fmb, 1); /* no, int sub */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FOP_MUL: /* multiply */
|
||||||
|
if (sta = fp15_opnd (fir, ar, &fmb)) break; /* fetch op to FMB */
|
||||||
|
if (fir & FI_FP) sta = fp15_fmul (fir, &fma, &fmb); /* fp? */
|
||||||
|
else sta = fp15_imul (fir, &fma, &fmb); /* no, int mul */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FOP_DIV: /* divide */
|
||||||
|
if (sta = fp15_opnd (fir, ar, &fmb)) break; /* fetch op to FMB */
|
||||||
|
if (fir & FI_FP) sta = fp15_fdiv (fir, &fma, &fmb); /* fp? */
|
||||||
|
else sta = fp15_idiv (fir, &fma, &fmb); /* no, int div */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FOP_RDIV: /* reverse divide */
|
||||||
|
fmb = fma; /* FMB <- FMA */
|
||||||
|
if (sta = fp15_opnd (fir, ar, &fma)) break; /* fetch op to FMA */
|
||||||
|
if (fir & FI_FP) sta = fp15_fdiv (fir, &fma, &fmb); /* fp? */
|
||||||
|
else sta = fp15_idiv (fir, &fma, &fmb); /* no, int div */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FOP_LD: /* load */
|
||||||
|
if (sta = fp15_opnd (fir, ar, &fma)) break; /* fetch op to FMA */
|
||||||
|
fp15_asign (fir, &fma); /* modify A sign */
|
||||||
|
if (fir & FI_FP) /* fp? */
|
||||||
|
sta = fp15_norm (ir, &fma, NULL, 0); /* normalize */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FOP_ST: /* store */
|
||||||
|
fp15_asign (fir, &fma); /* modify A sign */
|
||||||
|
sta = fp15_store (fir, ar, &fma); /* store result */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FOP_FLT: /* float */
|
||||||
|
if (sta = fp15_opnd (fir, ar, &fma)) break; /* fetch op to FMA */
|
||||||
|
fma.exp = 35;
|
||||||
|
fp15_asign (fir, &fma); /* adjust A sign */
|
||||||
|
sta = fp15_norm (ir, &fma, NULL, 0); /* normalize */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FOP_FIX: /* fix */
|
||||||
|
if (sta = fp15_opnd (fir, ar, &fma)) break; /* fetch op to FMA */
|
||||||
|
sta = fp15_fix (fir, &fma); /* fix */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FOP_LFMQ: /* load FMQ */
|
||||||
|
if (sta = fp15_opnd (fir, ar, &fma)) break; /* fetch op to FMA */
|
||||||
|
dp_swap (&fma, &fmq); /* swap FMA, FMQ */
|
||||||
|
fp15_asign (fir, &fma); /* adjust A sign */
|
||||||
|
if (fir & FI_FP) /* fp? norm, no rnd */
|
||||||
|
sta = fp15_norm (ir | FI_NORND, &fma, &fmq, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FOP_JEA: /* JEA */
|
||||||
|
if (ir & 0200) { /* store? */
|
||||||
|
dat = jea | (fma.sign << JEA_V_SIGN) | (fguard << JEA_V_GUARD);
|
||||||
|
sta = Write (ar, dat, WR); }
|
||||||
|
else { /* no, load */
|
||||||
|
if (sta = Read (ar, &dat, RD)) break;
|
||||||
|
fguard = (dat >> JEA_V_GUARD) & 1;
|
||||||
|
jea = dat; }
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FOP_ADD: /* add */
|
||||||
|
if (sta = fp15_opnd (fir, ar, &fmb)) break; /* fetch op to FMB */
|
||||||
|
if (fir & FI_FP) sta = fp15_fadd (fir, &fma, &fmb, 0); /* fp? */
|
||||||
|
else sta = fp15_iadd (fir, &fma, &fmb, 0); /* no, int add */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FOP_BR: /* branch */
|
||||||
|
if (((fir & 001) && ((fma.hi | fma.lo) == 0)) ||
|
||||||
|
((fir & 002) && fma.sign) ||
|
||||||
|
((fir & 004) && !fma.sign) ||
|
||||||
|
((fir & 010) && ((fma.hi | fma.lo) != 0)) ||
|
||||||
|
((fir & 020) && fguard)) { /* cond met? */
|
||||||
|
PCQ_ENTRY; /* save current PC */
|
||||||
|
PC = (PC & BLKMASK) | (ar & IAMASK); } /* branch within 32K */
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break; }
|
||||||
|
|
||||||
|
fma.exp = fma.exp & DMASK; /* mask exp to 18b */
|
||||||
|
fmb.exp = fmb.exp & DMASK;
|
||||||
|
if (sta != FP_OK) return fp15_exc (sta); /* error? */
|
||||||
|
return MM_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Operand load and store */
|
||||||
|
|
||||||
|
t_stat fp15_opnd (int32 ir, int32 addr, UFP *fpn)
|
||||||
|
{
|
||||||
|
int32 i, numwd, wd[3];
|
||||||
|
|
||||||
|
fguard = 0; /* clear guard */
|
||||||
|
if (ir & FI_NOLOAD) return FP_OK; /* no load? */
|
||||||
|
if (ir & FI_FP) numwd = 2; /* fp? at least 2 */
|
||||||
|
else numwd = 1; /* else at least 1 */
|
||||||
|
if (ir & FI_DP) numwd = numwd + 1; /* dp? 1 more */
|
||||||
|
for (i = 0; i < numwd; i++) { /* fetch words */
|
||||||
|
if (Read (addr, &wd[i], RD)) return FP_MM;
|
||||||
|
addr = (addr + 1) & AMASK; }
|
||||||
|
if (ir & FI_FP) { /* fp? */
|
||||||
|
fpn->sign = GET_SIGN (wd[1]); /* frac sign */
|
||||||
|
fpn->hi = wd[1] & UFP_FH_MASK; /* frac high */
|
||||||
|
if (ir & FI_DP) { /* dp? */
|
||||||
|
fpn->exp = SEXT18 (wd[0]); /* exponent */
|
||||||
|
fpn->lo = wd[2]; } /* frac low */
|
||||||
|
else { /* sp */
|
||||||
|
fpn->exp = SEXT9 (wd[0]); /* exponent */
|
||||||
|
fpn->lo = wd[0] & UFP_FL_SMASK; } /* frac low */
|
||||||
|
}
|
||||||
|
else { fpn->sign = GET_SIGN (wd[0]); /* int, get sign */
|
||||||
|
if (ir & FI_DP) { /* dp? */
|
||||||
|
fpn->lo = wd[1]; /* 2 words */
|
||||||
|
fpn->hi = wd[0]; }
|
||||||
|
else { /* single */
|
||||||
|
fpn->lo = wd[0]; /* 1 word */
|
||||||
|
fpn->hi = fpn->sign? DMASK: 0; } /* sign extended */
|
||||||
|
if (fpn->sign) { /* negative? */
|
||||||
|
fpn->lo = (-fpn->lo) & UFP_FL_MASK; /* take abs val */
|
||||||
|
fpn->hi = (~fpn->hi + (fpn->lo == 0)) & UFP_FH_MASK; }
|
||||||
|
}
|
||||||
|
return FP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat fp15_store (int32 ir, int32 addr, UFP *a)
|
||||||
|
{
|
||||||
|
int32 i, numwd, wd[3];
|
||||||
|
t_stat sta;
|
||||||
|
|
||||||
|
fguard = 0; /* clear guard */
|
||||||
|
if (ir & FI_FP) { /* fp? */
|
||||||
|
if (sta = fp15_norm (ir, a, NULL, 0)) return sta; /* normalize */
|
||||||
|
wd[1] = (a->sign << 17) | a->hi; /* hi frac */
|
||||||
|
if (ir & FI_DP) { /* dp? */
|
||||||
|
numwd = 3; /* 3 words */
|
||||||
|
wd[0] = a->exp & DMASK; /* exponent */
|
||||||
|
wd[2] = a->lo; } /* low frac */
|
||||||
|
else { /* single */
|
||||||
|
if (!(ir & FI_NORND) && (a->lo & UFP_FL_SRND)) { /* round? */
|
||||||
|
a->lo = (a->lo + UFP_FL_SRND) & UFP_FL_SMASK;
|
||||||
|
a->hi = (a->hi + (a->lo == 0)) & UFP_FH_MASK;
|
||||||
|
if ((a->hi | a->lo) == 0) { /* carry out? */
|
||||||
|
a->hi = UFP_FH_NORM; /* shift back */
|
||||||
|
a->exp = a->exp + 1; } }
|
||||||
|
if (a->exp > 0377) return FP_OVF; /* sp ovf? */
|
||||||
|
if (a->exp < -0400) return FP_UNF; /* sp unf? */
|
||||||
|
numwd = 2; /* 2 words */
|
||||||
|
wd[0] = (a->exp & 0777) | a->lo; } /* low frac'exp */
|
||||||
|
}
|
||||||
|
else { fmb.lo = (-a->lo) & UFP_FL_MASK; /* 2's complement */
|
||||||
|
fmb.hi = (~a->hi + (fmb.lo == 0)) & UFP_FH_MASK;/* to FMB */
|
||||||
|
if (ir & FI_DP) { /* dp? */
|
||||||
|
numwd = 2; /* 2 words */
|
||||||
|
if (a->sign) { /* negative? */
|
||||||
|
wd[0] = fmb.hi | SIGN; /* store FMB */
|
||||||
|
wd[1] = fmb.lo; }
|
||||||
|
else { /* pos, store FMA */
|
||||||
|
wd[0] = a->hi;
|
||||||
|
wd[1] = a->lo; } }
|
||||||
|
else { /* single */
|
||||||
|
if (a->hi || (a->lo & SIGN)) return FP_OVF; /* check int ovf */
|
||||||
|
numwd = 1; /* 1 word */
|
||||||
|
if (a->sign) wd[0] = fmb.lo; /* neg? store FMB */
|
||||||
|
else wd[0] = a->lo; } /* pos, store FMA */
|
||||||
|
}
|
||||||
|
for (i = 0; i < numwd; i++) { /* store words */
|
||||||
|
if (Write (addr, wd[i], WR)) return FP_MM;
|
||||||
|
addr = (addr + 1) & AMASK; }
|
||||||
|
return FP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Integer arithmetic routines */
|
||||||
|
|
||||||
|
/* Integer add - overflow only on add, if carry out of high fraction */
|
||||||
|
|
||||||
|
t_stat fp15_iadd (int32 ir, UFP *a, UFP *b, t_bool sub)
|
||||||
|
{
|
||||||
|
fmq.hi = fmq.lo = 0; /* clear FMQ */
|
||||||
|
if (a->sign ^ b->sign ^ sub) dp_sub (a, b); /* eff subtract? */
|
||||||
|
else { dp_add (a, b); /* no, add */
|
||||||
|
if (a->hi & UFP_FH_CARRY) { /* carry out? */
|
||||||
|
a->hi = a->hi & UFP_FH_MASK; /* mask to 35b */
|
||||||
|
return FP_OVF; } } /* overflow */
|
||||||
|
fp15_asign (ir, a); /* adjust A sign */
|
||||||
|
return FP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Integer multiply - overflow if high result (FMQ after swap) non-zero */
|
||||||
|
|
||||||
|
t_stat fp15_imul (int32 ir, UFP *a, UFP *b)
|
||||||
|
{
|
||||||
|
a->sign = a->sign ^ b->sign; /* sign of result */
|
||||||
|
dp_mul (a, b); /* a'FMQ <- a * b */
|
||||||
|
dp_swap (a, &fmq); /* swap a, FMQ */
|
||||||
|
if (fmq.hi | fmq.lo) return FP_OVF; /* FMQ != 0? ovf */
|
||||||
|
fp15_asign (ir, a); /* adjust A sign */
|
||||||
|
return FP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Integer divide - actually done as fraction divide
|
||||||
|
|
||||||
|
- If divisor zero, error
|
||||||
|
- If dividend zero, done
|
||||||
|
- Normalize dividend and divisor together
|
||||||
|
- If divisor normalized but dividend not, result is zero
|
||||||
|
- If divisor not normalized, normalize and count shifts
|
||||||
|
- Do fraction divide for number of shifts, +1, steps
|
||||||
|
|
||||||
|
Note that dp_lsh_1 returns a 72b result; the last right shift
|
||||||
|
guarantees a 71b remainder. The quotient cannot exceed 71b */
|
||||||
|
|
||||||
|
t_stat fp15_idiv (int32 ir, UFP *a, UFP *b)
|
||||||
|
{
|
||||||
|
int32 i, sc;
|
||||||
|
|
||||||
|
a->sign = a->sign ^ b->sign; /* sign of result */
|
||||||
|
fmq.hi = fmq.lo = 0; /* clear quotient */
|
||||||
|
a->exp = 0; /* clear a exp */
|
||||||
|
if ((b->hi | b->lo) == 0) return FP_DIV; /* div by 0? */
|
||||||
|
if ((a->hi | a->lo) == 0) return FP_OK; /* div into 0? */
|
||||||
|
while (((a->hi & UFP_FH_NORM) == 0) && /* normalize divd */
|
||||||
|
((b->hi & UFP_FH_NORM) == 0)) { /* and divr */
|
||||||
|
dp_lsh_1 (a, NULL); /* lsh divd, divr */
|
||||||
|
dp_lsh_1 (b, NULL); } /* can't carry out */
|
||||||
|
if (!(a->hi & UFP_FH_NORM) && (b->hi & UFP_FH_NORM)) { /* divr norm, divd not? */
|
||||||
|
a->hi = a->lo = 0; /* result is 0 */
|
||||||
|
return FP_OK; }
|
||||||
|
while ((b->hi & UFP_FH_NORM) == 0) { /* normalize divr */
|
||||||
|
dp_lsh_1 (b, NULL); /* can't carry out */
|
||||||
|
a->exp = a->exp + 1; } /* count steps */
|
||||||
|
sc = a->exp;
|
||||||
|
for (i = 0; i <= sc; i++) { /* n+1 steps */
|
||||||
|
dp_lsh_1 (&fmq, NULL); /* left shift quo */
|
||||||
|
if (dp_cmp (a, b) >= 0) { /* sub work? */
|
||||||
|
dp_sub (a, b); /* a -= b */
|
||||||
|
if (i == 0) a->exp = a->exp + 1; /* first step? */
|
||||||
|
fmq.lo = fmq.lo | 1; } /* set quo bit */
|
||||||
|
dp_lsh_1 (a, NULL); } /* left shift divd */
|
||||||
|
dp_rsh_1 (a, NULL); /* shift back */
|
||||||
|
dp_swap (a, &fmq); /* swap a, FMQ */
|
||||||
|
fp15_asign (ir, a); /* adjust A sign */
|
||||||
|
return FP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Floating point arithmetic routines */
|
||||||
|
|
||||||
|
/* Floating add
|
||||||
|
- Special add case, overflow if carry out increments exp out of range
|
||||||
|
- All cases, overflow/underflow detected in normalize */
|
||||||
|
|
||||||
|
t_stat fp15_fadd (int32 ir, UFP *a, UFP *b, t_bool sub)
|
||||||
|
{
|
||||||
|
int32 ediff;
|
||||||
|
|
||||||
|
fmq.hi = fmq.lo = 0; /* clear FMQ */
|
||||||
|
ediff = a->exp - b->exp; /* exp diff */
|
||||||
|
if (((a->hi | a->lo) == 0) || (ediff < -35)) { /* a = 0 or "small"? */
|
||||||
|
*a = *b; /* rslt is b */
|
||||||
|
a->sign = a->sign ^ sub; } /* or -b if sub */
|
||||||
|
else if (((b->hi | b->lo) != 0) && (ediff <= 35)) { /* b!=0 && ~"small"? */
|
||||||
|
if (ediff > 0) dp_dnrm_r (ir, b, ediff); /* |a| > |b|? dnorm b */
|
||||||
|
else if (ediff < 0) { /* |a| < |b|? */
|
||||||
|
a->exp = b->exp; /* b exp is rslt */
|
||||||
|
dp_dnrm_r (ir, a, -ediff); } /* denorm A */
|
||||||
|
if (a->sign ^ b->sign ^ sub) dp_sub (a, b); /* eff sub? */
|
||||||
|
else { /* eff add */
|
||||||
|
dp_add (a, b); /* add */
|
||||||
|
if (a->hi & UFP_FH_CARRY) { /* carry out? */
|
||||||
|
fguard = a->lo & 1; /* set guard */
|
||||||
|
dp_rsh_1 (a, NULL); /* right shift */
|
||||||
|
a->exp = a->exp + 1; /* incr exponent */
|
||||||
|
if (!(ir & FI_NORND) && fguard) /* rounding? */
|
||||||
|
dp_inc (a);
|
||||||
|
if (a->exp > 0377777) return FP_OVF; } }
|
||||||
|
} /* end if b != 0 */
|
||||||
|
fp15_asign (ir, a); /* adjust A sign */
|
||||||
|
return fp15_norm (ir, a, NULL, 0); /* normalize */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Floating multiply - overflow/underflow detected in normalize */
|
||||||
|
|
||||||
|
t_stat fp15_fmul (int32 ir, UFP *a, UFP *b)
|
||||||
|
{
|
||||||
|
a->sign = a->sign ^ b->sign; /* sign of result */
|
||||||
|
a->exp = a->exp + b->exp; /* exp of result */
|
||||||
|
dp_mul (a, b); /* mul fractions */
|
||||||
|
fp15_asign (ir, a); /* adjust A sign */
|
||||||
|
return fp15_norm (ir, a, &fmq, 1); /* norm and round */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Floating divide - overflow/underflow detected in normalize */
|
||||||
|
|
||||||
|
t_stat fp15_fdiv (int32 ir, UFP *a, UFP *b)
|
||||||
|
{
|
||||||
|
int32 i;
|
||||||
|
|
||||||
|
a->sign = a->sign ^ b->sign; /* sign of result */
|
||||||
|
a->exp = a->exp - b->exp; /* exp of result */
|
||||||
|
fmq.hi = fmq.lo = 0; /* clear quotient */
|
||||||
|
if (!(b->hi & UFP_FH_NORM)) return FP_DIV; /* divr not norm? */
|
||||||
|
if (a->hi | a->lo) { /* divd non-zero? */
|
||||||
|
fp15_norm (0, a, NULL, 0); /* normalize divd */
|
||||||
|
for (i = 0; (fmq.hi & UFP_FH_NORM) == 0; i++) { /* until quo */
|
||||||
|
dp_lsh_1 (&fmq, NULL); /* left shift quo */
|
||||||
|
if (dp_cmp (a, b) >= 0) { /* sub work? */
|
||||||
|
dp_sub (a, b); /* a -= b */
|
||||||
|
if (i == 0) a->exp = a->exp + 1;
|
||||||
|
fmq.lo = fmq.lo | 1; } /* set quo bit */
|
||||||
|
dp_lsh_1 (a, NULL); } /* left shift divd */
|
||||||
|
dp_rsh_1 (a, NULL); /* shift back */
|
||||||
|
dp_swap (a, &fmq); } /* swap a, FMQ */
|
||||||
|
fp15_asign (ir, a); /* adjust A sign */
|
||||||
|
return fp15_norm (ir, a, &fmq, 1); /* norm and round */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Floating to integer - overflow only if exponent out of range */
|
||||||
|
|
||||||
|
t_stat fp15_fix (int32 ir, UFP *a)
|
||||||
|
{
|
||||||
|
int32 i;
|
||||||
|
|
||||||
|
fmq.hi = fmq.lo = 0; /* clear FMQ */
|
||||||
|
if (a->exp > 35) return FP_OVF; /* exp > 35? ovf */
|
||||||
|
if (a->exp < 0) a->hi = a->lo = 0; /* exp <0 ? rslt 0 */
|
||||||
|
else { for (i = a->exp; i < 35; i++) /* denorm frac */
|
||||||
|
dp_rsh_1 (a, &fmq);
|
||||||
|
if (fmq.hi & UFP_FH_NORM) { /* last out = 1? */
|
||||||
|
fguard = 1; /* set guard */
|
||||||
|
if (!(ir & FI_NORND)) dp_inc (a); } } /* round */
|
||||||
|
fp15_asign (ir, a); /* adjust A sign */
|
||||||
|
return FP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Double precision routines */
|
||||||
|
|
||||||
|
/* Double precision add - returns 72b result (including carry) */
|
||||||
|
|
||||||
|
void dp_add (UFP *a, UFP *b)
|
||||||
|
{
|
||||||
|
int32 a_hi_orig = a->hi;
|
||||||
|
|
||||||
|
a->lo = (a->lo + b->lo) & UFP_FL_MASK; /* add low */
|
||||||
|
a->hi = a->hi + b->hi + (a->lo < b->lo); /* add hi + carry */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Double precision increment - returns 72b result (including carry) */
|
||||||
|
|
||||||
|
void dp_inc (UFP *a)
|
||||||
|
{
|
||||||
|
a->lo = (a->lo + 1) & UFP_FL_MASK; /* inc low */
|
||||||
|
a->hi = a->hi + (a->lo == 0); /* propagate carry */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Double precision subtract - result always fits in 71b */
|
||||||
|
|
||||||
|
void dp_sub (UFP *a, UFP *b)
|
||||||
|
{
|
||||||
|
if (dp_cmp (a,b) >= 0) { /* |a| >= |b|? */
|
||||||
|
a->hi = (a->hi - b->hi - (a->lo < b->lo)) & UFP_FH_MASK;
|
||||||
|
a->lo = (a->lo - b->lo) & UFP_FL_MASK; } /* a - b */
|
||||||
|
else { a->hi = (b->hi - a->hi - (b->lo < a->lo)) & UFP_FH_MASK;
|
||||||
|
a->lo = (b->lo - a->lo) & UFP_FL_MASK; /* b - a */
|
||||||
|
a->sign = a->sign ^ 1; } /* change a sign */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Double precision compare - returns +1 (>), 0 (=), -1 (<) */
|
||||||
|
|
||||||
|
int32 dp_cmp (UFP *a, UFP *b)
|
||||||
|
{
|
||||||
|
if (a->hi < b->hi) return -1;
|
||||||
|
if (a->hi > b->hi) return +1;
|
||||||
|
if (a->lo < b->lo) return -1;
|
||||||
|
if (a->lo > b->lo) return +1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Double precision multiply - returns 70b result */
|
||||||
|
|
||||||
|
void dp_mul (UFP *a, UFP *b)
|
||||||
|
{
|
||||||
|
int32 i;
|
||||||
|
|
||||||
|
fmq.hi = a->hi; /* FMQ <- a */
|
||||||
|
fmq.lo = a->lo;
|
||||||
|
a->hi = a->lo = 0; /* a <- 0 */
|
||||||
|
if (((fmq.hi | fmq.lo) == 0) || ((b->hi | b->lo) == 0)) return;
|
||||||
|
for (i = 0; i < 35; i++) { /* 35 iterations */
|
||||||
|
if (fmq.lo & 1) dp_add (a, b); /* FMQ<35>? a += b */
|
||||||
|
dp_rsh_1 (a, &fmq); } /* rsh a'FMQ */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Double (quad) precision left shift - returns 72b (143b) result */
|
||||||
|
|
||||||
|
void dp_lsh_1 (UFP *a, UFP *b)
|
||||||
|
{
|
||||||
|
int32 t = b? b->lo: 0;
|
||||||
|
|
||||||
|
a->hi = (a->hi << 1) | (a->lo >> 17);
|
||||||
|
a->lo = ((a->lo << 1) | (t >> 16)) & UFP_FL_MASK;
|
||||||
|
if (b) {
|
||||||
|
b->hi = ((b->hi << 1) | (b->lo >> 17)) & UFP_FH_MASK;
|
||||||
|
b->lo = (b->lo << 1) & UFP_FL_MASK; }
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Double (quad) precision right shift - returns 71b (142b) result */
|
||||||
|
|
||||||
|
void dp_rsh_1 (UFP *a, UFP *b)
|
||||||
|
{
|
||||||
|
if (b) {
|
||||||
|
b->lo = (b->lo >> 1) | ((b->hi & 1) << 17);
|
||||||
|
b->hi = (b->hi >> 1) | ((a->lo & 1) << 16); }
|
||||||
|
a->lo = (a->lo >> 1) | ((a->hi & 1) << 17);
|
||||||
|
a->hi = a->hi >> 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Double precision denormalize and round - returns 71b result */
|
||||||
|
|
||||||
|
void dp_dnrm_r (int32 ir, UFP *a, int32 sc)
|
||||||
|
{
|
||||||
|
int32 i;
|
||||||
|
|
||||||
|
if (sc <= 0) return; /* legit? */
|
||||||
|
for (i = 0; i < sc; i++) dp_rsh_1 (a, &fmq); /* dnorm to fmq */
|
||||||
|
if (!(ir & FI_NORND) && (fmq.hi & UFP_FH_NORM)) /* round & fmq<1>? */
|
||||||
|
dp_inc (a); /* incr a */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Double precision swap */
|
||||||
|
|
||||||
|
void dp_swap (UFP *a, UFP *b)
|
||||||
|
{
|
||||||
|
int32 t;
|
||||||
|
|
||||||
|
t = a->hi; /* swap fractions */
|
||||||
|
a->hi = b->hi;
|
||||||
|
b->hi = t;
|
||||||
|
t = a->lo;
|
||||||
|
a->lo = b->lo;
|
||||||
|
b->lo = t;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Support routines */
|
||||||
|
|
||||||
|
void fp15_asign (int32 fir, UFP *a)
|
||||||
|
{
|
||||||
|
int32 sgnop = FI_GETSGNOP (fir);
|
||||||
|
|
||||||
|
switch (sgnop) { /* modify FMA sign */
|
||||||
|
case 1:
|
||||||
|
a->sign = 0;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
a->sign = 1;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
a->sign = a->sign ^ 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break; }
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FP15 normalization and rounding
|
||||||
|
|
||||||
|
- Do normalization if enabled (NOR phase, part 1)
|
||||||
|
Normalization also does zero detect
|
||||||
|
- Do rounding if enabled (NOR phase, part 2) */
|
||||||
|
|
||||||
|
t_stat fp15_norm (int32 ir, UFP *a, UFP *b, t_bool rnd)
|
||||||
|
{
|
||||||
|
if (!(ir & FI_NONORM)) { /* norm enabled? */
|
||||||
|
if ((a->hi | a->lo) || (b && (b->hi | b->lo))) { /* frac != 0? */
|
||||||
|
while ((a->hi & UFP_FH_NORM) == 0) { /* until norm */
|
||||||
|
dp_lsh_1 (a, b); /* lsh a'b, no cry */
|
||||||
|
a->exp = a->exp - 1; } } /* decr exp */
|
||||||
|
else a->sign = a->exp = 0; } /* true zero */
|
||||||
|
if (rnd && b && (b->hi & UFP_FH_NORM)) { /* rounding? */
|
||||||
|
fguard = 1; /* set guard */
|
||||||
|
if (!(ir & FI_NORND)) { /* round enabled? */
|
||||||
|
dp_inc (a); /* add 1 */
|
||||||
|
if (a->hi & UFP_FH_CARRY) { /* carry out? */
|
||||||
|
a->hi = UFP_FH_NORM; /* set hi bit */
|
||||||
|
a->exp = a->exp + 1; } } } /* incr exp */
|
||||||
|
if (a->exp > 0377777) return FP_OVF; /* overflow? */
|
||||||
|
if (a->exp < -0400000) return FP_UNF; /* underflow? */
|
||||||
|
return FP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Exception */
|
||||||
|
|
||||||
|
t_stat fp15_exc (t_stat sta)
|
||||||
|
{
|
||||||
|
int32 ma, mb;
|
||||||
|
|
||||||
|
if (sta == FP_MM) trap_pending = 0; /* if mm, kill trap */
|
||||||
|
ma = (jea & JEA_EAMASK) + sta - 1; /* JEA address */
|
||||||
|
PCQ_ENTRY; /* record branch */
|
||||||
|
PC = Incr_addr (PC); /* PC+1 for "JMS" */
|
||||||
|
mb = Jms_word (usmd); /* form JMS word */
|
||||||
|
if (Write (ma, mb, WR)) return MM_ERR; /* store */
|
||||||
|
PC = (jea + 1) & IAMASK; /* new PC */
|
||||||
|
return MM_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset routine */
|
||||||
|
|
||||||
|
t_stat fp15_reset (DEVICE *dptr)
|
||||||
|
{
|
||||||
|
jea = 0;
|
||||||
|
fir = 0;
|
||||||
|
fguard = 0;
|
||||||
|
fma.exp = fma.hi = fma.lo = fma.sign = 0;
|
||||||
|
fmb.exp = fmb.hi = fmb.lo = fmb.sign = 0;
|
||||||
|
fmq.exp = fmq.hi = fmq.lo = fmq.sign = 0;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
|
@ -28,6 +28,7 @@
|
||||||
lp09 (PDP-9,15) LP09 line printer
|
lp09 (PDP-9,15) LP09 line printer
|
||||||
lp15 (PDP-15) LP15 line printer
|
lp15 (PDP-15) LP15 line printer
|
||||||
|
|
||||||
|
23-Jul-03 RMS Fixed overprint bug in Type 62
|
||||||
25-Apr-03 RMS Revised for extended file support
|
25-Apr-03 RMS Revised for extended file support
|
||||||
05-Feb-03 RMS Added LP09, fixed conditionalization
|
05-Feb-03 RMS Added LP09, fixed conditionalization
|
||||||
05-Oct-02 RMS Added DIB, device number support
|
05-Oct-02 RMS Added DIB, device number support
|
||||||
|
@ -53,7 +54,8 @@ extern int32 int_hwre[API_HLVL+1];
|
||||||
#define BPTR_MAX 40 /* pointer max */
|
#define BPTR_MAX 40 /* pointer max */
|
||||||
#define BPTR_MASK 077 /* buf ptr max */
|
#define BPTR_MASK 077 /* buf ptr max */
|
||||||
|
|
||||||
int32 lp62_iot = 0; /* saved state */
|
int32 lp62_spc = 0; /* print vs spc */
|
||||||
|
int32 lp62_ovrpr = 0; /* overprint */
|
||||||
int32 lp62_stopioe = 0;
|
int32 lp62_stopioe = 0;
|
||||||
int32 lp62_bp = 0; /* buffer ptr */
|
int32 lp62_bp = 0; /* buffer ptr */
|
||||||
char lp62_buf[LP62_BSIZE + 1] = { 0 };
|
char lp62_buf[LP62_BSIZE + 1] = { 0 };
|
||||||
|
@ -73,8 +75,8 @@ static const char *lp62_cc[] = {
|
||||||
"\f" };
|
"\f" };
|
||||||
|
|
||||||
DEVICE lp62_dev;
|
DEVICE lp62_dev;
|
||||||
int32 lp62_65 (int32 pulse, int32 AC);
|
int32 lp62_65 (int32 pulse, int32 dat);
|
||||||
int32 lp62_66 (int32 pulse, int32 AC);
|
int32 lp62_66 (int32 pulse, int32 dat);
|
||||||
int32 lp62_iors (void);
|
int32 lp62_iors (void);
|
||||||
t_stat lp62_svc (UNIT *uptr);
|
t_stat lp62_svc (UNIT *uptr);
|
||||||
t_stat lp62_reset (DEVICE *dptr);
|
t_stat lp62_reset (DEVICE *dptr);
|
||||||
|
@ -97,7 +99,8 @@ REG lp62_reg[] = {
|
||||||
{ FLDATA (DONE, int_hwre[API_LPT], INT_V_LPT) },
|
{ FLDATA (DONE, int_hwre[API_LPT], INT_V_LPT) },
|
||||||
{ FLDATA (SPC, int_hwre[API_LPTSPC], INT_V_LPTSPC) },
|
{ FLDATA (SPC, int_hwre[API_LPTSPC], INT_V_LPTSPC) },
|
||||||
{ DRDATA (BPTR, lp62_bp, 6) },
|
{ DRDATA (BPTR, lp62_bp, 6) },
|
||||||
{ ORDATA (STATE, lp62_iot, 6), REG_HRO },
|
{ ORDATA (STATE, lp62_spc, 6), REG_HRO },
|
||||||
|
{ FLDATA (OVRPR, lp62_ovrpr, 0), REG_HRO },
|
||||||
{ DRDATA (POS, lp62_unit.pos, T_ADDR_W), PV_LEFT },
|
{ DRDATA (POS, lp62_unit.pos, T_ADDR_W), PV_LEFT },
|
||||||
{ DRDATA (TIME, lp62_unit.wait, 24), PV_LEFT },
|
{ DRDATA (TIME, lp62_unit.wait, 24), PV_LEFT },
|
||||||
{ FLDATA (STOP_IOE, lp62_stopioe, 0) },
|
{ FLDATA (STOP_IOE, lp62_stopioe, 0) },
|
||||||
|
@ -118,62 +121,62 @@ DEVICE lp62_dev = {
|
||||||
|
|
||||||
/* IOT routines */
|
/* IOT routines */
|
||||||
|
|
||||||
int32 lp62_65 (int32 pulse, int32 AC)
|
int32 lp62_65 (int32 pulse, int32 dat)
|
||||||
{
|
{
|
||||||
int32 i;
|
int32 i;
|
||||||
|
|
||||||
if ((pulse & 01) && TST_INT (LPT)) AC = IOT_SKP | AC; /* LPSF */
|
if ((pulse & 01) && TST_INT (LPT)) dat = IOT_SKP | dat; /* LPSF */
|
||||||
if (pulse & 02) {
|
if (pulse & 02) {
|
||||||
int32 sb = pulse & 060; /* subopcode */
|
int32 sb = pulse & 060; /* subopcode */
|
||||||
if (sb == 000) CLR_INT (LPT); /* LPCF */
|
if (sb == 000) CLR_INT (LPT); /* LPCF */
|
||||||
if ((sb == 040) && (lp62_bp < BPTR_MAX)) { /* LPLD */
|
if ((sb == 040) && (lp62_bp < BPTR_MAX)) { /* LPLD */
|
||||||
i = lp62_bp * 3; /* cvt to chr ptr */
|
i = lp62_bp * 3; /* cvt to chr ptr */
|
||||||
lp62_buf[i] = lp62_trans[(AC >> 12) & 077];
|
lp62_buf[i] = lp62_trans[(dat >> 12) & 077];
|
||||||
lp62_buf[i + 1] = lp62_trans[(AC >> 6) & 077];
|
lp62_buf[i + 1] = lp62_trans[(dat >> 6) & 077];
|
||||||
lp62_buf[i + 2] = lp62_trans[AC & 077];
|
lp62_buf[i + 2] = lp62_trans[dat & 077];
|
||||||
lp62_bp = (lp62_bp + 1) & BPTR_MASK; }
|
lp62_bp = (lp62_bp + 1) & BPTR_MASK; }
|
||||||
}
|
}
|
||||||
if (pulse & 04) /* LPSE */
|
if (pulse & 04) { /* LPSE */
|
||||||
sim_activate (&lp62_unit, lp62_unit.wait); /* activate */
|
lp62_spc = 0; /* print */
|
||||||
return AC;
|
sim_activate (&lp62_unit, lp62_unit.wait); } /* activate */
|
||||||
|
return dat;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 lp62_66 (int32 pulse, int32 AC)
|
int32 lp62_66 (int32 pulse, int32 dat)
|
||||||
{
|
{
|
||||||
if ((pulse & 01) && TST_INT (LPTSPC)) /* LSSF */
|
if ((pulse & 01) && TST_INT (LPTSPC)) /* LSSF */
|
||||||
AC = IOT_SKP | AC;
|
dat = IOT_SKP | dat;
|
||||||
if (pulse & 02) CLR_INT (LPTSPC); /* LSCF */
|
if (pulse & 02) CLR_INT (LPTSPC); /* LSCF */
|
||||||
if (pulse & 04) { /* LSPR */
|
if (pulse & 04) { /* LSPR */
|
||||||
lp62_iot = 020 | (AC & 07); /* space, no print */
|
lp62_spc = 020 | (dat & 07); /* space */
|
||||||
sim_activate (&lp62_unit, lp62_unit.wait); } /* activate */
|
sim_activate (&lp62_unit, lp62_unit.wait); } /* activate */
|
||||||
return AC;
|
return dat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unit service, printer is in one of three states
|
/* Unit service, action based on lp62_spc
|
||||||
|
|
||||||
lp62_iot = 0 write buffer to file, set state to
|
lp62_spc = 0 write buffer to file, set overprint
|
||||||
lp62_iot = 10 write cr, then write buffer to file
|
lp62_spc = 2x space command x, clear overprint
|
||||||
lp62_iot = 2x space command x, then set state to 0
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
t_stat lp62_svc (UNIT *uptr)
|
t_stat lp62_svc (UNIT *uptr)
|
||||||
{
|
{
|
||||||
int32 i;
|
int32 i;
|
||||||
|
|
||||||
if (lp62_iot & 020) { /* space? */
|
if (lp62_spc) { /* space? */
|
||||||
SET_INT (LPTSPC); /* set flag */
|
SET_INT (LPTSPC); /* set flag */
|
||||||
if ((uptr->flags & UNIT_ATT) == 0) /* attached? */
|
if ((uptr->flags & UNIT_ATT) == 0) /* attached? */
|
||||||
return IORETURN (lp62_stopioe, SCPE_UNATT);
|
return IORETURN (lp62_stopioe, SCPE_UNATT);
|
||||||
fputs (lp62_cc[lp62_iot & 07], uptr->fileref); /* print cctl */
|
fputs (lp62_cc[lp62_spc & 07], uptr->fileref); /* print cctl */
|
||||||
if (ferror (uptr->fileref)) { /* error? */
|
if (ferror (uptr->fileref)) { /* error? */
|
||||||
perror ("LPT I/O error");
|
perror ("LPT I/O error");
|
||||||
clearerr (uptr->fileref);
|
clearerr (uptr->fileref);
|
||||||
return SCPE_IOERR; }
|
return SCPE_IOERR; }
|
||||||
lp62_iot = 0; } /* clear state */
|
lp62_ovrpr = 0; } /* clear overprint */
|
||||||
else { SET_INT (LPT); /* print */
|
else { SET_INT (LPT); /* print */
|
||||||
if ((uptr->flags & UNIT_ATT) == 0) /* attached? */
|
if ((uptr->flags & UNIT_ATT) == 0) /* attached? */
|
||||||
return IORETURN (lp62_stopioe, SCPE_UNATT);
|
return IORETURN (lp62_stopioe, SCPE_UNATT);
|
||||||
if (lp62_iot & 010) fputc ('\r', uptr->fileref);
|
if (lp62_ovrpr) fputc ('\r', uptr->fileref); /* overprint? */
|
||||||
fputs (lp62_buf, uptr->fileref); /* print buffer */
|
fputs (lp62_buf, uptr->fileref); /* print buffer */
|
||||||
if (ferror (uptr->fileref)) { /* test error */
|
if (ferror (uptr->fileref)) { /* test error */
|
||||||
perror ("LPT I/O error");
|
perror ("LPT I/O error");
|
||||||
|
@ -181,7 +184,7 @@ else { SET_INT (LPT); /* print */
|
||||||
return SCPE_IOERR; }
|
return SCPE_IOERR; }
|
||||||
lp62_bp = 0;
|
lp62_bp = 0;
|
||||||
for (i = 0; i <= LP62_BSIZE; i++) lp62_buf[i] = 0; /* clear buffer */
|
for (i = 0; i <= LP62_BSIZE; i++) lp62_buf[i] = 0; /* clear buffer */
|
||||||
lp62_iot = 010; } /* set state */
|
lp62_ovrpr = 1; } /* set overprint */
|
||||||
uptr->pos = ftell (uptr->fileref); /* update position */
|
uptr->pos = ftell (uptr->fileref); /* update position */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
@ -197,7 +200,8 @@ CLR_INT (LPTSPC);
|
||||||
sim_cancel (&lp62_unit); /* deactivate unit */
|
sim_cancel (&lp62_unit); /* deactivate unit */
|
||||||
lp62_bp = 0; /* clear buffer ptr */
|
lp62_bp = 0; /* clear buffer ptr */
|
||||||
for (i = 0; i <= LP62_BSIZE; i++) lp62_buf[i] = 0; /* clear buffer */
|
for (i = 0; i <= LP62_BSIZE; i++) lp62_buf[i] = 0; /* clear buffer */
|
||||||
lp62_iot = 0; /* clear state */
|
lp62_spc = 0; /* clear state */
|
||||||
|
lp62_ovrpr = 0; /* clear overprint */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,8 +239,8 @@ static const char *lp647_cc[] = {
|
||||||
"\f" };
|
"\f" };
|
||||||
|
|
||||||
DEVICE lp647_dev;
|
DEVICE lp647_dev;
|
||||||
int32 lp647_65 (int32 pulse, int32 AC);
|
int32 lp647_65 (int32 pulse, int32 dat);
|
||||||
int32 lp647_66 (int32 pulse, int32 AC);
|
int32 lp647_66 (int32 pulse, int32 dat);
|
||||||
int32 lp647_iors (void);
|
int32 lp647_iors (void);
|
||||||
t_stat lp647_svc (UNIT *uptr);
|
t_stat lp647_svc (UNIT *uptr);
|
||||||
t_stat lp647_reset (DEVICE *dptr);
|
t_stat lp647_reset (DEVICE *dptr);
|
||||||
|
@ -285,12 +289,12 @@ DEVICE lp647_dev = {
|
||||||
|
|
||||||
/* IOT routines */
|
/* IOT routines */
|
||||||
|
|
||||||
int32 lp647_65 (int32 pulse, int32 AC)
|
int32 lp647_65 (int32 pulse, int32 dat)
|
||||||
{
|
{
|
||||||
int32 i, sb;
|
int32 i, sb;
|
||||||
|
|
||||||
sb = pulse & 060; /* subcode */
|
sb = pulse & 060; /* subcode */
|
||||||
if ((pulse & 01) && lp647_don) AC = IOT_SKP | AC; /* LPSF */
|
if ((pulse & 01) && lp647_don) dat = IOT_SKP | dat; /* LPSF */
|
||||||
if (pulse & 02) { /* pulse 02 */
|
if (pulse & 02) { /* pulse 02 */
|
||||||
lp647_don = 0; /* clear done */
|
lp647_don = 0; /* clear done */
|
||||||
CLR_INT (LPT); /* clear int req */
|
CLR_INT (LPT); /* clear int req */
|
||||||
|
@ -310,32 +314,32 @@ if (pulse & 004) { /* LPDI */
|
||||||
break;
|
break;
|
||||||
case 040: /* LPB3 */
|
case 040: /* LPB3 */
|
||||||
if (lp647_bp < LP647_BSIZE) {
|
if (lp647_bp < LP647_BSIZE) {
|
||||||
lp647_buf[lp647_bp] = lp647_buf[lp647_bp] | ((AC >> 12) & 077);
|
lp647_buf[lp647_bp] = lp647_buf[lp647_bp] | ((dat >> 12) & 077);
|
||||||
lp647_bp = lp647_bp + 1; }
|
lp647_bp = lp647_bp + 1; }
|
||||||
case 020: /* LPB2 */
|
case 020: /* LPB2 */
|
||||||
if (lp647_bp < LP647_BSIZE) {
|
if (lp647_bp < LP647_BSIZE) {
|
||||||
lp647_buf[lp647_bp] = lp647_buf[lp647_bp] | ((AC >> 6) & 077);
|
lp647_buf[lp647_bp] = lp647_buf[lp647_bp] | ((dat >> 6) & 077);
|
||||||
lp647_bp = lp647_bp + 1; }
|
lp647_bp = lp647_bp + 1; }
|
||||||
case 060: /* LPB1 */
|
case 060: /* LPB1 */
|
||||||
if (lp647_bp < LP647_BSIZE) {
|
if (lp647_bp < LP647_BSIZE) {
|
||||||
lp647_buf[lp647_bp] = lp647_buf[lp647_bp] | (AC & 077);
|
lp647_buf[lp647_bp] = lp647_buf[lp647_bp] | (dat & 077);
|
||||||
lp647_bp = lp647_bp + 1; }
|
lp647_bp = lp647_bp + 1; }
|
||||||
lp647_don = 1; /* set done */
|
lp647_don = 1; /* set done */
|
||||||
if (lp647_ie) SET_INT (LPT); /* set int */
|
if (lp647_ie) SET_INT (LPT); /* set int */
|
||||||
break; } /* end case */
|
break; } /* end case */
|
||||||
}
|
}
|
||||||
return AC;
|
return dat;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 lp647_66 (int32 pulse, int32 AC)
|
int32 lp647_66 (int32 pulse, int32 dat)
|
||||||
{
|
{
|
||||||
if ((pulse & 01) && lp647_err) AC = IOT_SKP | AC; /* LPSE */
|
if ((pulse & 01) && lp647_err) dat = IOT_SKP | dat; /* LPSE */
|
||||||
if (pulse & 02) { /* LPCF */
|
if (pulse & 02) { /* LPCF */
|
||||||
lp647_don = 0; /* clear done, int */
|
lp647_don = 0; /* clear done, int */
|
||||||
CLR_INT (LPT); }
|
CLR_INT (LPT); }
|
||||||
if (pulse & 04) {
|
if (pulse & 04) {
|
||||||
if ((pulse & 060) < 060) { /* LPLS, LPPB, LPPS */
|
if ((pulse & 060) < 060) { /* LPLS, LPPB, LPPS */
|
||||||
lp647_iot = (pulse & 060) | (AC & 07); /* save parameters */
|
lp647_iot = (pulse & 060) | (dat & 07); /* save parameters */
|
||||||
sim_activate (&lp647_unit, lp647_unit.wait); } /* activate */
|
sim_activate (&lp647_unit, lp647_unit.wait); } /* activate */
|
||||||
#if defined (PDP9)
|
#if defined (PDP9)
|
||||||
else { /* LPEI */
|
else { /* LPEI */
|
||||||
|
@ -343,7 +347,7 @@ if (pulse & 04) {
|
||||||
if (lp647_don) SET_INT (LPT); }
|
if (lp647_don) SET_INT (LPT); }
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return AC;
|
return dat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unit service. lp647_iot specifies the action to be taken
|
/* Unit service. lp647_iot specifies the action to be taken
|
||||||
|
@ -442,7 +446,7 @@ int32 lp09_ie = 1; /* int enable */
|
||||||
int32 lp09_stopioe = 0;
|
int32 lp09_stopioe = 0;
|
||||||
DEVICE lp09_dev;
|
DEVICE lp09_dev;
|
||||||
|
|
||||||
int32 lp09_66 (int32 pulse, int32 AC);
|
int32 lp09_66 (int32 pulse, int32 dat);
|
||||||
int32 lp09_iors (void);
|
int32 lp09_iors (void);
|
||||||
t_stat lp09_svc (UNIT *uptr);
|
t_stat lp09_svc (UNIT *uptr);
|
||||||
t_stat lp09_reset (DEVICE *dptr);
|
t_stat lp09_reset (DEVICE *dptr);
|
||||||
|
@ -486,13 +490,13 @@ DEVICE lp09_dev = {
|
||||||
|
|
||||||
/* IOT routines */
|
/* IOT routines */
|
||||||
|
|
||||||
int32 lp09_66 (int32 pulse, int32 AC)
|
int32 lp09_66 (int32 pulse, int32 dat)
|
||||||
{
|
{
|
||||||
int32 sb = pulse & 060; /* subopcode */
|
int32 sb = pulse & 060; /* subopcode */
|
||||||
|
|
||||||
if (pulse & 001) {
|
if (pulse & 001) {
|
||||||
if ((sb == 000) && lp09_don) AC = IOT_SKP | AC; /* LSDF */
|
if ((sb == 000) && lp09_don) dat = IOT_SKP | dat; /* LSDF */
|
||||||
if ((sb == 020) && lp09_err) AC = IOT_SKP | AC; /* LSEF */
|
if ((sb == 020) && lp09_err) dat = IOT_SKP | dat; /* LSEF */
|
||||||
}
|
}
|
||||||
if (pulse & 002) {
|
if (pulse & 002) {
|
||||||
if (sb == 000) { /* LSCF */
|
if (sb == 000) { /* LSCF */
|
||||||
|
@ -501,11 +505,11 @@ if (pulse & 002) {
|
||||||
else if (sb == 020) { /* LPLD */
|
else if (sb == 020) { /* LPLD */
|
||||||
lp09_don = 0; /* clear done, int */
|
lp09_don = 0; /* clear done, int */
|
||||||
CLR_INT (LPT);
|
CLR_INT (LPT);
|
||||||
lp09_unit.buf = AC & 0177; /* load char */
|
lp09_unit.buf = dat & 0177; /* load char */
|
||||||
if ((lp09_unit.buf == 015) || (lp09_unit.buf == 014) ||
|
if ((lp09_unit.buf == 015) || (lp09_unit.buf == 014) ||
|
||||||
(lp09_unit.buf == 012))
|
(lp09_unit.buf == 012))
|
||||||
sim_activate (&lp09_unit, lp09_unit.wait);
|
sim_activate (&lp09_unit, lp09_unit.wait);
|
||||||
else AC = AC | (lp09_svc (&lp09_unit) << IOT_V_REASON); }
|
else dat = dat | (lp09_svc (&lp09_unit) << IOT_V_REASON); }
|
||||||
}
|
}
|
||||||
if (pulse & 004) {
|
if (pulse & 004) {
|
||||||
if (sb == 000) { /* LIOF */
|
if (sb == 000) { /* LIOF */
|
||||||
|
@ -515,7 +519,7 @@ if (pulse & 004) {
|
||||||
lp09_ie = 1; /* set int enab */
|
lp09_ie = 1; /* set int enab */
|
||||||
if (lp09_don) SET_INT (LPT); } /* if done, set int */
|
if (lp09_don) SET_INT (LPT); } /* if done, set int */
|
||||||
}
|
}
|
||||||
return AC;
|
return dat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unit service */
|
/* Unit service */
|
||||||
|
@ -608,8 +612,8 @@ int32 lp15_bp = 0;
|
||||||
char lp15_buf[LP15_BSIZE] = { 0 };
|
char lp15_buf[LP15_BSIZE] = { 0 };
|
||||||
|
|
||||||
DEVICE lp15_dev;
|
DEVICE lp15_dev;
|
||||||
int32 lp15_65 (int32 pulse, int32 AC);
|
int32 lp15_65 (int32 pulse, int32 dat);
|
||||||
int32 lp15_66 (int32 pulse, int32 AC);
|
int32 lp15_66 (int32 pulse, int32 dat);
|
||||||
int32 lp15_iors (void);
|
int32 lp15_iors (void);
|
||||||
t_stat lp15_svc (UNIT *uptr);
|
t_stat lp15_svc (UNIT *uptr);
|
||||||
t_stat lp15_reset (DEVICE *dptr);
|
t_stat lp15_reset (DEVICE *dptr);
|
||||||
|
@ -656,18 +660,18 @@ DEVICE lp15_dev = {
|
||||||
|
|
||||||
/* IOT routines */
|
/* IOT routines */
|
||||||
|
|
||||||
int32 lp15_65 (int32 pulse, int32 AC)
|
int32 lp15_65 (int32 pulse, int32 dat)
|
||||||
{
|
{
|
||||||
int32 header, sb;
|
int32 header, sb;
|
||||||
|
|
||||||
sb = pulse & 060; /* subopcode */
|
sb = pulse & 060; /* subopcode */
|
||||||
if (pulse & 01) {
|
if (pulse & 01) {
|
||||||
if ((sb == 000) && (lp15_sta & (STA_ERR | STA_DON))) /* LPSF */
|
if ((sb == 000) && (lp15_sta & (STA_ERR | STA_DON))) /* LPSF */
|
||||||
AC = IOT_SKP | AC;
|
dat = IOT_SKP | dat;
|
||||||
else if ((sb == 020) || (sb == 040)) { /* LPP1, LPPM */
|
else if ((sb == 020) || (sb == 040)) { /* LPP1, LPPM */
|
||||||
sim_activate (&lp15_unit, lp15_unit.wait); /* activate */
|
sim_activate (&lp15_unit, lp15_unit.wait); /* activate */
|
||||||
header = M[(M[LPT_CA] + 1) & ADDRMASK]; /* get first word */
|
header = M[(M[LPT_CA] + 1) & AMASK]; /* get first word */
|
||||||
M[LPT_CA] = (M[LPT_CA] + 2) & 0777777;
|
M[LPT_CA] = (M[LPT_CA] + 2) & DMASK;
|
||||||
lp15_mode = header & 1; /* mode */
|
lp15_mode = header & 1; /* mode */
|
||||||
if (sb == 040) lp15_lc = 1; /* line count */
|
if (sb == 040) lp15_lc = 1; /* line count */
|
||||||
else lp15_lc = (header >> 9) & 0377;
|
else lp15_lc = (header >> 9) & 0377;
|
||||||
|
@ -675,18 +679,18 @@ if (pulse & 01) {
|
||||||
lp15_bp = 0; } /* reset buf ptr */
|
lp15_bp = 0; } /* reset buf ptr */
|
||||||
else if (sb == 060) lp15_ie = 0; /* LPDI */
|
else if (sb == 060) lp15_ie = 0; /* LPDI */
|
||||||
}
|
}
|
||||||
if ((pulse & 02) && (sb == 040)) AC = AC | lp15_updsta (0); /* LPOS, LPRS */
|
if ((pulse & 02) && (sb == 040)) dat = dat | lp15_updsta (0); /* LPOS, LPRS */
|
||||||
if ((pulse & 04) && (sb == 040)) lp15_ie = 1; /* LPEI */
|
if ((pulse & 04) && (sb == 040)) lp15_ie = 1; /* LPEI */
|
||||||
lp15_updsta (0); /* update status */
|
lp15_updsta (0); /* update status */
|
||||||
return AC;
|
return dat;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 lp15_66 (int32 pulse, int32 AC)
|
int32 lp15_66 (int32 pulse, int32 dat)
|
||||||
{
|
{
|
||||||
if (pulse == 021) lp15_sta = lp15_sta & ~STA_DON; /* LPCD */
|
if (pulse == 021) lp15_sta = lp15_sta & ~STA_DON; /* LPCD */
|
||||||
if (pulse == 041) lp15_sta = 0; /* LPCF */
|
if (pulse == 041) lp15_sta = 0; /* LPCF */
|
||||||
lp15_updsta (0); /* update status */
|
lp15_updsta (0); /* update status */
|
||||||
return AC;
|
return dat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unit service */
|
/* Unit service */
|
||||||
|
@ -709,9 +713,9 @@ if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
|
||||||
return IORETURN (lp15_stopioe, SCPE_UNATT); }
|
return IORETURN (lp15_stopioe, SCPE_UNATT); }
|
||||||
|
|
||||||
for (more = 1; more != 0; ) { /* loop until ctrl */
|
for (more = 1; more != 0; ) { /* loop until ctrl */
|
||||||
w0 = M[(M[LPT_CA] + 1) & ADDRMASK]; /* get first word */
|
w0 = M[(M[LPT_CA] + 1) & AMASK]; /* get first word */
|
||||||
w1 = M[(M[LPT_CA] + 2) & ADDRMASK]; /* get second word */
|
w1 = M[(M[LPT_CA] + 2) & AMASK]; /* get second word */
|
||||||
M[LPT_CA] = (M[LPT_CA] + 2) & 0777777; /* advance mem addr */
|
M[LPT_CA] = (M[LPT_CA] + 2) & DMASK; /* advance mem addr */
|
||||||
if (lp15_mode) { /* unpacked? */
|
if (lp15_mode) { /* unpacked? */
|
||||||
c[0] = w0 & 0177;
|
c[0] = w0 & 0177;
|
||||||
c[1] = w1 & 0177;
|
c[1] = w1 & 0177;
|
||||||
|
|
|
@ -131,7 +131,7 @@ int32 mt_log = 0;
|
||||||
uint8 *mtxb = NULL; /* transfer buffer */
|
uint8 *mtxb = NULL; /* transfer buffer */
|
||||||
|
|
||||||
DEVICE mt_dev;
|
DEVICE mt_dev;
|
||||||
int32 mt (int32 pulse, int32 AC);
|
int32 mt (int32 pulse, int32 dat);
|
||||||
int32 mt_iors (void);
|
int32 mt_iors (void);
|
||||||
t_stat mt_svc (UNIT *uptr);
|
t_stat mt_svc (UNIT *uptr);
|
||||||
t_stat mt_reset (DEVICE *dptr);
|
t_stat mt_reset (DEVICE *dptr);
|
||||||
|
@ -194,7 +194,7 @@ DEVICE mt_dev = {
|
||||||
|
|
||||||
/* IOT routine */
|
/* IOT routine */
|
||||||
|
|
||||||
int32 mt (int32 pulse, int32 AC)
|
int32 mt (int32 pulse, int32 dat)
|
||||||
{
|
{
|
||||||
int32 f, sb;
|
int32 f, sb;
|
||||||
UNIT *uptr;
|
UNIT *uptr;
|
||||||
|
@ -205,21 +205,21 @@ sb = pulse & 060; /* subop */
|
||||||
if (pulse & 01) {
|
if (pulse & 01) {
|
||||||
if ((sb == 000) && (uptr->flags & UNIT_ATT) && /* MTTR */
|
if ((sb == 000) && (uptr->flags & UNIT_ATT) && /* MTTR */
|
||||||
!sim_is_active (uptr))
|
!sim_is_active (uptr))
|
||||||
AC = IOT_SKP | AC;
|
dat = IOT_SKP | dat;
|
||||||
else if ((sb == 020) && !mt_busy ()) /* MTCR */
|
else if ((sb == 020) && !mt_busy ()) /* MTCR */
|
||||||
AC = IOT_SKP | AC;
|
dat = IOT_SKP | dat;
|
||||||
else if ((sb == 040) && (mt_sta & (STA_ERR | STA_DON))) /* MTSF */
|
else if ((sb == 040) && (mt_sta & (STA_ERR | STA_DON))) /* MTSF */
|
||||||
AC = IOT_SKP | AC;
|
dat = IOT_SKP | dat;
|
||||||
}
|
}
|
||||||
if ((pulse & 06) && mt_log)
|
if ((pulse & 06) && mt_log)
|
||||||
printf ("[MT%d: IOT=%o, AC=%o, sta=%o]\n",
|
printf ("[MT%d: IOT=%o, AC=%o, sta=%o]\n",
|
||||||
GET_UNIT (mt_cu), 0707300 + pulse, AC, mt_sta);
|
GET_UNIT (mt_cu), 0707300 + pulse, dat, mt_sta);
|
||||||
if (pulse & 02) {
|
if (pulse & 02) {
|
||||||
if (sb == 000) AC = AC | (mt_cu & 0777700); /* MTRC */
|
if (sb == 000) dat = dat | (mt_cu & 0777700); /* MTRC */
|
||||||
else if (sb == 020) { /* MTAF, MTLC */
|
else if (sb == 020) { /* MTAF, MTLC */
|
||||||
if (!mt_busy ()) mt_cu = mt_sta = 0; /* if not busy, clr */
|
if (!mt_busy ()) mt_cu = mt_sta = 0; /* if not busy, clr */
|
||||||
mt_sta = mt_sta & ~(STA_ERR | STA_DON); } /* clear flags */
|
mt_sta = mt_sta & ~(STA_ERR | STA_DON); } /* clear flags */
|
||||||
else if (sb == 040) AC = AC | mt_sta; /* MTRS */
|
else if (sb == 040) dat = dat | mt_sta; /* MTRS */
|
||||||
}
|
}
|
||||||
if (pulse & 04) {
|
if (pulse & 04) {
|
||||||
if (sb == 000) { /* MTGO */
|
if (sb == 000) { /* MTGO */
|
||||||
|
@ -236,10 +236,10 @@ if (pulse & 04) {
|
||||||
else mt_sta = uptr->USTAT = 0; /* no, clear status */
|
else mt_sta = uptr->USTAT = 0; /* no, clear status */
|
||||||
sim_activate (uptr, mt_time); } } /* start io */
|
sim_activate (uptr, mt_time); } } /* start io */
|
||||||
if (sb == 020) /* MTCM, MTLC */
|
if (sb == 020) /* MTCM, MTLC */
|
||||||
mt_cu = (mt_cu & 0770700) | (AC & 0777700); /* load status */
|
mt_cu = (mt_cu & 0770700) | (dat & 0777700); /* load status */
|
||||||
}
|
}
|
||||||
mt_updcsta (mt_dev.units + GET_UNIT (mt_cu), 0); /* update status */
|
mt_updcsta (mt_dev.units + GET_UNIT (mt_cu), 0); /* update status */
|
||||||
return AC;
|
return dat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unit service
|
/* Unit service
|
||||||
|
@ -289,9 +289,9 @@ case FN_CMPARE: /* read/compare */
|
||||||
cbc = tbc; /* use smaller */
|
cbc = tbc; /* use smaller */
|
||||||
wc = PACKED (mt_cu)? ((tbc + 2) / 3): ((tbc + 1) / 2); }
|
wc = PACKED (mt_cu)? ((tbc + 2) / 3): ((tbc + 1) / 2); }
|
||||||
for (i = p = 0; i < wc; i++) { /* copy buffer */
|
for (i = p = 0; i < wc; i++) { /* copy buffer */
|
||||||
M[MT_WC] = (M[MT_WC] + 1) & 0777777; /* inc WC, CA */
|
M[MT_WC] = (M[MT_WC] + 1) & DMASK; /* inc WC, CA */
|
||||||
M[MT_CA] = (M[MT_CA] + 1) & 0777777;
|
M[MT_CA] = (M[MT_CA] + 1) & DMASK;
|
||||||
xma = M[MT_CA] & ADDRMASK;
|
xma = M[MT_CA] & AMASK;
|
||||||
if (PACKED (mt_cu)) { /* packed? */
|
if (PACKED (mt_cu)) { /* packed? */
|
||||||
c1 = mtxb[p++] & 077;
|
c1 = mtxb[p++] & 077;
|
||||||
c2 = mtxb[p++] & 077;
|
c2 = mtxb[p++] & 077;
|
||||||
|
@ -303,16 +303,16 @@ case FN_CMPARE: /* read/compare */
|
||||||
c = (c1 << 8) | c2; }
|
c = (c1 << 8) | c2; }
|
||||||
if ((f == FN_READ) && MEM_ADDR_OK (xma)) M[xma] = c;
|
if ((f == FN_READ) && MEM_ADDR_OK (xma)) M[xma] = c;
|
||||||
else if ((f == FN_CMPARE) && (c != (M[xma] &
|
else if ((f == FN_CMPARE) && (c != (M[xma] &
|
||||||
(PACKED (mt_cu)? 0777777: 0177777)))) {
|
(PACKED (mt_cu)? DMASK: 0177777)))) {
|
||||||
mt_updcsta (uptr, STA_CPE);
|
mt_updcsta (uptr, STA_CPE);
|
||||||
break; } }
|
break; } }
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FN_WRITE: /* write */
|
case FN_WRITE: /* write */
|
||||||
tbc = PACKED (mt_cu)? wc * 3: wc * 2;
|
tbc = PACKED (mt_cu)? wc * 3: wc * 2;
|
||||||
xma = M[MT_CA] & ADDRMASK; /* get mem addr */
|
xma = M[MT_CA] & AMASK; /* get mem addr */
|
||||||
for (i = p = 0; i < wc; i++) { /* copy buf to tape */
|
for (i = p = 0; i < wc; i++) { /* copy buf to tape */
|
||||||
xma = (xma + 1) & ADDRMASK; /* incr mem addr */
|
xma = (xma + 1) & AMASK; /* incr mem addr */
|
||||||
if (PACKED (mt_cu)) { /* packed? */
|
if (PACKED (mt_cu)) { /* packed? */
|
||||||
mtxb[p++] = (M[xma] >> 12) & 077;
|
mtxb[p++] = (M[xma] >> 12) & 077;
|
||||||
mtxb[p++] = (M[xma] >> 6) & 077;
|
mtxb[p++] = (M[xma] >> 6) & 077;
|
||||||
|
@ -323,7 +323,7 @@ case FN_WRITE: /* write */
|
||||||
if (st = sim_tape_wrrecf (uptr, mtxb, tbc)) /* write rec, err? */
|
if (st = sim_tape_wrrecf (uptr, mtxb, tbc)) /* write rec, err? */
|
||||||
r = mt_map_err (uptr, st); /* map error */
|
r = mt_map_err (uptr, st); /* map error */
|
||||||
else {
|
else {
|
||||||
M[MT_CA] = (M[MT_CA] + wc) & 0777777; /* advance mem addr */
|
M[MT_CA] = (M[MT_CA] + wc) & DMASK; /* advance mem addr */
|
||||||
M[MT_WC] = 0; } /* clear word cnt */
|
M[MT_WC] = 0; } /* clear word cnt */
|
||||||
mt_cu = mt_cu & ~CU_ERASE; /* clear erase flag */
|
mt_cu = mt_cu & ~CU_ERASE; /* clear erase flag */
|
||||||
break;
|
break;
|
||||||
|
@ -339,7 +339,7 @@ case FN_WREOF:
|
||||||
|
|
||||||
case FN_SPACEF: /* space forward */
|
case FN_SPACEF: /* space forward */
|
||||||
do {
|
do {
|
||||||
M[MT_WC] = (M[MT_WC] + 1) & 0777777; /* inc WC */
|
M[MT_WC] = (M[MT_WC] + 1) & DMASK; /* inc WC */
|
||||||
if (st = sim_tape_sprecf (uptr, &tbc)) { /* space rec fwd, err? */
|
if (st = sim_tape_sprecf (uptr, &tbc)) { /* space rec fwd, err? */
|
||||||
r = mt_map_err (uptr, st); /* map error */
|
r = mt_map_err (uptr, st); /* map error */
|
||||||
break; }
|
break; }
|
||||||
|
@ -349,7 +349,7 @@ case FN_SPACEF: /* space forward */
|
||||||
|
|
||||||
case FN_SPACER: /* space reverse */
|
case FN_SPACER: /* space reverse */
|
||||||
do {
|
do {
|
||||||
M[MT_WC] = (M[MT_WC] + 1) & 0777777; /* inc WC */
|
M[MT_WC] = (M[MT_WC] + 1) & DMASK; /* inc WC */
|
||||||
if (st = sim_tape_sprecr (uptr, &tbc)) { /* space rec rev, err? */
|
if (st = sim_tape_sprecr (uptr, &tbc)) { /* space rec rev, err? */
|
||||||
r = mt_map_err (uptr, st); /* map error */
|
r = mt_map_err (uptr, st); /* map error */
|
||||||
break; }
|
break; }
|
||||||
|
|
|
@ -149,7 +149,7 @@ if (pulse & 001) {
|
||||||
if (pulse & 002) {
|
if (pulse & 002) {
|
||||||
if (sb == 000) AC = AC | rb_make_da (rb_da); /* DBRD */
|
if (sb == 000) AC = AC | rb_make_da (rb_da); /* DBRD */
|
||||||
if (sb == 020) AC = AC | rb_sta; /* DBRS */
|
if (sb == 020) AC = AC | rb_sta; /* DBRS */
|
||||||
if (sb == 040) rb_ma = AC & ADDRMASK; /* DBLM */
|
if (sb == 040) rb_ma = AC & AMASK; /* DBLM */
|
||||||
}
|
}
|
||||||
if (pulse & 004) {
|
if (pulse & 004) {
|
||||||
if (sb == 000) rb_da = rb_set_da (AC, rb_da); /* DBLD */
|
if (sb == 000) rb_da = rb_set_da (AC, rb_da); /* DBLD */
|
||||||
|
@ -236,7 +236,7 @@ do { if (rb_sta & RBS_WR) { /* write? */
|
||||||
else if (MEM_ADDR_OK (rb_ma)) /* read, valid addr? */
|
else if (MEM_ADDR_OK (rb_ma)) /* read, valid addr? */
|
||||||
M[rb_ma] = *(((int32 *) uptr->filebuf) + rb_da);
|
M[rb_ma] = *(((int32 *) uptr->filebuf) + rb_da);
|
||||||
rb_wc = (rb_wc + 1) & 0177777; /* incr word count */
|
rb_wc = (rb_wc + 1) & 0177777; /* incr word count */
|
||||||
rb_ma = (rb_ma + 1) & ADDRMASK; /* incr mem addr */
|
rb_ma = (rb_ma + 1) & AMASK; /* incr mem addr */
|
||||||
rb_da = rb_da + 1; /* incr disk addr */
|
rb_da = rb_da + 1; /* incr disk addr */
|
||||||
if (rb_da > RB_SIZE) rb_da = 0; /* disk wraparound? */
|
if (rb_da > RB_SIZE) rb_da = 0; /* disk wraparound? */
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
rf (PDP-9) RF09/RF09
|
rf (PDP-9) RF09/RF09
|
||||||
(PDP-15) RF15/RS09
|
(PDP-15) RF15/RS09
|
||||||
|
|
||||||
|
26-Jul-03 RMS Fixed bug in set size routine
|
||||||
14-Mar-03 RMS Fixed variable platter interaction with save/restore
|
14-Mar-03 RMS Fixed variable platter interaction with save/restore
|
||||||
03-Mar-03 RMS Fixed autosizing
|
03-Mar-03 RMS Fixed autosizing
|
||||||
12-Feb-03 RMS Removed 8 platter sizing hack
|
12-Feb-03 RMS Removed 8 platter sizing hack
|
||||||
|
@ -113,8 +114,8 @@ int32 rf_burst = 1; /* burst mode flag */
|
||||||
int32 rf_stopioe = 1; /* stop on error */
|
int32 rf_stopioe = 1; /* stop on error */
|
||||||
|
|
||||||
DEVICE rf_dev;
|
DEVICE rf_dev;
|
||||||
int32 rf70 (int32 pulse, int32 AC);
|
int32 rf70 (int32 pulse, int32 dat);
|
||||||
int32 rf72 (int32 pulse, int32 AC);
|
int32 rf72 (int32 pulse, int32 dat);
|
||||||
int32 rf_iors (void);
|
int32 rf_iors (void);
|
||||||
t_stat rf_svc (UNIT *uptr);
|
t_stat rf_svc (UNIT *uptr);
|
||||||
t_stat rf_reset (DEVICE *dptr);
|
t_stat rf_reset (DEVICE *dptr);
|
||||||
|
@ -151,14 +152,14 @@ REG rf_reg[] = {
|
||||||
{ NULL } };
|
{ NULL } };
|
||||||
|
|
||||||
MTAB rf_mod[] = {
|
MTAB rf_mod[] = {
|
||||||
{ UNIT_PLAT, 0, NULL, "1P", &rf_set_size },
|
{ UNIT_PLAT, (0 << UNIT_V_PLAT), NULL, "1P", &rf_set_size },
|
||||||
{ UNIT_PLAT, 1, NULL, "2P", &rf_set_size },
|
{ UNIT_PLAT, (1 << UNIT_V_PLAT), NULL, "2P", &rf_set_size },
|
||||||
{ UNIT_PLAT, 2, NULL, "3P", &rf_set_size },
|
{ UNIT_PLAT, (2 << UNIT_V_PLAT), NULL, "3P", &rf_set_size },
|
||||||
{ UNIT_PLAT, 3, NULL, "4P", &rf_set_size },
|
{ UNIT_PLAT, (3 << UNIT_V_PLAT), NULL, "4P", &rf_set_size },
|
||||||
{ UNIT_PLAT, 4, NULL, "5P", &rf_set_size },
|
{ UNIT_PLAT, (4 << UNIT_V_PLAT), NULL, "5P", &rf_set_size },
|
||||||
{ UNIT_PLAT, 5, NULL, "6P", &rf_set_size },
|
{ UNIT_PLAT, (5 << UNIT_V_PLAT), NULL, "6P", &rf_set_size },
|
||||||
{ UNIT_PLAT, 6, NULL, "7P", &rf_set_size },
|
{ UNIT_PLAT, (6 << UNIT_V_PLAT), NULL, "7P", &rf_set_size },
|
||||||
{ UNIT_PLAT, 7, NULL, "8P", &rf_set_size },
|
{ UNIT_PLAT, (7 << UNIT_V_PLAT), NULL, "8P", &rf_set_size },
|
||||||
{ UNIT_AUTO, UNIT_AUTO, "autosize", "AUTOSIZE", NULL },
|
{ UNIT_AUTO, UNIT_AUTO, "autosize", "AUTOSIZE", NULL },
|
||||||
{ MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO", &set_devno, &show_devno },
|
{ MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO", &set_devno, &show_devno },
|
||||||
{ 0 } };
|
{ 0 } };
|
||||||
|
@ -172,14 +173,14 @@ DEVICE rf_dev = {
|
||||||
|
|
||||||
/* IOT routines */
|
/* IOT routines */
|
||||||
|
|
||||||
int32 rf70 (int32 pulse, int32 AC)
|
int32 rf70 (int32 pulse, int32 dat)
|
||||||
{
|
{
|
||||||
int32 t, sb;
|
int32 t, sb;
|
||||||
|
|
||||||
sb = pulse & 060; /* subopcode */
|
sb = pulse & 060; /* subopcode */
|
||||||
if (pulse & 01) {
|
if (pulse & 01) {
|
||||||
if ((sb == 000) && (rf_sta & (RFS_ERR | RFS_DON)))
|
if ((sb == 000) && (rf_sta & (RFS_ERR | RFS_DON)))
|
||||||
AC = IOT_SKP | AC; /* DSSF */
|
dat = IOT_SKP | dat; /* DSSF */
|
||||||
else if (sb == 020) rf_reset (&rf_dev); /* DSCC */
|
else if (sb == 020) rf_reset (&rf_dev); /* DSCC */
|
||||||
else if (sb == 040) { /* DSCF */
|
else if (sb == 040) { /* DSCF */
|
||||||
if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy inhibits */
|
if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy inhibits */
|
||||||
|
@ -187,19 +188,19 @@ if (pulse & 01) {
|
||||||
}
|
}
|
||||||
if (pulse & 02) {
|
if (pulse & 02) {
|
||||||
if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy sets PGE */
|
if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy sets PGE */
|
||||||
else if (sb == 000) AC = AC | rf_dbuf; /* DRBR */
|
else if (sb == 000) dat = dat | rf_dbuf; /* DRBR */
|
||||||
else if (sb == 020) /* DRAL */
|
else if (sb == 020) /* DRAL */
|
||||||
AC = AC | (rf_da & 0777777);
|
dat = dat | (rf_da & DMASK);
|
||||||
else if (sb == 040) /* DSFX */
|
else if (sb == 040) /* DSFX */
|
||||||
rf_sta = rf_sta ^ (AC & (RFS_FNC | RFS_IE)); /* xor func */
|
rf_sta = rf_sta ^ (dat & (RFS_FNC | RFS_IE)); /* xor func */
|
||||||
else if (sb == 060) /* DRAH */
|
else if (sb == 060) /* DRAH */
|
||||||
AC = AC | (rf_da >> 18) | ((rf_sta & RFS_NED)? 010: 0);
|
dat = dat | (rf_da >> 18) | ((rf_sta & RFS_NED)? 010: 0);
|
||||||
}
|
}
|
||||||
if (pulse & 04) {
|
if (pulse & 04) {
|
||||||
if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy sets PGE */
|
if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy sets PGE */
|
||||||
else if (sb == 000) rf_dbuf = AC & 0777777; /* DLBR */
|
else if (sb == 000) rf_dbuf = dat & DMASK; /* DLBR */
|
||||||
else if (sb == 020) /* DLAL */
|
else if (sb == 020) /* DLAL */
|
||||||
rf_da = (rf_da & ~0777777) | (AC & 0777777);
|
rf_da = (rf_da & ~DMASK) | (dat & DMASK);
|
||||||
else if (sb == 040) { /* DSCN */
|
else if (sb == 040) { /* DSCN */
|
||||||
rf_sta = rf_sta & ~RFS_DON; /* clear done */
|
rf_sta = rf_sta & ~RFS_DON; /* clear done */
|
||||||
if (GET_FNC (rf_sta) != FN_NOP) {
|
if (GET_FNC (rf_sta) != FN_NOP) {
|
||||||
|
@ -207,20 +208,20 @@ if (pulse & 04) {
|
||||||
if (t < 0) t = t + RF_NUMWD; /* wrap around? */
|
if (t < 0) t = t + RF_NUMWD; /* wrap around? */
|
||||||
sim_activate (&rf_unit, t * rf_time); } } /* schedule op */
|
sim_activate (&rf_unit, t * rf_time); } } /* schedule op */
|
||||||
else if (sb == 060) { /* DLAH */
|
else if (sb == 060) { /* DLAH */
|
||||||
rf_da = (rf_da & 0777777) | ((AC & 07) << 18);
|
rf_da = (rf_da & DMASK) | ((dat & 07) << 18);
|
||||||
if ((uint32) rf_da >= rf_unit.capac) /* for sizing */
|
if ((uint32) rf_da >= rf_unit.capac) /* for sizing */
|
||||||
rf_updsta (RFS_NED); }
|
rf_updsta (RFS_NED); }
|
||||||
}
|
}
|
||||||
rf_updsta (0); /* update status */
|
rf_updsta (0); /* update status */
|
||||||
return AC;
|
return dat;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 rf72 (int32 pulse, int32 AC)
|
int32 rf72 (int32 pulse, int32 dat)
|
||||||
{
|
{
|
||||||
int32 sb = pulse & 060;
|
int32 sb = pulse & 060;
|
||||||
|
|
||||||
if (pulse & 02) {
|
if (pulse & 02) {
|
||||||
if (sb == 000) AC = AC | GET_POS (rf_time) | /* DLOK */
|
if (sb == 000) dat = dat | GET_POS (rf_time) | /* DLOK */
|
||||||
(sim_is_active (&rf_unit)? 0400000: 0);
|
(sim_is_active (&rf_unit)? 0400000: 0);
|
||||||
else if (sb == 040) { /* DSCD */
|
else if (sb == 040) { /* DSCD */
|
||||||
if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy inhibits */
|
if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy inhibits */
|
||||||
|
@ -228,9 +229,9 @@ if (pulse & 02) {
|
||||||
rf_updsta (0); }
|
rf_updsta (0); }
|
||||||
else if (sb == 060) { /* DSRS */
|
else if (sb == 060) { /* DSRS */
|
||||||
if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy sets PGE */
|
if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy sets PGE */
|
||||||
AC = AC | rf_updsta (0); }
|
dat = dat | rf_updsta (0); }
|
||||||
}
|
}
|
||||||
return AC;
|
return dat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unit service - assumes the entire disk is buffered */
|
/* Unit service - assumes the entire disk is buffered */
|
||||||
|
@ -247,8 +248,8 @@ f = GET_FNC (rf_sta); /* get function */
|
||||||
do { if ((uint32) rf_da >= uptr->capac) { /* disk overflow? */
|
do { if ((uint32) rf_da >= uptr->capac) { /* disk overflow? */
|
||||||
rf_updsta (RFS_NED); /* nx disk error */
|
rf_updsta (RFS_NED); /* nx disk error */
|
||||||
break; }
|
break; }
|
||||||
M[RF_WC] = (M[RF_WC] + 1) & 0777777; /* incr word count */
|
M[RF_WC] = (M[RF_WC] + 1) & DMASK; /* incr word count */
|
||||||
pa = M[RF_CA] = (M[RF_CA] + 1) & ADDRMASK; /* incr mem addr */
|
pa = M[RF_CA] = (M[RF_CA] + 1) & AMASK; /* incr mem addr */
|
||||||
if ((f == FN_READ) && MEM_ADDR_OK (pa)) /* read? */
|
if ((f == FN_READ) && MEM_ADDR_OK (pa)) /* read? */
|
||||||
M[pa] = *(((int32 *) uptr->filebuf) + rf_da);
|
M[pa] = *(((int32 *) uptr->filebuf) + rf_da);
|
||||||
if ((f == FN_WCHK) && /* write check? */
|
if ((f == FN_WCHK) && /* write check? */
|
||||||
|
@ -323,9 +324,9 @@ return attach_unit (uptr, cptr);
|
||||||
|
|
||||||
t_stat rf_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
|
t_stat rf_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||||
{
|
{
|
||||||
if ((val < 0) || (val > RF_NUMDK)) return SCPE_IERR;
|
if (val < 0) return SCPE_IERR;
|
||||||
if (uptr->flags & UNIT_ATT) return SCPE_ALATT;
|
if (uptr->flags & UNIT_ATT) return SCPE_ALATT;
|
||||||
uptr->capac = (val + 1) * RF_DKSIZE;
|
uptr->capac = UNIT_GETP (val) * RF_DKSIZE;
|
||||||
uptr->flags = uptr->flags & ~UNIT_AUTO;
|
uptr->flags = uptr->flags & ~UNIT_AUTO;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,8 +144,8 @@ int32 rp_swait = 10; /* seek time */
|
||||||
int32 rp_rwait = 10; /* rotate time */
|
int32 rp_rwait = 10; /* rotate time */
|
||||||
|
|
||||||
DEVICE rp_dev;
|
DEVICE rp_dev;
|
||||||
int32 rp63 (int32 pulse, int32 AC);
|
int32 rp63 (int32 pulse, int32 dat);
|
||||||
int32 rp64 (int32 pulse, int32 AC);
|
int32 rp64 (int32 pulse, int32 dat);
|
||||||
int32 rp_iors (void);
|
int32 rp_iors (void);
|
||||||
t_stat rp_svc (UNIT *uptr);
|
t_stat rp_svc (UNIT *uptr);
|
||||||
void rp_updsta (int32 newa, int32 newb);
|
void rp_updsta (int32 newa, int32 newb);
|
||||||
|
@ -202,7 +202,7 @@ DEVICE rp_dev = {
|
||||||
|
|
||||||
/* IOT routines */
|
/* IOT routines */
|
||||||
|
|
||||||
int32 rp63 (int32 pulse, int32 AC)
|
int32 rp63 (int32 pulse, int32 dat)
|
||||||
{
|
{
|
||||||
int32 sb = pulse & 060; /* subopcode */
|
int32 sb = pulse & 060; /* subopcode */
|
||||||
|
|
||||||
|
@ -210,24 +210,24 @@ rp_updsta (0, 0);
|
||||||
if (pulse & 01) {
|
if (pulse & 01) {
|
||||||
if ((sb == 000) && /* DPSF */
|
if ((sb == 000) && /* DPSF */
|
||||||
((rp_sta & (STA_DON | STA_ERR)) || (rp_stb & STB_ATTN)))
|
((rp_sta & (STA_DON | STA_ERR)) || (rp_stb & STB_ATTN)))
|
||||||
AC = IOT_SKP | AC;
|
dat = IOT_SKP | dat;
|
||||||
else if ((sb == 020) && (rp_stb & STB_ATTN)) /* DPSA */
|
else if ((sb == 020) && (rp_stb & STB_ATTN)) /* DPSA */
|
||||||
AC = IOT_SKP | AC;
|
dat = IOT_SKP | dat;
|
||||||
else if ((sb == 040) && (rp_sta & STA_DON)) /* DPSJ */
|
else if ((sb == 040) && (rp_sta & STA_DON)) /* DPSJ */
|
||||||
AC = IOT_SKP | AC;
|
dat = IOT_SKP | dat;
|
||||||
else if ((sb == 060) && (rp_sta & STA_ERR)) /* DPSE */
|
else if ((sb == 060) && (rp_sta & STA_ERR)) /* DPSE */
|
||||||
AC = IOT_SKP | AC;
|
dat = IOT_SKP | dat;
|
||||||
}
|
}
|
||||||
if (pulse & 02) {
|
if (pulse & 02) {
|
||||||
if (sb == 000) AC = AC | rp_sta; /* DPOSA */
|
if (sb == 000) dat = dat | rp_sta; /* DPOSA */
|
||||||
else if (sb == 020) AC = AC | rp_stb; /* DPOSB */
|
else if (sb == 020) dat = dat | rp_stb; /* DPOSB */
|
||||||
}
|
}
|
||||||
if (pulse & 04) {
|
if (pulse & 04) {
|
||||||
if (rp_busy) { /* busy? */
|
if (rp_busy) { /* busy? */
|
||||||
rp_updsta (0, STB_PGE);
|
rp_updsta (0, STB_PGE);
|
||||||
return AC; }
|
return dat; }
|
||||||
else if (sb == 000) { /* DPLA */
|
else if (sb == 000) { /* DPLA */
|
||||||
rp_da = AC & 0777777;
|
rp_da = dat & DMASK;
|
||||||
if (GET_SECT (rp_da) >= RP_NUMSC) rp_updsta (STA_NXS, 0);
|
if (GET_SECT (rp_da) >= RP_NUMSC) rp_updsta (STA_NXS, 0);
|
||||||
if (GET_SURF (rp_da) >= RP_NUMSF) rp_updsta (STA_NXF, 0);
|
if (GET_SURF (rp_da) >= RP_NUMSF) rp_updsta (STA_NXF, 0);
|
||||||
if (GET_CYL (rp_da) >= RP_NUMCY) rp_updsta (STA_NXC, 0); }
|
if (GET_CYL (rp_da) >= RP_NUMCY) rp_updsta (STA_NXC, 0); }
|
||||||
|
@ -236,38 +236,38 @@ if (pulse & 04) {
|
||||||
rp_stb = rp_stb & ~(STB_FME | STB_WPE | STB_LON | STB_WCE |
|
rp_stb = rp_stb & ~(STB_FME | STB_WPE | STB_LON | STB_WCE |
|
||||||
STB_TME | STB_PGE | STB_EOP);
|
STB_TME | STB_PGE | STB_EOP);
|
||||||
rp_updsta (0, 0); }
|
rp_updsta (0, 0); }
|
||||||
else if (sb == 040) rp_ma = AC & 0777777; /* DPCA */
|
else if (sb == 040) rp_ma = dat & DMASK; /* DPCA */
|
||||||
else if (sb == 060) rp_wc = AC & 0777777; /* DPWC */
|
else if (sb == 060) rp_wc = dat & DMASK; /* DPWC */
|
||||||
}
|
}
|
||||||
return AC;
|
return dat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* IOT 64 */
|
/* IOT 64 */
|
||||||
|
|
||||||
int32 rp64 (int32 pulse, int32 AC)
|
int32 rp64 (int32 pulse, int32 dat)
|
||||||
{
|
{
|
||||||
int32 u, f, c, sb;
|
int32 u, f, c, sb;
|
||||||
UNIT *uptr;
|
UNIT *uptr;
|
||||||
|
|
||||||
sb = pulse & 060;
|
sb = pulse & 060;
|
||||||
if (pulse & 01) {
|
if (pulse & 01) {
|
||||||
if (sb == 020) AC = IOT_SKP | AC; /* DPSN */
|
if (sb == 020) dat = IOT_SKP | dat; /* DPSN */
|
||||||
}
|
}
|
||||||
if (pulse & 02) {
|
if (pulse & 02) {
|
||||||
if (sb == 000) AC = AC | rp_unit[GET_UNIT (rp_sta)].CYL; /* DPOU */
|
if (sb == 000) dat = dat | rp_unit[GET_UNIT (rp_sta)].CYL; /* DPOU */
|
||||||
else if (sb == 020) AC = AC | rp_da; /* DPOA */
|
else if (sb == 020) dat = dat | rp_da; /* DPOA */
|
||||||
else if (sb == 040) AC = AC | rp_ma; /* DPOC */
|
else if (sb == 040) dat = dat | rp_ma; /* DPOC */
|
||||||
else if (sb == 060) AC = AC | rp_wc; /* DPOW */
|
else if (sb == 060) dat = dat | rp_wc; /* DPOW */
|
||||||
}
|
}
|
||||||
if (pulse & 04) {
|
if (pulse & 04) {
|
||||||
if (rp_busy) { /* busy? */
|
if (rp_busy) { /* busy? */
|
||||||
rp_updsta (0, STB_PGE);
|
rp_updsta (0, STB_PGE);
|
||||||
return AC; }
|
return dat; }
|
||||||
if (sb == 000) rp_sta = rp_sta & ~STA_RW; /* DPCF */
|
if (sb == 000) rp_sta = rp_sta & ~STA_RW; /* DPCF */
|
||||||
else if (sb == 020) rp_sta = rp_sta & (AC | ~STA_RW); /* DPLZ */
|
else if (sb == 020) rp_sta = rp_sta & (dat | ~STA_RW); /* DPLZ */
|
||||||
else if (sb == 040) rp_sta = rp_sta | (AC & STA_RW); /* DPLO */
|
else if (sb == 040) rp_sta = rp_sta | (dat & STA_RW); /* DPLO */
|
||||||
else if (sb == 060) /* DPLF */
|
else if (sb == 060) /* DPLF */
|
||||||
rp_sta = (rp_sta & ~STA_RW) | (AC & STA_RW);
|
rp_sta = (rp_sta & ~STA_RW) | (dat & STA_RW);
|
||||||
rp_sta = rp_sta & ~STA_DON; /* clear done */
|
rp_sta = rp_sta & ~STA_DON; /* clear done */
|
||||||
u = GET_UNIT (rp_sta); /* get unit num */
|
u = GET_UNIT (rp_sta); /* get unit num */
|
||||||
uptr = rp_dev.units + u; /* select unit */
|
uptr = rp_dev.units + u; /* select unit */
|
||||||
|
@ -286,7 +286,7 @@ if (pulse & 04) {
|
||||||
sim_activate (uptr, MAX (RP_MIN, c + rp_rwait)); } }
|
sim_activate (uptr, MAX (RP_MIN, c + rp_rwait)); } }
|
||||||
}
|
}
|
||||||
rp_updsta (0, 0);
|
rp_updsta (0, 0);
|
||||||
return AC;
|
return dat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unit service
|
/* Unit service
|
||||||
|
@ -342,7 +342,7 @@ if (rp_sta & (STA_NXS | STA_NXF | STA_NXC)) { /* or bad disk addr? */
|
||||||
rp_updsta (STA_DON, STB_SUFU); /* done, unsafe */
|
rp_updsta (STA_DON, STB_SUFU); /* done, unsafe */
|
||||||
return SCPE_OK; }
|
return SCPE_OK; }
|
||||||
|
|
||||||
pa = rp_ma & ADDRMASK; /* get mem addr */
|
pa = rp_ma & AMASK; /* get mem addr */
|
||||||
da = GET_DA (rp_da) * RP_NUMWD; /* get disk addr */
|
da = GET_DA (rp_da) * RP_NUMWD; /* get disk addr */
|
||||||
wc = 01000000 - rp_wc; /* get true wc */
|
wc = 01000000 - rp_wc; /* get true wc */
|
||||||
if (((uint32) (pa + wc)) > MEMSIZE) { /* memory overrun? */
|
if (((uint32) (pa + wc)) > MEMSIZE) { /* memory overrun? */
|
||||||
|
@ -373,8 +373,8 @@ if ((f == FN_WRCHK) && (err == 0)) { /* write check? */
|
||||||
if (comp != M[pa + i]) rp_updsta (0, STB_WCE); }
|
if (comp != M[pa + i]) rp_updsta (0, STB_WCE); }
|
||||||
err = ferror (uptr->fileref); }
|
err = ferror (uptr->fileref); }
|
||||||
|
|
||||||
rp_wc = (rp_wc + wc) & 0777777; /* final word count */
|
rp_wc = (rp_wc + wc) & DMASK; /* final word count */
|
||||||
rp_ma = (rp_ma + wc) & 0777777; /* final mem addr */
|
rp_ma = (rp_ma + wc) & DMASK; /* final mem addr */
|
||||||
da = (da + wc + (RP_NUMWD - 1)) / RP_NUMWD; /* final sector num */
|
da = (da + wc + (RP_NUMWD - 1)) / RP_NUMWD; /* final sector num */
|
||||||
cyl = da / (RP_NUMSC * RP_NUMSF); /* get cyl */
|
cyl = da / (RP_NUMSC * RP_NUMSF); /* get cyl */
|
||||||
if (cyl >= RP_NUMCY) cyl = RP_NUMCY - 1;
|
if (cyl >= RP_NUMCY) cyl = RP_NUMCY - 1;
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
tto teleprinter
|
tto teleprinter
|
||||||
clk clock
|
clk clock
|
||||||
|
|
||||||
|
26-Jul-03 RMS Increased PTP, TTO timeouts for PDP-15 operating systems
|
||||||
|
Added hardware read-in mode support for PDP-7/9/15
|
||||||
25-Apr-03 RMS Revised for extended file support
|
25-Apr-03 RMS Revised for extended file support
|
||||||
14-Mar-03 RMS Clean up flags on detach
|
14-Mar-03 RMS Clean up flags on detach
|
||||||
01-Mar-03 RMS Added SET/SHOW CLK FREQ support, SET TTI CTRL-C support
|
01-Mar-03 RMS Added SET/SHOW CLK FREQ support, SET TTI CTRL-C support
|
||||||
|
@ -62,7 +64,7 @@
|
||||||
#define UNIT_PASCII (1 << UNIT_V_PASCII)
|
#define UNIT_PASCII (1 << UNIT_V_PASCII)
|
||||||
|
|
||||||
extern int32 M[];
|
extern int32 M[];
|
||||||
extern int32 int_hwre[API_HLVL+1], saved_PC;
|
extern int32 int_hwre[API_HLVL+1], PC, ASW;
|
||||||
extern int32 sim_switches;
|
extern int32 sim_switches;
|
||||||
extern UNIT cpu_unit;
|
extern UNIT cpu_unit;
|
||||||
|
|
||||||
|
@ -74,10 +76,10 @@ int32 tto_state = 0;
|
||||||
int32 clk_tps = 60; /* ticks/second */
|
int32 clk_tps = 60; /* ticks/second */
|
||||||
int32 tmxr_poll = 16000; /* term mux poll */
|
int32 tmxr_poll = 16000; /* term mux poll */
|
||||||
|
|
||||||
int32 ptr (int32 pulse, int32 AC);
|
int32 ptr (int32 pulse, int32 dat);
|
||||||
int32 ptp (int32 pulse, int32 AC);
|
int32 ptp (int32 pulse, int32 dat);
|
||||||
int32 tti (int32 pulse, int32 AC);
|
int32 tti (int32 pulse, int32 dat);
|
||||||
int32 tto (int32 pulse, int32 AC);
|
int32 tto (int32 pulse, int32 dat);
|
||||||
int32 clk_iors (void);
|
int32 clk_iors (void);
|
||||||
int32 ptr_iors (void);
|
int32 ptr_iors (void);
|
||||||
int32 ptp_iors (void);
|
int32 ptp_iors (void);
|
||||||
|
@ -188,7 +190,7 @@ DEVICE ptr_dev = {
|
||||||
DIB ptp_dib = { DEV_PTP, 1, &ptp_iors, { &ptp } };
|
DIB ptp_dib = { DEV_PTP, 1, &ptp_iors, { &ptp } };
|
||||||
|
|
||||||
UNIT ptp_unit = {
|
UNIT ptp_unit = {
|
||||||
UDATA (&ptp_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT };
|
UDATA (&ptp_svc, UNIT_SEQ+UNIT_ATTABLE, 0), 1000 };
|
||||||
|
|
||||||
REG ptp_reg[] = {
|
REG ptp_reg[] = {
|
||||||
{ ORDATA (BUF, ptp_unit.buf, 8) },
|
{ ORDATA (BUF, ptp_unit.buf, 8) },
|
||||||
|
@ -327,7 +329,7 @@ static const char tto_trans[64] = {
|
||||||
|
|
||||||
DIB tto_dib = { DEV_TTO, 1, &tto_iors, { &tto } };
|
DIB tto_dib = { DEV_TTO, 1, &tto_iors, { &tto } };
|
||||||
|
|
||||||
UNIT tto_unit = { UDATA (&tto_svc, UNIT_KSR, 0), SERIAL_OUT_WAIT };
|
UNIT tto_unit = { UDATA (&tto_svc, UNIT_KSR, 0), 1000 };
|
||||||
|
|
||||||
REG tto_reg[] = {
|
REG tto_reg[] = {
|
||||||
{ ORDATA (BUF, tto_unit.buf, TTO_WIDTH) },
|
{ ORDATA (BUF, tto_unit.buf, TTO_WIDTH) },
|
||||||
|
@ -358,10 +360,10 @@ DEVICE tto_dev = {
|
||||||
|
|
||||||
/* Clock: IOT routine */
|
/* Clock: IOT routine */
|
||||||
|
|
||||||
int32 clk (int32 pulse, int32 AC)
|
int32 clk (int32 pulse, int32 dat)
|
||||||
{
|
{
|
||||||
if (pulse & 001) { /* CLSF */
|
if (pulse & 001) { /* CLSF */
|
||||||
if (TST_INT (CLK)) AC = AC | IOT_SKP; }
|
if (TST_INT (CLK)) dat = dat | IOT_SKP; }
|
||||||
if (pulse & 004) { /* CLON/CLOF */
|
if (pulse & 004) { /* CLON/CLOF */
|
||||||
if (pulse & 040) { /* CLON */
|
if (pulse & 040) { /* CLON */
|
||||||
CLR_INT (CLK); /* clear flag */
|
CLR_INT (CLK); /* clear flag */
|
||||||
|
@ -370,7 +372,7 @@ if (pulse & 004) { /* CLON/CLOF */
|
||||||
sim_activate (&clk_unit, /* start, calibr */
|
sim_activate (&clk_unit, /* start, calibr */
|
||||||
sim_rtc_init (clk_unit.wait)); }
|
sim_rtc_init (clk_unit.wait)); }
|
||||||
else clk_reset (&clk_dev); } /* CLOF */
|
else clk_reset (&clk_dev); } /* CLOF */
|
||||||
return AC;
|
return dat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unit service */
|
/* Unit service */
|
||||||
|
@ -380,7 +382,7 @@ t_stat clk_svc (UNIT *uptr)
|
||||||
int32 t;
|
int32 t;
|
||||||
|
|
||||||
if (clk_state) { /* clock on? */
|
if (clk_state) { /* clock on? */
|
||||||
M[7] = (M[7] + 1) & 0777777; /* incr counter */
|
M[7] = (M[7] + 1) & DMASK; /* incr counter */
|
||||||
if (M[7] == 0) SET_INT (CLK); /* ovrflo? set flag */
|
if (M[7] == 0) SET_INT (CLK); /* ovrflo? set flag */
|
||||||
t = sim_rtc_calb (clk_tps); /* calibrate clock */
|
t = sim_rtc_calb (clk_tps); /* calibrate clock */
|
||||||
sim_activate (&clk_unit, t); /* reactivate unit */
|
sim_activate (&clk_unit, t); /* reactivate unit */
|
||||||
|
@ -426,19 +428,19 @@ return SCPE_OK;
|
||||||
|
|
||||||
/* Paper tape reader: IOT routine */
|
/* Paper tape reader: IOT routine */
|
||||||
|
|
||||||
int32 ptr (int32 pulse, int32 AC)
|
int32 ptr (int32 pulse, int32 dat)
|
||||||
{
|
{
|
||||||
if (pulse & 001) { /* RSF */
|
if (pulse & 001) { /* RSF */
|
||||||
if (TST_INT (PTR)) AC = AC | IOT_SKP; }
|
if (TST_INT (PTR)) dat = dat | IOT_SKP; }
|
||||||
if (pulse & 002) { /* RRB, RCF */
|
if (pulse & 002) { /* RRB, RCF */
|
||||||
CLR_INT (PTR); /* clear done */
|
CLR_INT (PTR); /* clear done */
|
||||||
AC = AC | ptr_unit.buf; } /* return buffer */
|
dat = dat | ptr_unit.buf; } /* return buffer */
|
||||||
if (pulse & 004) { /* RSA, RSB */
|
if (pulse & 004) { /* RSA, RSB */
|
||||||
ptr_state = (pulse & 040)? 18: 0; /* set mode */
|
ptr_state = (pulse & 040)? 18: 0; /* set mode */
|
||||||
CLR_INT (PTR); /* clear done */
|
CLR_INT (PTR); /* clear done */
|
||||||
ptr_unit.buf = 0; /* clear buffer */
|
ptr_unit.buf = 0; /* clear buffer */
|
||||||
sim_activate (&ptr_unit, ptr_unit.wait); }
|
sim_activate (&ptr_unit, ptr_unit.wait); }
|
||||||
return AC;
|
return dat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unit service */
|
/* Unit service */
|
||||||
|
@ -526,6 +528,39 @@ ptr_unit.flags = ptr_unit.flags & ~UNIT_RASCII;
|
||||||
return detach_unit (uptr);
|
return detach_unit (uptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Hardware RIM loader routines, PDP-7/9/15 */
|
||||||
|
|
||||||
|
int32 ptr_getw (FILE *fileref, int32 *hi)
|
||||||
|
{
|
||||||
|
int32 word, bits, st, ch;
|
||||||
|
|
||||||
|
word = st = bits = 0;
|
||||||
|
do { if ((ch = getc (fileref)) == EOF) return -1;
|
||||||
|
if (ch & 0200) {
|
||||||
|
word = (word << 6) | (ch & 077);
|
||||||
|
bits = (bits << 1) | ((ch >> 6) & 1);
|
||||||
|
st++; } }
|
||||||
|
while (st < 3);
|
||||||
|
if (hi != NULL) *hi = bits;
|
||||||
|
return word;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat ptr_rim_load (FILE *fileref, int32 origin)
|
||||||
|
{
|
||||||
|
int32 bits, val;
|
||||||
|
|
||||||
|
for (;;) { /* word loop */
|
||||||
|
if ((val = ptr_getw (fileref, &bits)) < 0) return SCPE_FMT;
|
||||||
|
if (bits & 1) { /* end of tape? */
|
||||||
|
if ((val & 0760000) == OP_JMP) {
|
||||||
|
PC = ((origin - 1) & 060000) | (val & 017777);
|
||||||
|
return SCPE_OK; }
|
||||||
|
else if (val == OP_HLT) return STOP_HALT;
|
||||||
|
break; }
|
||||||
|
else if (MEM_ADDR_OK (origin)) M[origin++] = val; }
|
||||||
|
return SCPE_FMT;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined (PDP4) || defined (PDP7)
|
#if defined (PDP4) || defined (PDP7)
|
||||||
|
|
||||||
/* Bootstrap routine, PDP-4 and PDP-7
|
/* Bootstrap routine, PDP-4 and PDP-7
|
||||||
|
@ -533,12 +568,11 @@ return detach_unit (uptr);
|
||||||
In a 4K system, the boostrap resides at 7762-7776.
|
In a 4K system, the boostrap resides at 7762-7776.
|
||||||
In an 8K or greater system, the bootstrap resides at 17762-17776.
|
In an 8K or greater system, the bootstrap resides at 17762-17776.
|
||||||
Because the program is so small, simple masking can be
|
Because the program is so small, simple masking can be
|
||||||
used to remove addr<5> for a 4K system.
|
used to remove addr<5> for a 4K system. */
|
||||||
*/
|
|
||||||
|
|
||||||
#define BOOT_START 017577
|
#define BOOT_START 017577
|
||||||
#define BOOT_FPC 017577
|
#define BOOT_FPC 017577 /* funny format loader */
|
||||||
#define BOOT_RPC 017770
|
#define BOOT_RPC 017770 /* RIM loader */
|
||||||
#define BOOT_LEN (sizeof (boot_rom) / sizeof (int))
|
#define BOOT_LEN (sizeof (boot_rom) / sizeof (int))
|
||||||
|
|
||||||
static const int32 boot_rom[] = {
|
static const int32 boot_rom[] = {
|
||||||
|
@ -677,6 +711,10 @@ t_stat ptr_boot (int32 unitno, DEVICE *dptr)
|
||||||
int32 i, mask, wd;
|
int32 i, mask, wd;
|
||||||
extern int32 sim_switches;
|
extern int32 sim_switches;
|
||||||
|
|
||||||
|
#if defined (PDP7)
|
||||||
|
if (sim_switches & SWMASK ('H')) /* hardware RIM load? */
|
||||||
|
return ptr_rim_load (ptr_unit.fileref, ASW);
|
||||||
|
#endif
|
||||||
if (ptr_dib.dev != DEV_PTR) return STOP_NONSTD; /* non-std addr? */
|
if (ptr_dib.dev != DEV_PTR) return STOP_NONSTD; /* non-std addr? */
|
||||||
if (MEMSIZE < 8192) mask = 0767777; /* 4k? */
|
if (MEMSIZE < 8192) mask = 0767777; /* 4k? */
|
||||||
else mask = 0777777;
|
else mask = 0777777;
|
||||||
|
@ -684,7 +722,7 @@ for (i = 0; i < BOOT_LEN; i++) {
|
||||||
wd = boot_rom[i];
|
wd = boot_rom[i];
|
||||||
if ((wd >= 0040000) && (wd < 0640000)) wd = wd & mask;
|
if ((wd >= 0040000) && (wd < 0640000)) wd = wd & mask;
|
||||||
M[(BOOT_START & mask) + i] = wd; }
|
M[(BOOT_START & mask) + i] = wd; }
|
||||||
saved_PC = ((sim_switches & SWMASK ('F'))? BOOT_FPC: BOOT_RPC) & mask;
|
PC = ((sim_switches & SWMASK ('F'))? BOOT_FPC: BOOT_RPC) & mask;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -694,24 +732,24 @@ return SCPE_OK;
|
||||||
|
|
||||||
t_stat ptr_boot (int32 unitno, DEVICE *dptr)
|
t_stat ptr_boot (int32 unitno, DEVICE *dptr)
|
||||||
{
|
{
|
||||||
return SCPE_ARG;
|
return ptr_rim_load (ptr_unit.fileref, ASW);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Paper tape punch: IOT routine */
|
/* Paper tape punch: IOT routine */
|
||||||
|
|
||||||
int32 ptp (int32 pulse, int32 AC)
|
int32 ptp (int32 pulse, int32 dat)
|
||||||
{
|
{
|
||||||
if (pulse & 001) { /* PSF */
|
if (pulse & 001) { /* PSF */
|
||||||
if (TST_INT (PTP)) AC = AC | IOT_SKP; }
|
if (TST_INT (PTP)) dat = dat | IOT_SKP; }
|
||||||
if (pulse & 002) CLR_INT (PTP); /* PCF */
|
if (pulse & 002) CLR_INT (PTP); /* PCF */
|
||||||
if (pulse & 004) { /* PSA, PSB, PLS */
|
if (pulse & 004) { /* PSA, PSB, PLS */
|
||||||
CLR_INT (PTP); /* clear flag */
|
CLR_INT (PTP); /* clear flag */
|
||||||
ptp_unit.buf = (pulse & 040)? /* load punch buf */
|
ptp_unit.buf = (pulse & 040)? /* load punch buf */
|
||||||
(AC & 077) | 0200: AC & 0377; /* bin or alpha */
|
(dat & 077) | 0200: dat & 0377; /* bin or alpha */
|
||||||
sim_activate (&ptp_unit, ptp_unit.wait); } /* activate unit */
|
sim_activate (&ptp_unit, ptp_unit.wait); } /* activate unit */
|
||||||
return AC;
|
return dat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unit service */
|
/* Unit service */
|
||||||
|
@ -782,16 +820,16 @@ return detach_unit (uptr);
|
||||||
|
|
||||||
/* Terminal input: IOT routine */
|
/* Terminal input: IOT routine */
|
||||||
|
|
||||||
int32 tti (int32 pulse, int32 AC)
|
int32 tti (int32 pulse, int32 dat)
|
||||||
{
|
{
|
||||||
if (pulse & 001) { /* KSF */
|
if (pulse & 001) { /* KSF */
|
||||||
if (TST_INT (TTI)) AC = AC | IOT_SKP; }
|
if (TST_INT (TTI)) dat = dat | IOT_SKP; }
|
||||||
if (pulse & 002) { /* KRB */
|
if (pulse & 002) { /* KRB */
|
||||||
CLR_INT (TTI); /* clear flag */
|
CLR_INT (TTI); /* clear flag */
|
||||||
AC = AC | tti_unit.buf & TTI_MASK; } /* return buffer */
|
dat = dat | tti_unit.buf & TTI_MASK; } /* return buffer */
|
||||||
if (pulse & 004) { /* IORS */
|
if (pulse & 004) { /* IORS */
|
||||||
AC = AC | upd_iors (); }
|
dat = dat | upd_iors (); }
|
||||||
return AC;
|
return dat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unit service */
|
/* Unit service */
|
||||||
|
@ -870,15 +908,15 @@ return SCPE_OK;
|
||||||
|
|
||||||
/* Terminal output: IOT routine */
|
/* Terminal output: IOT routine */
|
||||||
|
|
||||||
int32 tto (int32 pulse, int32 AC)
|
int32 tto (int32 pulse, int32 dat)
|
||||||
{
|
{
|
||||||
if (pulse & 001) { /* TSF */
|
if (pulse & 001) { /* TSF */
|
||||||
if (TST_INT (TTO)) AC = AC | IOT_SKP; }
|
if (TST_INT (TTO)) dat = dat | IOT_SKP; }
|
||||||
if (pulse & 002) CLR_INT (TTO); /* clear flag */
|
if (pulse & 002) CLR_INT (TTO); /* clear flag */
|
||||||
if (pulse & 004) { /* load buffer */
|
if (pulse & 004) { /* load buffer */
|
||||||
sim_activate (&tto_unit, tto_unit.wait); /* activate unit */
|
sim_activate (&tto_unit, tto_unit.wait); /* activate unit */
|
||||||
tto_unit.buf = AC & TTO_MASK; } /* load buffer */
|
tto_unit.buf = dat & TTO_MASK; } /* load buffer */
|
||||||
return AC;
|
return dat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unit service */
|
/* Unit service */
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
in this Software without prior written authorization from Robert M Supnik.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
30-Jul-03 RMS Fixed FPM class mask
|
||||||
|
18-Jul-03 RMS Added FP15 support
|
||||||
02-Mar-03 RMS Split loaders apart for greater flexibility
|
02-Mar-03 RMS Split loaders apart for greater flexibility
|
||||||
09-Feb-03 RMS Fixed bug in FMTASC (found by Hans Pufal)
|
09-Feb-03 RMS Fixed bug in FMTASC (found by Hans Pufal)
|
||||||
31-Jan-03 RMS Added support for RB09
|
31-Jan-03 RMS Added support for RB09
|
||||||
|
@ -47,6 +49,9 @@
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
extern DEVICE cpu_dev;
|
extern DEVICE cpu_dev;
|
||||||
|
#if defined (PDP15)
|
||||||
|
extern DEVICE fpp_dev;
|
||||||
|
#endif
|
||||||
extern DEVICE ptr_dev, ptp_dev;
|
extern DEVICE ptr_dev, ptp_dev;
|
||||||
extern DEVICE tti_dev, tto_dev;
|
extern DEVICE tti_dev, tto_dev;
|
||||||
extern UNIT tti_unit, tto_unit;
|
extern UNIT tti_unit, tto_unit;
|
||||||
|
@ -87,7 +92,7 @@ extern UNIT cpu_unit;
|
||||||
extern REG cpu_reg[];
|
extern REG cpu_reg[];
|
||||||
extern int32 M[];
|
extern int32 M[];
|
||||||
extern int32 memm;
|
extern int32 memm;
|
||||||
extern int32 saved_PC;
|
extern int32 PC;
|
||||||
|
|
||||||
/* SCP data structures and interface routines
|
/* SCP data structures and interface routines
|
||||||
|
|
||||||
|
@ -111,9 +116,13 @@ char sim_name[] = "PDP-15";
|
||||||
|
|
||||||
REG *sim_PC = &cpu_reg[0];
|
REG *sim_PC = &cpu_reg[0];
|
||||||
|
|
||||||
int32 sim_emax = 3;
|
int32 sim_emax = 2;
|
||||||
|
|
||||||
DEVICE *sim_devices[] = { &cpu_dev,
|
DEVICE *sim_devices[] = {
|
||||||
|
&cpu_dev,
|
||||||
|
#if defined (PDP15)
|
||||||
|
&fpp_dev,
|
||||||
|
#endif
|
||||||
&ptr_dev,
|
&ptr_dev,
|
||||||
&ptp_dev,
|
&ptp_dev,
|
||||||
&tti_dev,
|
&tti_dev,
|
||||||
|
@ -159,7 +168,8 @@ const char *sim_stop_messages[] = {
|
||||||
"Breakpoint",
|
"Breakpoint",
|
||||||
"Nested XCT's",
|
"Nested XCT's",
|
||||||
"Invalid API interrupt",
|
"Invalid API interrupt",
|
||||||
"Non-standard device number" };
|
"Non-standard device number",
|
||||||
|
"Memory management error" };
|
||||||
|
|
||||||
/* Binary loaders */
|
/* Binary loaders */
|
||||||
|
|
||||||
|
@ -202,7 +212,7 @@ for (;;) {
|
||||||
if ((val = getword (fileref, NULL)) < 0) return SCPE_FMT;
|
if ((val = getword (fileref, NULL)) < 0) return SCPE_FMT;
|
||||||
if (MEM_ADDR_OK (origin)) M[origin++] = val; }
|
if (MEM_ADDR_OK (origin)) M[origin++] = val; }
|
||||||
else if ((val & 0760000) == OP_JMP) { /* JMP? */
|
else if ((val & 0760000) == OP_JMP) { /* JMP? */
|
||||||
saved_PC = ((origin - 1) & 060000) | (val & 017777);
|
PC = ((origin - 1) & 060000) | (val & 017777);
|
||||||
return SCPE_OK; }
|
return SCPE_OK; }
|
||||||
else if (val == OP_HLT) return SCPE_OK; /* HLT? */
|
else if (val == OP_HLT) return SCPE_OK; /* HLT? */
|
||||||
else return SCPE_FMT; } /* error */
|
else return SCPE_FMT; } /* error */
|
||||||
|
@ -226,7 +236,7 @@ t_stat r;
|
||||||
|
|
||||||
if (*cptr != 0) { /* more input? */
|
if (*cptr != 0) { /* more input? */
|
||||||
cptr = get_glyph (cptr, gbuf, 0); /* get origin */
|
cptr = get_glyph (cptr, gbuf, 0); /* get origin */
|
||||||
origin = get_uint (gbuf, 8, ADDRMASK, &r);
|
origin = get_uint (gbuf, 8, AMASK, &r);
|
||||||
if (r != SCPE_OK) return r;
|
if (r != SCPE_OK) return r;
|
||||||
if (*cptr != 0) return SCPE_ARG; } /* no more */
|
if (*cptr != 0) return SCPE_ARG; } /* no more */
|
||||||
else origin = 0200; /* default 200 */
|
else origin = 0200; /* default 200 */
|
||||||
|
@ -234,7 +244,7 @@ else origin = 0200; /* default 200 */
|
||||||
for (;;) { /* word loop */
|
for (;;) { /* word loop */
|
||||||
if ((val = getword (fileref, &bits)) < 0) return SCPE_FMT;
|
if ((val = getword (fileref, &bits)) < 0) return SCPE_FMT;
|
||||||
if (bits & 1) { /* end of tape? */
|
if (bits & 1) { /* end of tape? */
|
||||||
if ((val & 0760000) == OP_JMP) saved_PC =
|
if ((val & 0760000) == OP_JMP) PC =
|
||||||
((origin - 1) & 060000) | (val & 017777);
|
((origin - 1) & 060000) | (val & 017777);
|
||||||
else if (val != OP_HLT) return SCPE_FMT;
|
else if (val != OP_HLT) return SCPE_FMT;
|
||||||
break; }
|
break; }
|
||||||
|
@ -258,16 +268,16 @@ return SCPE_OK;
|
||||||
|
|
||||||
t_stat bin_load_915 (FILE *fileref, char *cptr)
|
t_stat bin_load_915 (FILE *fileref, char *cptr)
|
||||||
{
|
{
|
||||||
int32 i, val, origin, count, cksum;
|
int32 i, val, bits, origin, count, cksum;
|
||||||
|
|
||||||
if (*cptr != 0) return SCPE_2MARG; /* no arguments */
|
if (*cptr != 0) return SCPE_2MARG; /* no arguments */
|
||||||
do { val = getc (fileref); } /* find end RIM */
|
do { val = getword (fileref, & bits); } /* find end RIM */
|
||||||
while (((val & 0100) == 0) && (val != EOF));
|
while ((val >= 0) && ((bits & 1) == 0));
|
||||||
if (val == EOF) rewind (fileref); /* no RIM? rewind */
|
if (val < 0) rewind (fileref); /* no RIM? rewind */
|
||||||
for (;;) { /* block loop */
|
for (;;) { /* block loop */
|
||||||
if ((val = getword (fileref, NULL)) < 0) return SCPE_FMT;
|
if ((val = getword (fileref, NULL)) < 0) return SCPE_FMT;
|
||||||
if (val & SIGN) {
|
if (val & SIGN) {
|
||||||
if (val != DMASK) saved_PC = val & 077777;
|
if (val != DMASK) PC = val & 077777;
|
||||||
break; }
|
break; }
|
||||||
cksum = origin = val; /* save origin */
|
cksum = origin = val; /* save origin */
|
||||||
if ((val = getword (fileref, NULL)) < 0) return SCPE_FMT;
|
if ((val = getword (fileref, NULL)) < 0) return SCPE_FMT;
|
||||||
|
@ -328,23 +338,30 @@ return bin_load_915 (fileref, cptr); /* must be BIN */
|
||||||
#define I_V_EST 8 /* EAE setup */
|
#define I_V_EST 8 /* EAE setup */
|
||||||
#define I_V_ESH 9 /* EAE shift */
|
#define I_V_ESH 9 /* EAE shift */
|
||||||
#define I_V_EMD 10 /* EAE mul-div */
|
#define I_V_EMD 10 /* EAE mul-div */
|
||||||
#define I_NPN (I_V_NPN << I_V_FL) /* no operand */
|
#define I_V_FPM 11 /* FP15 mem ref */
|
||||||
#define I_NPI (I_V_NPI << I_V_FL) /* no operand IOT */
|
#define I_V_FPI 12 /* FP15 indirect */
|
||||||
#define I_IOT (I_V_IOT << I_V_FL) /* IOT */
|
#define I_V_FPN 13 /* FP15 no operand */
|
||||||
#define I_MRF (I_V_MRF << I_V_FL) /* memory reference */
|
#define I_NPN (I_V_NPN << I_V_FL)
|
||||||
#define I_OPR (I_V_OPR << I_V_FL) /* OPR */
|
#define I_NPI (I_V_NPI << I_V_FL)
|
||||||
#define I_LAW (I_V_LAW << I_V_FL) /* LAW */
|
#define I_IOT (I_V_IOT << I_V_FL)
|
||||||
#define I_XR (I_V_XR << I_V_FL) /* index */
|
#define I_MRF (I_V_MRF << I_V_FL)
|
||||||
#define I_XR9 (I_V_XR9 << I_V_FL) /* index literal */
|
#define I_OPR (I_V_OPR << I_V_FL)
|
||||||
#define I_EST (I_V_EST << I_V_FL) /* EAE setup */
|
#define I_LAW (I_V_LAW << I_V_FL)
|
||||||
#define I_ESH (I_V_ESH << I_V_FL) /* EAE shift */
|
#define I_XR (I_V_XR << I_V_FL)
|
||||||
#define I_EMD (I_V_EMD << I_V_FL) /* EAE mul-div */
|
#define I_XR9 (I_V_XR9 << I_V_FL)
|
||||||
|
#define I_EST (I_V_EST << I_V_FL)
|
||||||
|
#define I_ESH (I_V_ESH << I_V_FL)
|
||||||
|
#define I_EMD (I_V_EMD << I_V_FL)
|
||||||
|
#define I_FPM (I_V_FPM << I_V_FL)
|
||||||
|
#define I_FPI (I_V_FPI << I_V_FL)
|
||||||
|
#define I_FPN (I_V_FPN << I_V_FL)
|
||||||
#define MD(x) ((I_EMD) + ((x) << I_V_DC))
|
#define MD(x) ((I_EMD) + ((x) << I_V_DC))
|
||||||
|
|
||||||
static const int32 masks[] = {
|
static const int32 masks[] = {
|
||||||
0777777, 0777767, 0740000, 0760000,
|
0777777, 0777767, 0770000, 0760000,
|
||||||
0763730, 0760000, 0777000, 0777000,
|
0763730, 0760000, 0777000, 0777000,
|
||||||
0740700, 0760700, 0777700 };
|
0740700, 0760700, 0777700, 0777777,
|
||||||
|
0777777, 0777777 };
|
||||||
|
|
||||||
static const char *opcode[] = {
|
static const char *opcode[] = {
|
||||||
"CAL", "DAC", "JMS", "DZM", /* mem refs */
|
"CAL", "DAC", "JMS", "DZM", /* mem refs */
|
||||||
|
@ -452,9 +469,75 @@ static const char *opcode[] = {
|
||||||
#if defined (PDP15)
|
#if defined (PDP15)
|
||||||
"SPCO", "SKP15", "RES",
|
"SPCO", "SKP15", "RES",
|
||||||
"SBA", "DBA", "EBA",
|
"SBA", "DBA", "EBA",
|
||||||
|
"ORMM", "RDMM", "LDMM", "MPLR",
|
||||||
|
"ENB", "INH", "MPRC", "IPFH",
|
||||||
"AAS", "PAX", "PAL", "AAC",
|
"AAS", "PAX", "PAL", "AAC",
|
||||||
"PXA", "AXS", "PXL", "PLA",
|
"PXA", "AXS", "PXL", "PLA",
|
||||||
"PLX", "CLAC","CLX", "CLLR", "AXR",
|
"PLX", "CLAC","CLX", "CLLR", "AXR",
|
||||||
|
|
||||||
|
"FPT", /* FP15 */
|
||||||
|
"ISB", "ESB", /* mem ref */
|
||||||
|
"FSB", "URFSB", "UNFSB", "UUFSB",
|
||||||
|
"DSB", "URDSB", "UNDSB", "UUDSB",
|
||||||
|
"IRS", "ERS",
|
||||||
|
"FRS", "URFRS", "UNFRS", "UUFRS",
|
||||||
|
"DRS", "URDRS", "UNDRS", "UUDRS",
|
||||||
|
"IMP", "EMP",
|
||||||
|
"FMP", "URFMP", "UNFMP", "UUFMP",
|
||||||
|
"DMP", "URDMP", "UNDMP", "UUDMP",
|
||||||
|
"IDV", "EDV",
|
||||||
|
"FDV", "URFDV", "UNFDV", "UUFDV",
|
||||||
|
"DDV", "URDDV", "UNDDV", "UUDDV",
|
||||||
|
"IRD", "ERD",
|
||||||
|
"FRD", "URFRD", "UNFRD", "UUFRD",
|
||||||
|
"DRD", "URDRD", "UNDRD", "UUDRD",
|
||||||
|
"ILD", "ELD",
|
||||||
|
"FLD", "UNFLD", "DLD", "UNDLD",
|
||||||
|
"IST", "EST",
|
||||||
|
"FST", "URFST", "UNFST", "UUFST",
|
||||||
|
"DST", "UNDST",
|
||||||
|
"ILF", "UNILF", "ELF", "UNELF",
|
||||||
|
"FLX", "URFLX", "DLX", "URDLX",
|
||||||
|
"ILQ", "ELQ",
|
||||||
|
"FLQ", "UNFLQ", "DLQ", "UNDLQ",
|
||||||
|
"LJE", "SJE",
|
||||||
|
"IAD", "EAD",
|
||||||
|
"FAD", "URFAD", "UNFAD", "UUFAD",
|
||||||
|
"DAD", "URDAD", "UNDAD", "UUDAD",
|
||||||
|
"BZA", "BMA", "BLE", "BPA",
|
||||||
|
"BRU", "BNA", "BAC",
|
||||||
|
"ISB*", "ESB*", /* indirect */
|
||||||
|
"FSB*", "URFSB*", "UNFSB*", "UUFSB*",
|
||||||
|
"DSB*", "URDSB*", "UNDSB*", "UUDSB*",
|
||||||
|
"IRS*", "ERS*",
|
||||||
|
"FRS*", "URFRS*", "UNFRS*", "UUFRS*",
|
||||||
|
"DRS*", "URDRS*", "UNDRS*", "UUDRS*",
|
||||||
|
"IMP*", "EMP*",
|
||||||
|
"FMP*", "URFMP*", "UNFMP*", "UUFMP*",
|
||||||
|
"DMP*", "URDMP*", "UNDMP*", "UUDMP*",
|
||||||
|
"IDV*", "EDV*",
|
||||||
|
"FDV*", "URFDV*", "UNFDV*", "UUFDV*",
|
||||||
|
"DDV*", "URDDV*", "UNDDV*", "UUDDV*",
|
||||||
|
"IRD*", "ERD",
|
||||||
|
"FRD*", "URFRD*", "UNFRD*", "UUFRD*",
|
||||||
|
"DRD*", "URDRD*", "UNDRD*", "UUDRD*",
|
||||||
|
"ILD*", "ELD",
|
||||||
|
"FLD*", "UNFLD*", "DLD*", "UNDLD*",
|
||||||
|
"IST*", "EST",
|
||||||
|
"FST*", "URFST*", "UNFST*", "UUFST*",
|
||||||
|
"DST*", "UNDST*",
|
||||||
|
"ILF*", "UNILF*", "ELF*", "UNELF*",
|
||||||
|
"FLX*", "URFLX*", "DLX*", "URDLX*",
|
||||||
|
"ILQ*", "ELQ*",
|
||||||
|
"FLQ*", "UNFLQ*", "DLQ*", "UNDLQ*",
|
||||||
|
"LJE*", "SJE*",
|
||||||
|
"IAD*", "EAD*",
|
||||||
|
"FAD*", "URFAD*", "UNFAD*", "UUFAD*",
|
||||||
|
"DAD*", "URDAD*", "UNDAD*", "UUDAD*",
|
||||||
|
|
||||||
|
"FLA", "UNFLA", "FXA", "URFXA", /* no operand */
|
||||||
|
"SWQ", "UNSWQ", "FZR",
|
||||||
|
"FAB", "FNG", "FCM", "FNM",
|
||||||
#endif
|
#endif
|
||||||
#if defined (PDP9) || defined (PDP15)
|
#if defined (PDP9) || defined (PDP15)
|
||||||
"MPSK", "MPSNE", "MPCV", "MPEU",
|
"MPSK", "MPSNE", "MPCV", "MPEU",
|
||||||
|
@ -617,9 +700,74 @@ static const int32 opc_val[] = {
|
||||||
#if defined (PDP15)
|
#if defined (PDP15)
|
||||||
0703341+I_NPI, 0707741+I_NPI, 0707742+I_NPI,
|
0703341+I_NPI, 0707741+I_NPI, 0707742+I_NPI,
|
||||||
0707761+I_NPI, 0707762+I_NPI, 0707764+I_NPI,
|
0707761+I_NPI, 0707762+I_NPI, 0707764+I_NPI,
|
||||||
|
0700022+I_NPI, 0700032+I_NPN, 0700024+I_NPI, 0701724+I_NPI,
|
||||||
|
0705521+I_NPI, 0705522+I_NPI, 0701722+I_NPI, 0701764+I_NPI,
|
||||||
0720000+I_XR9, 0721000+I_XR, 0722000+I_XR, 0723000+I_XR9,
|
0720000+I_XR9, 0721000+I_XR, 0722000+I_XR, 0723000+I_XR9,
|
||||||
0724000+I_XR, 0725000+I_XR9, 0726000+I_XR, 0730000+I_XR,
|
0724000+I_XR, 0725000+I_XR9, 0726000+I_XR, 0730000+I_XR,
|
||||||
0731000+I_XR, 0734000+I_XR, 0735000+I_XR, 0736000+I_XR, 0737000+I_XR9,
|
0731000+I_XR, 0734000+I_XR, 0735000+I_XR, 0736000+I_XR, 0737000+I_XR9,
|
||||||
|
|
||||||
|
0710314+I_FPN,
|
||||||
|
0710400+I_FPM, 0710500+I_FPM,
|
||||||
|
0710440+I_FPM, 0710450+I_FPM, 0710460+I_FPM, 0710470+I_FPM,
|
||||||
|
0710540+I_FPM, 0710550+I_FPM, 0710560+I_FPM, 0710570+I_FPM,
|
||||||
|
0711000+I_FPM, 0711100+I_FPM,
|
||||||
|
0711040+I_FPM, 0711050+I_FPM, 0711060+I_FPM, 0711070+I_FPM,
|
||||||
|
0711140+I_FPM, 0711150+I_FPM, 0711160+I_FPM, 0711170+I_FPM,
|
||||||
|
0711400+I_FPM, 0711500+I_FPM,
|
||||||
|
0711440+I_FPM, 0711450+I_FPM, 0711460+I_FPM, 0711470+I_FPM,
|
||||||
|
0711540+I_FPM, 0711550+I_FPM, 0711560+I_FPM, 0711570+I_FPM,
|
||||||
|
0712000+I_FPM, 0712100+I_FPM,
|
||||||
|
0712040+I_FPM, 0712050+I_FPM, 0712060+I_FPM, 0712070+I_FPM,
|
||||||
|
0712140+I_FPM, 0712150+I_FPM, 0712160+I_FPM, 0712170+I_FPM,
|
||||||
|
0712400+I_FPM, 0712500+I_FPM,
|
||||||
|
0712440+I_FPM, 0712450+I_FPM, 0712460+I_FPM, 0712470+I_FPM,
|
||||||
|
0712540+I_FPM, 0712550+I_FPM, 0712560+I_FPM, 0712570+I_FPM,
|
||||||
|
0713000+I_FPM, 0713100+I_FPM,
|
||||||
|
0713050+I_FPM, 0713070+I_FPM, 0713150+I_FPM, 0713170+I_FPM,
|
||||||
|
0713600+I_FPM, 0713700+I_FPM,
|
||||||
|
0713640+I_FPM, 0713650+I_FPM, 0713660+I_FPM, 0713670+I_FPM,
|
||||||
|
0713750+I_FPM, 0713770+I_FPM,
|
||||||
|
0714010+I_FPM, 0714030+I_FPM, 0714110+I_FPM, 0714130+I_FPM,
|
||||||
|
0714460+I_FPM, 0714470+I_FPM, 0714560+I_FPM, 0714570+I_FPM,
|
||||||
|
0715000+I_FPM, 0715100+I_FPM,
|
||||||
|
0715050+I_FPM, 0715070+I_FPM, 0715150+I_FPM, 0715170+I_FPM,
|
||||||
|
0715400+I_FPM, 0715600+I_FPM,
|
||||||
|
0716000+I_FPM, 0716100+I_FPM,
|
||||||
|
0716040+I_FPM, 0716050+I_FPM, 0716060+I_FPM, 0716070+I_FPM,
|
||||||
|
0716140+I_FPM, 0716150+I_FPM, 0716160+I_FPM, 0716170+I_FPM,
|
||||||
|
0716601+I_FPM, 0716602+I_FPM, 0716603+I_FPM,
|
||||||
|
0716604+I_FPM, 0716606+I_FPM, 0716610+I_FPM, 0716620+I_FPM,
|
||||||
|
0710400+I_FPI, 0710500+I_FPI, /* indirect */
|
||||||
|
0710440+I_FPI, 0710450+I_FPI, 0710460+I_FPI, 0710470+I_FPI,
|
||||||
|
0710540+I_FPI, 0710550+I_FPI, 0710560+I_FPI, 0710570+I_FPI,
|
||||||
|
0711000+I_FPI, 0711100+I_FPI,
|
||||||
|
0711040+I_FPI, 0711050+I_FPI, 0711060+I_FPI, 0711070+I_FPI,
|
||||||
|
0711140+I_FPI, 0711150+I_FPI, 0711160+I_FPI, 0711170+I_FPI,
|
||||||
|
0711400+I_FPI, 0711500+I_FPI,
|
||||||
|
0711440+I_FPI, 0711450+I_FPI, 0711460+I_FPI, 0711470+I_FPI,
|
||||||
|
0711540+I_FPI, 0711550+I_FPI, 0711560+I_FPI, 0711570+I_FPI,
|
||||||
|
0712000+I_FPI, 0712100+I_FPI,
|
||||||
|
0712040+I_FPI, 0712050+I_FPI, 0712060+I_FPI, 0712070+I_FPI,
|
||||||
|
0712140+I_FPI, 0712150+I_FPI, 0712160+I_FPI, 0712170+I_FPI,
|
||||||
|
0712400+I_FPI, 0712500+I_FPI,
|
||||||
|
0712440+I_FPI, 0712450+I_FPI, 0712460+I_FPI, 0712470+I_FPI,
|
||||||
|
0712540+I_FPI, 0712550+I_FPI, 0712560+I_FPI, 0712570+I_FPI,
|
||||||
|
0713000+I_FPI, 0713100+I_FPI,
|
||||||
|
0713050+I_FPI, 0713070+I_FPI, 0713150+I_FPI, 0713170+I_FPI,
|
||||||
|
0713600+I_FPI, 0713700+I_FPI,
|
||||||
|
0713640+I_FPI, 0713650+I_FPI, 0713660+I_FPI, 0713670+I_FPI,
|
||||||
|
0713750+I_FPI, 0713770+I_FPI,
|
||||||
|
0714010+I_FPI, 0714030+I_FPI, 0714110+I_FPI, 0714130+I_FPI,
|
||||||
|
0714460+I_FPI, 0714470+I_FPI, 0714560+I_FPI, 0714570+I_FPI,
|
||||||
|
0715000+I_FPI, 0715100+I_FPI,
|
||||||
|
0715050+I_FPI, 0715070+I_FPI, 0715150+I_FPI, 0715170+I_FPI,
|
||||||
|
0715400+I_FPI, 0715600+I_FPI,
|
||||||
|
0716000+I_FPI, 0716100+I_FPI,
|
||||||
|
0716040+I_FPI, 0716050+I_FPI, 0716060+I_FPI, 0716070+I_FPI,
|
||||||
|
0716140+I_FPI, 0716150+I_FPI, 0716160+I_FPI, 0716170+I_FPI,
|
||||||
|
0714210+I_FPN, 0714230+I_FPN, 0714660+I_FPN, 0714670+I_FPN,
|
||||||
|
0715250+I_FPN, 0715270+I_FPN, 0711200+I_FPN,
|
||||||
|
0713271+I_FPN, 0713272+I_FPN, 0713273+I_FPN, 0713250+I_FPN,
|
||||||
#endif
|
#endif
|
||||||
#if defined (PDP9) || defined (PDP15)
|
#if defined (PDP9) || defined (PDP15)
|
||||||
0701701+I_NPI, 0701741+I_NPI, 0701702+I_NPI, 0701742+I_NPI,
|
0701701+I_NPI, 0701741+I_NPI, 0701702+I_NPI, 0701742+I_NPI,
|
||||||
|
@ -741,7 +889,7 @@ if (!(sw & SWMASK ('M'))) return SCPE_ARG;
|
||||||
|
|
||||||
for (i = 0; opc_val[i] >= 0; i++) { /* loop thru ops */
|
for (i = 0; opc_val[i] >= 0; i++) { /* loop thru ops */
|
||||||
j = (opc_val[i] >> I_V_FL) & I_M_FL; /* get class */
|
j = (opc_val[i] >> I_V_FL) & I_M_FL; /* get class */
|
||||||
if ((opc_val[i] & 0777777) == (inst & masks[j])) { /* match? */
|
if ((opc_val[i] & DMASK) == (inst & masks[j])) { /* match? */
|
||||||
|
|
||||||
switch (j) { /* case on class */
|
switch (j) { /* case on class */
|
||||||
case I_V_NPN: /* no operands */
|
case I_V_NPN: /* no operands */
|
||||||
|
@ -758,17 +906,17 @@ for (i = 0; opc_val[i] >= 0; i++) { /* loop thru ops */
|
||||||
case I_V_MRF: /* mem ref */
|
case I_V_MRF: /* mem ref */
|
||||||
#if defined (PDP15)
|
#if defined (PDP15)
|
||||||
if (memm) {
|
if (memm) {
|
||||||
disp = inst & 017777;
|
disp = inst & B_DAMASK;
|
||||||
ma = (addr & 0760000) | disp; }
|
ma = (addr & (AMASK & ~B_DAMASK)) | disp; }
|
||||||
else {
|
else {
|
||||||
disp = inst & 007777;
|
disp = inst & P_DAMASK;
|
||||||
ma = (addr & 0770000) | disp; }
|
ma = (addr & (AMASK & ~P_DAMASK)) | disp; }
|
||||||
fprintf (of, "%s %-o", opcode[i], (cflag? ma & ADDRMASK: disp));
|
fprintf (of, "%s %-o", opcode[i], (cflag? ma & AMASK: disp));
|
||||||
if (!memm && (inst & 0010000)) fprintf (of, ",X");
|
if (!memm && (inst & I_IDX)) fprintf (of, ",X");
|
||||||
#else
|
#else
|
||||||
disp = inst & 017777;
|
disp = inst & B_DAMASK;
|
||||||
ma = (addr & 0760000) | disp;
|
ma = (addr & (AMASK & ~B_DAMASK)) | disp;
|
||||||
fprintf (of, "%s %-o", opcode[i], (cflag? ma & ADDRMASK: disp));
|
fprintf (of, "%s %-o", opcode[i], (cflag? ma & AMASK: disp));
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case I_V_OPR: /* operate */
|
case I_V_OPR: /* operate */
|
||||||
|
@ -796,7 +944,15 @@ for (i = 0; opc_val[i] >= 0; i++) { /* loop thru ops */
|
||||||
if (disp == k) fprintf (of, "%s", opcode[i]);
|
if (disp == k) fprintf (of, "%s", opcode[i]);
|
||||||
else if (disp < k) fprintf (of, "%s -%-o", opcode[i], k - disp);
|
else if (disp < k) fprintf (of, "%s -%-o", opcode[i], k - disp);
|
||||||
else fprintf (of, "%s +%-o", opcode[i], disp - k);
|
else fprintf (of, "%s +%-o", opcode[i], disp - k);
|
||||||
break; } /* end case */
|
break;
|
||||||
|
case I_V_FPM: case I_V_FPI: /* FP15 mem ref */
|
||||||
|
fprintf (of, "%s", opcode[i]);
|
||||||
|
if (val[1] & SIGN) fputc ('*', of);
|
||||||
|
fprintf (of, " %-o", val[1] & ~SIGN);
|
||||||
|
return -1;
|
||||||
|
case I_V_FPN: /* FP15 no operand */
|
||||||
|
fprintf (of, "%s", opcode[i]);
|
||||||
|
return -1; } /* end case */
|
||||||
return SCPE_OK; } /* end if */
|
return SCPE_OK; } /* end if */
|
||||||
} /* end for */
|
} /* end for */
|
||||||
return SCPE_ARG;
|
return SCPE_ARG;
|
||||||
|
@ -838,8 +994,8 @@ return get_uint (cptr, 8, 0777777, status);
|
||||||
|
|
||||||
t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw)
|
t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw)
|
||||||
{
|
{
|
||||||
int32 cflag, d, i, j, k, sign, dmask, epcmask;
|
int32 cflag, d, i, j, k, sign, damask, epcmask;
|
||||||
t_stat r;
|
t_stat r, sta = SCPE_OK;
|
||||||
char gbuf[CBUFSIZE];
|
char gbuf[CBUFSIZE];
|
||||||
|
|
||||||
cflag = (uptr == NULL) || (uptr == &cpu_unit);
|
cflag = (uptr == NULL) || (uptr == &cpu_unit);
|
||||||
|
@ -895,31 +1051,31 @@ case I_V_LAW: /* law */
|
||||||
break;
|
break;
|
||||||
case I_V_MRF: /* mem ref */
|
case I_V_MRF: /* mem ref */
|
||||||
#if defined (PDP15)
|
#if defined (PDP15)
|
||||||
if (memm) dmask = 017777;
|
if (memm) damask = B_DAMASK;
|
||||||
else dmask = 07777;
|
else damask = P_DAMASK;
|
||||||
cptr = get_glyph (cptr, gbuf, ','); /* get glyph */
|
cptr = get_glyph (cptr, gbuf, ','); /* get glyph */
|
||||||
#else
|
#else
|
||||||
dmask = 017777;
|
damask = B_DAMASK;
|
||||||
cptr = get_glyph (cptr, gbuf, 0); /* get next field */
|
cptr = get_glyph (cptr, gbuf, 0); /* get next field */
|
||||||
#endif
|
#endif
|
||||||
#if defined (PDP4) || defined (PDP7)
|
#if defined (PDP4) || defined (PDP7)
|
||||||
if (strcmp (gbuf, "I") == 0) { /* indirect? */
|
if (strcmp (gbuf, "I") == 0) { /* indirect? */
|
||||||
val[0] = val[0] | 020000;
|
val[0] = val[0] | I_IND;
|
||||||
cptr = get_glyph (cptr, gbuf, 0); }
|
cptr = get_glyph (cptr, gbuf, 0); }
|
||||||
#endif
|
#endif
|
||||||
epcmask = ADDRMASK & ~dmask; /* get ePC */
|
epcmask = AMASK & ~damask; /* get ePC */
|
||||||
d = get_uint (gbuf, 8, ADDRMASK, &r); /* get addr */
|
d = get_uint (gbuf, 8, AMASK, &r); /* get addr */
|
||||||
if (r != SCPE_OK) return SCPE_ARG;
|
if (r != SCPE_OK) return SCPE_ARG;
|
||||||
if (d <= dmask) val[0] = val[0] | d; /* fit in 12/13b? */
|
if (d <= damask) val[0] = val[0] | d; /* fit in 12/13b? */
|
||||||
else if (cflag && (((addr ^ d) & epcmask) == 0))
|
else if (cflag && (((addr ^ d) & epcmask) == 0))
|
||||||
val[0] = val[0] | (d & dmask); /* hi bits = ePC? */
|
val[0] = val[0] | (d & damask); /* hi bits = ePC? */
|
||||||
else return SCPE_ARG;
|
else return SCPE_ARG;
|
||||||
#if defined (PDP15)
|
#if defined (PDP15)
|
||||||
if (!memm) {
|
if (!memm) {
|
||||||
cptr = get_glyph (cptr, gbuf, 0);
|
cptr = get_glyph (cptr, gbuf, 0);
|
||||||
if (gbuf[0] != 0) {
|
if (gbuf[0] != 0) {
|
||||||
if (strcmp (gbuf, "X") != 0) return SCPE_ARG;
|
if (strcmp (gbuf, "X") != 0) return SCPE_ARG;
|
||||||
val[0] = val[0] | 010000; } }
|
val[0] = val[0] | I_IDX; } }
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case I_V_EMD: /* or'able */
|
case I_V_EMD: /* or'able */
|
||||||
|
@ -940,7 +1096,23 @@ case I_V_NPN: case I_V_NPI: case I_V_IOT: case I_V_OPR:
|
||||||
if (sign > 0) val[0] = val[0] + d;
|
if (sign > 0) val[0] = val[0] + d;
|
||||||
else if (sign < 0) val[0] = val[0] - d;
|
else if (sign < 0) val[0] = val[0] - d;
|
||||||
else val[0] = val[0] | d; } }
|
else val[0] = val[0] | d; } }
|
||||||
|
break;
|
||||||
|
case I_V_FPM: /* FP15 mem ref */
|
||||||
|
cptr = get_glyph (cptr, gbuf, 0); /* get next field */
|
||||||
|
val[1] = get_uint (gbuf, 8, AMASK, &r); /* get addr */
|
||||||
|
if (r != SCPE_OK) return SCPE_ARG;
|
||||||
|
sta = -1;
|
||||||
|
break;
|
||||||
|
case I_V_FPI: /* FP15 ind mem ref */
|
||||||
|
cptr = get_glyph (cptr, gbuf, 0); /* get next field */
|
||||||
|
val[1] = get_uint (gbuf, 8, AMASK, &r) | SIGN; /* get @addr */
|
||||||
|
if (r != SCPE_OK) return SCPE_ARG;
|
||||||
|
sta = -1;
|
||||||
|
break;
|
||||||
|
case I_V_FPN: /* FP15 no operand */
|
||||||
|
val[1] = 0;
|
||||||
|
sta = -1;
|
||||||
break; } /* end case */
|
break; } /* end case */
|
||||||
if (*cptr != 0) return SCPE_ARG; /* junk at end? */
|
if (*cptr != 0) return SCPE_ARG; /* junk at end? */
|
||||||
return SCPE_OK;
|
return sta;
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,8 +58,8 @@ TMLN tt1_ldsc = { 0 }; /* line descriptors */
|
||||||
TMXR tt_desc = { 1, 0, 0, &tt1_ldsc }; /* mux descriptor */
|
TMXR tt_desc = { 1, 0, 0, &tt1_ldsc }; /* mux descriptor */
|
||||||
|
|
||||||
DEVICE tti1_dev, tto1_dev;
|
DEVICE tti1_dev, tto1_dev;
|
||||||
int32 tti1 (int32 pulse, int32 AC);
|
int32 tti1 (int32 pulse, int32 dat);
|
||||||
int32 tto1 (int32 pulse, int32 AC);
|
int32 tto1 (int32 pulse, int32 dat);
|
||||||
t_stat tti1_svc (UNIT *uptr);
|
t_stat tti1_svc (UNIT *uptr);
|
||||||
t_stat tto1_svc (UNIT *uptr);
|
t_stat tto1_svc (UNIT *uptr);
|
||||||
t_stat tti1_reset (DEVICE *dptr);
|
t_stat tti1_reset (DEVICE *dptr);
|
||||||
|
@ -150,14 +150,14 @@ DEVICE tto1_dev = {
|
||||||
|
|
||||||
/* Terminal input: IOT routine */
|
/* Terminal input: IOT routine */
|
||||||
|
|
||||||
int32 tti1 (int32 pulse, int32 AC)
|
int32 tti1 (int32 pulse, int32 dat)
|
||||||
{
|
{
|
||||||
if (pulse & 001) { /* KSF1 */
|
if (pulse & 001) { /* KSF1 */
|
||||||
if (TST_INT (TTI1)) AC = AC | IOT_SKP; }
|
if (TST_INT (TTI1)) dat = dat | IOT_SKP; }
|
||||||
if (pulse & 002) { /* KRB1 */
|
if (pulse & 002) { /* KRB1 */
|
||||||
CLR_INT (TTI1); /* clear flag */
|
CLR_INT (TTI1); /* clear flag */
|
||||||
AC= AC | tti1_unit.buf; } /* return buffer */
|
dat= dat | tti1_unit.buf; } /* return buffer */
|
||||||
return AC;
|
return dat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unit service */
|
/* Unit service */
|
||||||
|
@ -204,15 +204,15 @@ return SCPE_OK;
|
||||||
|
|
||||||
/* Terminal output: IOT routine */
|
/* Terminal output: IOT routine */
|
||||||
|
|
||||||
int32 tto1 (int32 pulse, int32 AC)
|
int32 tto1 (int32 pulse, int32 dat)
|
||||||
{
|
{
|
||||||
if (pulse & 001) { /* TSF */
|
if (pulse & 001) { /* TSF */
|
||||||
if (TST_INT (TTO1)) AC = AC | IOT_SKP; }
|
if (TST_INT (TTO1)) dat = dat | IOT_SKP; }
|
||||||
if (pulse & 002) CLR_INT (TTO1); /* clear flag */
|
if (pulse & 002) CLR_INT (TTO1); /* clear flag */
|
||||||
if (pulse & 004) { /* load buffer */
|
if (pulse & 004) { /* load buffer */
|
||||||
sim_activate (&tto1_unit, tto1_unit.wait); /* activate unit */
|
sim_activate (&tto1_unit, tto1_unit.wait); /* activate unit */
|
||||||
tto1_unit.buf = AC & 0377; } /* load buffer */
|
tto1_unit.buf = dat & 0377; } /* load buffer */
|
||||||
return AC;
|
return dat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unit service */
|
/* Unit service */
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
df DF32 fixed head disk
|
df DF32 fixed head disk
|
||||||
|
|
||||||
|
26-Jul-03 RMS Fixed bug in set size routine
|
||||||
14-Mar-03 RMS Fixed variable platter interaction with save/restore
|
14-Mar-03 RMS Fixed variable platter interaction with save/restore
|
||||||
03-Mar-03 RMS Fixed autosizing
|
03-Mar-03 RMS Fixed autosizing
|
||||||
02-Feb-03 RMS Added variable platter and autosizing support
|
02-Feb-03 RMS Added variable platter and autosizing support
|
||||||
|
@ -142,10 +143,10 @@ REG df_reg[] = {
|
||||||
{ NULL } };
|
{ NULL } };
|
||||||
|
|
||||||
MTAB df_mod[] = {
|
MTAB df_mod[] = {
|
||||||
{ UNIT_PLAT, 0, NULL, "1P", &df_set_size },
|
{ UNIT_PLAT, (0 << UNIT_V_PLAT), NULL, "1P", &df_set_size },
|
||||||
{ UNIT_PLAT, 1, NULL, "2P", &df_set_size },
|
{ UNIT_PLAT, (1 << UNIT_V_PLAT), NULL, "2P", &df_set_size },
|
||||||
{ UNIT_PLAT, 2, NULL, "3P", &df_set_size },
|
{ UNIT_PLAT, (2 << UNIT_V_PLAT), NULL, "3P", &df_set_size },
|
||||||
{ UNIT_PLAT, 3, NULL, "4P", &df_set_size },
|
{ UNIT_PLAT, (3 << UNIT_V_PLAT), NULL, "4P", &df_set_size },
|
||||||
{ MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO",
|
{ MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO",
|
||||||
&set_dev, &show_dev, NULL },
|
&set_dev, &show_dev, NULL },
|
||||||
{ 0 } };
|
{ 0 } };
|
||||||
|
@ -338,9 +339,9 @@ return attach_unit (uptr, cptr);
|
||||||
|
|
||||||
t_stat df_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
|
t_stat df_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||||
{
|
{
|
||||||
if ((val < 0) || (val >= DF_NUMDK)) return SCPE_IERR;
|
if (val < 0) return SCPE_IERR;
|
||||||
if (uptr->flags & UNIT_ATT) return SCPE_ALATT;
|
if (uptr->flags & UNIT_ATT) return SCPE_ALATT;
|
||||||
uptr->capac = (val + 1) * DF_DKSIZE;
|
uptr->capac = UNIT_GETP (val) * DF_DKSIZE;
|
||||||
uptr->flags = uptr->flags & ~UNIT_AUTO;
|
uptr->flags = uptr->flags & ~UNIT_AUTO;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
rf RF08 fixed head disk
|
rf RF08 fixed head disk
|
||||||
|
|
||||||
|
26-Jul-03 RMS Fixed bug in set size routine
|
||||||
14-Mar-03 RMS Fixed variable platter interaction with save/restore
|
14-Mar-03 RMS Fixed variable platter interaction with save/restore
|
||||||
03-Mar-03 RMS Fixed autosizing
|
03-Mar-03 RMS Fixed autosizing
|
||||||
02-Feb-03 RMS Added variable platter and autosizing support
|
02-Feb-03 RMS Added variable platter and autosizing support
|
||||||
|
@ -154,10 +155,10 @@ REG rf_reg[] = {
|
||||||
{ NULL } };
|
{ NULL } };
|
||||||
|
|
||||||
MTAB rf_mod[] = {
|
MTAB rf_mod[] = {
|
||||||
{ UNIT_PLAT, 0, NULL, "1P", &rf_set_size },
|
{ UNIT_PLAT, (0 << UNIT_V_PLAT), NULL, "1P", &rf_set_size },
|
||||||
{ UNIT_PLAT, 1, NULL, "2P", &rf_set_size },
|
{ UNIT_PLAT, (1 << UNIT_V_PLAT), NULL, "2P", &rf_set_size },
|
||||||
{ UNIT_PLAT, 2, NULL, "3P", &rf_set_size },
|
{ UNIT_PLAT, (2 << UNIT_V_PLAT), NULL, "3P", &rf_set_size },
|
||||||
{ UNIT_PLAT, 3, NULL, "4P", &rf_set_size },
|
{ UNIT_PLAT, (3 << UNIT_V_PLAT), NULL, "4P", &rf_set_size },
|
||||||
{ UNIT_AUTO, UNIT_AUTO, "autosize", "AUTOSIZE", NULL },
|
{ UNIT_AUTO, UNIT_AUTO, "autosize", "AUTOSIZE", NULL },
|
||||||
{ MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO",
|
{ MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO",
|
||||||
&set_dev, &show_dev, NULL },
|
&set_dev, &show_dev, NULL },
|
||||||
|
@ -391,9 +392,9 @@ return attach_unit (uptr, cptr);
|
||||||
|
|
||||||
t_stat rf_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
|
t_stat rf_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||||
{
|
{
|
||||||
if ((val < 0) || (val >= RF_NUMDK)) return SCPE_IERR;
|
if (val < 0) return SCPE_IERR;
|
||||||
if (uptr->flags & UNIT_ATT) return SCPE_ALATT;
|
if (uptr->flags & UNIT_ATT) return SCPE_ALATT;
|
||||||
uptr->capac = (val + 1) * RF_DKSIZE;
|
uptr->capac = UNIT_GETP (val) * RF_DKSIZE;
|
||||||
uptr->flags = uptr->flags & ~UNIT_AUTO;
|
uptr->flags = uptr->flags & ~UNIT_AUTO;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,8 +170,9 @@ for channel W, entry [1] for channel Y, etc.
|
||||||
MODE[0:7] 12 channel mode (from EOM instruction)
|
MODE[0:7] 12 channel mode (from EOM instruction)
|
||||||
FLAG[0:7] 9 channel flags
|
FLAG[0:7] 9 channel flags
|
||||||
|
|
||||||
The user can display all the registers in a channel with the command SHOW
|
The user can display all the registers in a channel with the command:
|
||||||
CHAN <chan>.
|
|
||||||
|
SHOW CHAN channel-letter
|
||||||
|
|
||||||
2.3 Console Input (TTI)
|
2.3 Console Input (TTI)
|
||||||
|
|
||||||
|
@ -364,7 +365,7 @@ The lines (MUXL) implements these registers:
|
||||||
|
|
||||||
TIME[0:31] 24 transmit time, lines 0 to 31
|
TIME[0:31] 24 transmit time, lines 0 to 31
|
||||||
|
|
||||||
The additional terminals do not support save and restore. All open
|
The terminal multiplexor does not support save and restore. All open
|
||||||
connections are lost when the simulator shuts down or MUX is detached.
|
connections are lost when the simulator shuts down or MUX is detached.
|
||||||
|
|
||||||
2.10 Project Genie Drum (DRM)
|
2.10 Project Genie Drum (DRM)
|
||||||
|
@ -419,11 +420,8 @@ Error handling is as follows:
|
||||||
not attached 1 report error and stop
|
not attached 1 report error and stop
|
||||||
0 disk not ready
|
0 disk not ready
|
||||||
|
|
||||||
end of file x assume rest of disk is zero
|
The rapid access disk is buffered in memory; end of file and OS I/O errors
|
||||||
|
cannot occur. By default, the rapid access disk is assigned to channel E.
|
||||||
OS I/O error x report error and stop
|
|
||||||
|
|
||||||
By default, the rapid access disk is assigned to channel E.
|
|
||||||
|
|
||||||
2.12 Moving Head Disk (DSK)
|
2.12 Moving Head Disk (DSK)
|
||||||
|
|
||||||
|
@ -456,9 +454,12 @@ Error handling is as follows:
|
||||||
not attached 1 report error and stop
|
not attached 1 report error and stop
|
||||||
0 disk not ready
|
0 disk not ready
|
||||||
|
|
||||||
Rapid access disk data files are buffered in memory; therefore, end of file
|
end of file x assume rest of disk is zero
|
||||||
and OS I/O errors cannot occur. By default, the rapid access disk is
|
|
||||||
assigned to channel F.
|
OS I/O error x report error and stop
|
||||||
|
|
||||||
|
|
||||||
|
By default, the moving head disk is assigned to channel F.
|
||||||
|
|
||||||
2.13 Magnetic Tape (MT)
|
2.13 Magnetic Tape (MT)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
To: Users
|
To: Users
|
||||||
From: Bob Supnik
|
From: Bob Supnik
|
||||||
Subj: VAX Simulator Usage
|
Subj: VAX Simulator Usage
|
||||||
Date: 15-Jun-2003
|
Date: 15-Jul-2003
|
||||||
|
|
||||||
COPYRIGHT NOTICE
|
COPYRIGHT NOTICE
|
||||||
|
|
||||||
|
@ -37,17 +37,20 @@ This memorandum documents the VAX simulator.
|
||||||
1. Simulator Files
|
1. Simulator Files
|
||||||
|
|
||||||
To compile the VAX, you must define VM_VAX and USE_INT64 as part of the compilation
|
To compile the VAX, you must define VM_VAX and USE_INT64 as part of the compilation
|
||||||
command line.
|
command line. To enable extended file support (files greater than 2GB), you must
|
||||||
|
define USE_ADDR64 as part of the command line as well.
|
||||||
|
|
||||||
sim/ sim_defs.h
|
sim/ sim_defs.h
|
||||||
sim_ether.h
|
sim_ether.h
|
||||||
sim_rev.h
|
sim_rev.h
|
||||||
sim_sock.h
|
sim_sock.h
|
||||||
|
sim_tape.h
|
||||||
sim_tmxr.h
|
sim_tmxr.h
|
||||||
scp.c
|
scp.c
|
||||||
scp_tty.c
|
scp_tty.c
|
||||||
sim_ether.c
|
sim_ether.c
|
||||||
sim_sock.c
|
sim_sock.c
|
||||||
|
sim_tape.c
|
||||||
sim_tmxr.c
|
sim_tmxr.c
|
||||||
|
|
||||||
sim/vax/ vax_defs.h
|
sim/vax/ vax_defs.h
|
||||||
|
@ -59,6 +62,7 @@ sim/vax/ vax_defs.h
|
||||||
vax_mmu.c
|
vax_mmu.c
|
||||||
vax_stddev.c
|
vax_stddev.c
|
||||||
vax_sys.c
|
vax_sys.c
|
||||||
|
vax_sysdev.c
|
||||||
|
|
||||||
sim/pdp11/ pdp11_mscp.h
|
sim/pdp11/ pdp11_mscp.h
|
||||||
pdp11_uqssp.h
|
pdp11_uqssp.h
|
||||||
|
@ -90,7 +94,7 @@ PTR,PTP PCV11 paper tape reader/punch
|
||||||
TTI,TTO console terminal
|
TTI,TTO console terminal
|
||||||
LPT LPV11 line printer
|
LPT LPV11 line printer
|
||||||
CLK real-time clock
|
CLK real-time clock
|
||||||
DZ DZV11 8-line terminal multiplexor (up to 4)
|
DZ DZV11 4-line terminal multiplexor (up to 4)
|
||||||
RL RLV12/RL01(2) cartridge disk controller with four drives
|
RL RLV12/RL01(2) cartridge disk controller with four drives
|
||||||
RQ RQDX3 MSCP controller with four drives
|
RQ RQDX3 MSCP controller with four drives
|
||||||
RQB second RQDX3 MSCP controller with four drives
|
RQB second RQDX3 MSCP controller with four drives
|
||||||
|
@ -130,6 +134,9 @@ HALT instruction.
|
||||||
SET CPU 64M set memory size = 64MB
|
SET CPU 64M set memory size = 64MB
|
||||||
SET CPU SIMHALT kernel HALT returns to simulator
|
SET CPU SIMHALT kernel HALT returns to simulator
|
||||||
SET CPU CONHALT kernel HALT returns to boot ROM console
|
SET CPU CONHALT kernel HALT returns to boot ROM console
|
||||||
|
|
||||||
|
The CPU implements a show command to display the I/O address map:
|
||||||
|
|
||||||
SHOW CPU IOSPACE show I/O space address map
|
SHOW CPU IOSPACE show I/O space address map
|
||||||
|
|
||||||
If memory size is being reduced, and the memory being truncated contains
|
If memory size is being reduced, and the memory being truncated contains
|
||||||
|
@ -201,10 +208,10 @@ control registers for the interrupt system.
|
||||||
The CPU can maintain a history of the most recently executed instructions.
|
The CPU can maintain a history of the most recently executed instructions.
|
||||||
This is controlled by the SET CPU HISTORY and SHOW CPU HISTORY commands:
|
This is controlled by the SET CPU HISTORY and SHOW CPU HISTORY commands:
|
||||||
|
|
||||||
SET CPU HISTORY -- clear history buffer
|
SET CPU HISTORY clear history buffer
|
||||||
SET CPU HISTORY=0 -- disable history
|
SET CPU HISTORY=0 disable history
|
||||||
SET CPU HISTORY=n -- enable history, display length = n
|
SET CPU HISTORY=n enable history, display length = n
|
||||||
SHOW CPU HISTORY -- print CPU history
|
SHOW CPU HISTORY print CPU history
|
||||||
|
|
||||||
The maximum length for the history is 4096 entries.
|
The maximum length for the history is 4096 entries.
|
||||||
|
|
||||||
|
@ -225,15 +232,15 @@ The boot ROM consists of a single unit, representing the 128KB boot ROM.
|
||||||
It has no registers. The boot ROM is loaded with a binary byte stream
|
It has no registers. The boot ROM is loaded with a binary byte stream
|
||||||
using the LOAD -r command:
|
using the LOAD -r command:
|
||||||
|
|
||||||
LOAD -r KA655.BIN -- load boot ROM image KA655.BIN
|
LOAD -r KA655.BIN load boot ROM image KA655.BIN
|
||||||
|
|
||||||
ROM accesses a use a calibrated delay that slows ROM-based execution to
|
ROM accesses a use a calibrated delay that slows ROM-based execution to
|
||||||
about 500K instructions per second. This delay is required to make the
|
about 500K instructions per second. This delay is required to make the
|
||||||
power-up self-test routines run correctly on very fast hosts. The delay
|
power-up self-test routines run correctly on very fast hosts. The delay
|
||||||
is controlled with the commands:
|
is controlled with the commands:
|
||||||
|
|
||||||
SET ROM NODELAY -- ROM runs like RAM
|
SET ROM NODELAY ROM runs like RAM
|
||||||
SET ROM DELAY -- ROM runs slowly
|
SET ROM DELAY ROM runs slowly
|
||||||
|
|
||||||
2.1.4 Non-volatile Memory (NVR)
|
2.1.4 Non-volatile Memory (NVR)
|
||||||
|
|
||||||
|
@ -491,16 +498,16 @@ The clock (CLK) implements these registers:
|
||||||
The real-time clock autocalibrates; the clock interval is adjusted up or
|
The real-time clock autocalibrates; the clock interval is adjusted up or
|
||||||
down so that the clock tracks actual elapsed time.
|
down so that the clock tracks actual elapsed time.
|
||||||
|
|
||||||
2.3.7 DZ11 Terminal Multiplexor (DZ)
|
2.3.7 DZV11 Terminal Multiplexor (DZ)
|
||||||
|
|
||||||
The DZ11 is an 8-line terminal multiplexor. Up to 4 DZ11's (32 lines)
|
The DZV11 is an 4-line terminal multiplexor. Up to 4 DZ11's (16 lines)
|
||||||
are supported. The number of lines can be changed with the command
|
are supported. The number of lines can be changed with the command
|
||||||
|
|
||||||
SET DZ LINES=n set line count to n
|
SET DZ LINES=n set line count to n
|
||||||
|
|
||||||
The line count must be a multiple of 4, with a maximum of 16.
|
The line count must be a multiple of 4, with a maximum of 16.
|
||||||
|
|
||||||
The DZ11 supports 8-bit input and output of characters. 8-bit output
|
The DZV11 supports 8-bit input and output of characters. 8-bit output
|
||||||
may be incompatible with certain operating systems. The command
|
may be incompatible with certain operating systems. The command
|
||||||
|
|
||||||
SET DZ 7B
|
SET DZ 7B
|
||||||
|
@ -511,12 +518,15 @@ The terminal lines perform input and output through Telnet sessions
|
||||||
connected to a user-specified port. The ATTACH command specifies
|
connected to a user-specified port. The ATTACH command specifies
|
||||||
the port to be used:
|
the port to be used:
|
||||||
|
|
||||||
ATTACH {-am} DZ <port> set up listening port
|
ATTACH {-am} DZ <port> set up listening port
|
||||||
|
|
||||||
where port is a decimal number between 1 and 65535 that is not being used
|
where port is a decimal number between 1 and 65535 that is not being used
|
||||||
for other TCP/IP activities. The optional switch -m turns on the DZ11's
|
for other TCP/IP activities. The optional switch -m turns on the DZV11's
|
||||||
modem controls; the optional switch -a turns on active disconnects
|
modem controls; the optional switch -a turns on active disconnects
|
||||||
(disconnect session if computer clears Data Terminal Ready).
|
(disconnect session if computer clears Data Terminal Ready). Without
|
||||||
|
modem control, the DZ behaves as though terminals were directly connected;
|
||||||
|
disconnecting the Telnet session does not cause any operating system-
|
||||||
|
visible change in line status.
|
||||||
|
|
||||||
Once the DZ is attached and the simulator is running, the DZ will listen
|
Once the DZ is attached and the simulator is running, the DZ will listen
|
||||||
for connections on the specified port. It assumes that the incoming
|
for connections on the specified port. It assumes that the incoming
|
||||||
|
@ -528,7 +538,7 @@ The SHOW DZ CONNECTIONS command displays the current connections to the DZ.
|
||||||
The SHOW DZ STATISTICS command displays statistics for active connections.
|
The SHOW DZ STATISTICS command displays statistics for active connections.
|
||||||
The SET DZ DISCONNECT=linenumber disconnects the specified line.
|
The SET DZ DISCONNECT=linenumber disconnects the specified line.
|
||||||
|
|
||||||
The DZ11 implements these registers:
|
The DZV11 implements these registers:
|
||||||
|
|
||||||
name size comments
|
name size comments
|
||||||
|
|
||||||
|
@ -544,7 +554,7 @@ The DZ11 implements these registers:
|
||||||
MDMTCL 1 modem control enabled
|
MDMTCL 1 modem control enabled
|
||||||
AUTODS 1 autodisconnect enabled
|
AUTODS 1 autodisconnect enabled
|
||||||
|
|
||||||
The DZ11 does not support save and restore. All open connections are
|
The DZV11 does not support save and restore. All open connections are
|
||||||
lost when the simulator shuts down or the DZ is detached.
|
lost when the simulator shuts down or the DZ is detached.
|
||||||
|
|
||||||
2.4 RLV12/RL01,RL02 Cartridge Disk (RL)
|
2.4 RLV12/RL01,RL02 Cartridge Disk (RL)
|
||||||
|
@ -613,9 +623,14 @@ of many disk types:
|
||||||
SET RQn RA72 set type to RA72
|
SET RQn RA72 set type to RA72
|
||||||
SET RQn RA90 set type to RA90
|
SET RQn RA90 set type to RA90
|
||||||
SET RQn RA92 set type to RA92
|
SET RQn RA92 set type to RA92
|
||||||
SET RQn RA81 set type to RA81 with n LBN's.
|
SET RQn RAUSER{=n} set type to RA81 with n LBN's
|
||||||
|
|
||||||
The type options can be used only when a unit is not attached to a file.
|
The type options can be used only when a unit is not attached to a file.
|
||||||
|
RAUSER is a "user specified" disk; the user can specify the size of the
|
||||||
|
disk in logical block numbers (LBN's, 512 bytes each). The minimum size
|
||||||
|
is 50MB. The maximum size is 2GB if the simulator is compiled without
|
||||||
|
64b addressing, 1000GB with 64b addressing.
|
||||||
|
|
||||||
Units can also be set ONLINE or OFFLINE.
|
Units can also be set ONLINE or OFFLINE.
|
||||||
|
|
||||||
Each RQ controller implements the following special SHOW commands:
|
Each RQ controller implements the following special SHOW commands:
|
||||||
|
@ -662,13 +677,13 @@ Each RQ controller implements these registers:
|
||||||
|
|
||||||
Error handling is as follows:
|
Error handling is as follows:
|
||||||
|
|
||||||
error processed as
|
error processed as
|
||||||
|
|
||||||
not attached disk not ready
|
not attached disk not ready
|
||||||
|
|
||||||
end of file assume rest of disk is zero
|
end of file assume rest of disk is zero
|
||||||
|
|
||||||
OS I/O error report error and stop
|
OS I/O error report error and stop
|
||||||
|
|
||||||
2.6 TSV11/TSV05 Magnetic Tape (TS)
|
2.6 TSV11/TSV05 Magnetic Tape (TS)
|
||||||
|
|
||||||
|
@ -780,13 +795,13 @@ The TQ controller implements these registers:
|
||||||
|
|
||||||
Error handling is as follows:
|
Error handling is as follows:
|
||||||
|
|
||||||
error processed as
|
error processed as
|
||||||
|
|
||||||
not attached tape not ready
|
not attached tape not ready
|
||||||
|
|
||||||
end of file end of medium
|
end of file end of medium
|
||||||
|
|
||||||
OS I/O error report error and stop
|
OS I/O error report error and stop
|
||||||
|
|
||||||
2.8 DELQA/DEQNA Qbus Ethernet Controllers (XQ, XQB)
|
2.8 DELQA/DEQNA Qbus Ethernet Controllers (XQ, XQB)
|
||||||
|
|
||||||
|
@ -840,18 +855,18 @@ controller will behave as though the ethernet cable were unplugged.
|
||||||
|
|
||||||
XQ has the following registers:
|
XQ has the following registers:
|
||||||
|
|
||||||
name size comments
|
name size comments
|
||||||
|
|
||||||
SA0 16 station address word 0
|
SA0 16 station address word 0
|
||||||
SA1 16 station address word 1
|
SA1 16 station address word 1
|
||||||
SA2 16 station address word 2
|
SA2 16 station address word 2
|
||||||
SA3 16 station address word 3
|
SA3 16 station address word 3
|
||||||
SA4 16 station address word 4
|
SA4 16 station address word 4
|
||||||
SA5 16 station address word 5
|
SA5 16 station address word 5
|
||||||
CSR 16 control status register
|
CSR 16 control status register
|
||||||
VAR 16 vector address register
|
VAR 16 vector address register
|
||||||
RBDL 32 receive buffer descriptor list
|
RBDL 32 receive buffer descriptor list
|
||||||
XBDL 32 trans(X)mit buffer descriptorlList
|
XBDL 32 trans(X)mit buffer descriptorlList
|
||||||
|
|
||||||
One final note: because of it's asynchronous nature, the XQ controller is
|
One final note: because of it's asynchronous nature, the XQ controller is
|
||||||
not limited to the ~1.5Mbit/sec of the real DEQNA/DELQA controllers,
|
not limited to the ~1.5Mbit/sec of the real DEQNA/DELQA controllers,
|
||||||
|
|
10
descrip.mms
10
descrip.mms
|
@ -270,11 +270,13 @@ IBM1130_LIB = $(LIB_DIR)IBM1130-$(ARCH).OLB
|
||||||
IBM1130_SOURCE = $(IBM1130_DIR)IBM1130_CPU.C,$(IBM1130_DIR)IBM1130_CR.C,\
|
IBM1130_SOURCE = $(IBM1130_DIR)IBM1130_CPU.C,$(IBM1130_DIR)IBM1130_CR.C,\
|
||||||
$(IBM1130_DIR)IBM1130_DISK.C,$(IBM1130_DIR)IBM1130_STDDEV.C,\
|
$(IBM1130_DIR)IBM1130_DISK.C,$(IBM1130_DIR)IBM1130_STDDEV.C,\
|
||||||
$(IBM1130_DIR)IBM1130_SYS.C,$(IBM1130_DIR)IBM1130_GDU.C,\
|
$(IBM1130_DIR)IBM1130_SYS.C,$(IBM1130_DIR)IBM1130_GDU.C,\
|
||||||
$(IBM1130_DIR)IBM1130_GUI.C,$(IBM1130_DIR)IBM1130_PRT.C
|
$(IBM1130_DIR)IBM1130_GUI.C,$(IBM1130_DIR)IBM1130_PRT.C,\
|
||||||
|
$(IBM1130_DIR)IBM1130_FMT.C
|
||||||
IBM1130_OBJS = $(IBM1130_DIR)IBM1130_CPU.OBJ,$(IBM1130_DIR)IBM1130_CR.OBJ,\
|
IBM1130_OBJS = $(IBM1130_DIR)IBM1130_CPU.OBJ,$(IBM1130_DIR)IBM1130_CR.OBJ,\
|
||||||
$(IBM1130_DIR)IBM1130_DISK.OBJ,$(IBM1130_DIR)IBM1130_STDDEV.OBJ,\
|
$(IBM1130_DIR)IBM1130_DISK.OBJ,$(IBM1130_DIR)IBM1130_STDDEV.OBJ,\
|
||||||
$(IBM1130_DIR)IBM1130_SYS.OBJ,$(IBM1130_DIR)IBM1130_GDU.OBJ,\
|
$(IBM1130_DIR)IBM1130_SYS.OBJ,$(IBM1130_DIR)IBM1130_GDU.OBJ,\
|
||||||
$(IBM1130_DIR)IBM1130_GUI.OBJ,$(IBM1130_DIR)IBM1130_PRT.OBJ
|
$(IBM1130_DIR)IBM1130_GUI.OBJ,$(IBM1130_DIR)IBM1130_PRT.OBJ,\
|
||||||
|
$(IBM1130_DIR)IBM1130_FMT.OBJ
|
||||||
IBM1130_OPTIONS = /INCLUDE=($(SIMH_DIR),$(IBM1130_DIR))
|
IBM1130_OPTIONS = /INCLUDE=($(SIMH_DIR),$(IBM1130_DIR))
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -355,13 +357,13 @@ PDP18B_SOURCE = $(PDP18B_DIR)PDP18B_DT.C,$(PDP18B_DIR)PDP18B_DRM.C,\
|
||||||
$(PDP18B_DIR)PDP18B_MT.C,$(PDP18B_DIR)PDP18B_RF.C,\
|
$(PDP18B_DIR)PDP18B_MT.C,$(PDP18B_DIR)PDP18B_RF.C,\
|
||||||
$(PDP18B_DIR)PDP18B_RP.C,$(PDP18B_DIR)PDP18B_STDDEV.C,\
|
$(PDP18B_DIR)PDP18B_RP.C,$(PDP18B_DIR)PDP18B_STDDEV.C,\
|
||||||
$(PDP18B_DIR)PDP18B_SYS.C,$(PDP18B_DIR)PDP18B_TT1.C,\
|
$(PDP18B_DIR)PDP18B_SYS.C,$(PDP18B_DIR)PDP18B_TT1.C,\
|
||||||
$(PDP18B_DIR)PDP18B_RB.C
|
$(PDP18B_DIR)PDP18B_RB.C,$(PDP18B_DIR)PDP18B_FPP.C
|
||||||
PDP18B_OBJS = $(PDP18B_DIR)PDP18B_DT.OBJ,$(PDP18B_DIR)PDP18B_DRM.OBJ,\
|
PDP18B_OBJS = $(PDP18B_DIR)PDP18B_DT.OBJ,$(PDP18B_DIR)PDP18B_DRM.OBJ,\
|
||||||
$(PDP18B_DIR)PDP18B_CPU.OBJ,$(PDP18B_DIR)PDP18B_LP.OBJ,\
|
$(PDP18B_DIR)PDP18B_CPU.OBJ,$(PDP18B_DIR)PDP18B_LP.OBJ,\
|
||||||
$(PDP18B_DIR)PDP18B_MT.OBJ,$(PDP18B_DIR)PDP18B_RF.OBJ,\
|
$(PDP18B_DIR)PDP18B_MT.OBJ,$(PDP18B_DIR)PDP18B_RF.OBJ,\
|
||||||
$(PDP18B_DIR)PDP18B_RP.OBJ,$(PDP18B_DIR)PDP18B_STDDEV.OBJ,\
|
$(PDP18B_DIR)PDP18B_RP.OBJ,$(PDP18B_DIR)PDP18B_STDDEV.OBJ,\
|
||||||
$(PDP18B_DIR)PDP18B_SYS.OBJ,$(PDP18B_DIR)PDP18B_TT1.OBJ,\
|
$(PDP18B_DIR)PDP18B_SYS.OBJ,$(PDP18B_DIR)PDP18B_TT1.OBJ,\
|
||||||
$(PDP18B_DIR)PDP18B_RB.OBJ
|
$(PDP18B_DIR)PDP18B_RB.OBJ,$(PDP18B_DIR)PDP18B_FPP.OBJ
|
||||||
PDP4_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP18B_DIR))/DEFINE=("PDP4=1")
|
PDP4_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP18B_DIR))/DEFINE=("PDP4=1")
|
||||||
PDP7_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP18B_DIR))/DEFINE=("PDP7=1")
|
PDP7_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP18B_DIR))/DEFINE=("PDP7=1")
|
||||||
PDP9_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP18B_DIR))/DEFINE=("PDP9=1")
|
PDP9_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP18B_DIR))/DEFINE=("PDP9=1")
|
||||||
|
|
5
makefile
5
makefile
|
@ -61,7 +61,7 @@ PDP18BD = PDP18B/
|
||||||
PDP18B = ${PDP18BD}pdp18b_dt.c ${PDP18BD}pdp18b_drm.c ${PDP18BD}pdp18b_cpu.c \
|
PDP18B = ${PDP18BD}pdp18b_dt.c ${PDP18BD}pdp18b_drm.c ${PDP18BD}pdp18b_cpu.c \
|
||||||
${PDP18BD}pdp18b_lp.c ${PDP18BD}pdp18b_mt.c ${PDP18BD}pdp18b_rf.c \
|
${PDP18BD}pdp18b_lp.c ${PDP18BD}pdp18b_mt.c ${PDP18BD}pdp18b_rf.c \
|
||||||
${PDP18BD}pdp18b_rp.c ${PDP18BD}pdp18b_stddev.c ${PDP18BD}pdp18b_sys.c \
|
${PDP18BD}pdp18b_rp.c ${PDP18BD}pdp18b_stddev.c ${PDP18BD}pdp18b_sys.c \
|
||||||
${PDP18BD}pdp18b_rb.c ${PDP18BD}pdp18b_tt1.c
|
${PDP18BD}pdp18b_rb.c ${PDP18BD}pdp18b_tt1.c ${PDP18BD}pdp18b_fpp.c
|
||||||
PDP4_OPT = -DPDP4 -I ${PDP18BD}
|
PDP4_OPT = -DPDP4 -I ${PDP18BD}
|
||||||
PDP7_OPT = -DPDP7 -I ${PDP18BD}
|
PDP7_OPT = -DPDP7 -I ${PDP18BD}
|
||||||
PDP9_OPT = -DPDP9 -I ${PDP18BD}
|
PDP9_OPT = -DPDP9 -I ${PDP18BD}
|
||||||
|
@ -150,7 +150,8 @@ IBM1130D = Ibm1130/
|
||||||
IBM1130 = ${IBM1130D}ibm1130_cpu.c ${IBM1130D}ibm1130_cr.c \
|
IBM1130 = ${IBM1130D}ibm1130_cpu.c ${IBM1130D}ibm1130_cr.c \
|
||||||
${IBM1130D}ibm1130_disk.c ${IBM1130D}ibm1130_stddev.c \
|
${IBM1130D}ibm1130_disk.c ${IBM1130D}ibm1130_stddev.c \
|
||||||
${IBM1130D}ibm1130_sys.c ${IBM1130D}ibm1130_gdu.c \
|
${IBM1130D}ibm1130_sys.c ${IBM1130D}ibm1130_gdu.c \
|
||||||
${IBM1130D}ibm1130_gui.c ${IBM1130D}ibm1130_prt.c
|
${IBM1130D}ibm1130_gui.c ${IBM1130D}ibm1130_prt.c \
|
||||||
|
${IBM1130D}ibm1130_fmt.c
|
||||||
IBM1130_OPT = -I ${IBM1130D}
|
IBM1130_OPT = -I ${IBM1130D}
|
||||||
|
|
||||||
|
|
||||||
|
|
4
scp.c
4
scp.c
|
@ -23,6 +23,7 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
in this Software without prior written authorization from Robert M Supnik.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
15-Jul-03 RMS Removed unnecessary test in reset_all
|
||||||
15-Jun-03 RMS Added register flag REG_VMIO
|
15-Jun-03 RMS Added register flag REG_VMIO
|
||||||
25-Apr-03 RMS Added extended address support (V3.0)
|
25-Apr-03 RMS Added extended address support (V3.0)
|
||||||
Fixed bug in SAVE (found by Peter Schorn)
|
Fixed bug in SAVE (found by Peter Schorn)
|
||||||
|
@ -1324,7 +1325,6 @@ DEVICE *dptr;
|
||||||
uint32 i;
|
uint32 i;
|
||||||
t_stat reason;
|
t_stat reason;
|
||||||
|
|
||||||
if (start < 0) return SCPE_IERR;
|
|
||||||
for (i = 0; i < start; i++) {
|
for (i = 0; i < start; i++) {
|
||||||
if (sim_devices[i] == NULL) return SCPE_IERR; }
|
if (sim_devices[i] == NULL) return SCPE_IERR; }
|
||||||
for (i = start; (dptr = sim_devices[i]) != NULL; i++) {
|
for (i = start; (dptr = sim_devices[i]) != NULL; i++) {
|
||||||
|
@ -3729,7 +3729,7 @@ for (i = 0; i < sec; i++) { /* loop */
|
||||||
c = sim_os_poll_kbd (); /* check for stop char */
|
c = sim_os_poll_kbd (); /* check for stop char */
|
||||||
if ((c == SCPE_STOP) || stop_cpu) return SCPE_STOP;
|
if ((c == SCPE_STOP) || stop_cpu) return SCPE_STOP;
|
||||||
if ((i % 10) == 0) { /* Status every 10 sec */
|
if ((i % 10) == 0) { /* Status every 10 sec */
|
||||||
printf ("Waiting for console Telnet connnection\n");
|
printf ("Waiting for console Telnet connection\n");
|
||||||
fflush (stdout); }
|
fflush (stdout); }
|
||||||
sim_os_sleep (1); /* wait 1 second */
|
sim_os_sleep (1); /* wait 1 second */
|
||||||
}
|
}
|
||||||
|
|
|
@ -185,9 +185,9 @@ int32 i;
|
||||||
|
|
||||||
sys$gettim (tod); /* time 0.1usec */
|
sys$gettim (tod); /* time 0.1usec */
|
||||||
|
|
||||||
/* To convert to msec, must divide 64b quantity by 10000. This is actually done
|
/* To convert to msec, must divide a 64b quantity by 10000. This is actually done
|
||||||
by dividing the 96b quantity 0'time by 10000, producing 64b of quotient, the
|
by dividing the 96b quantity 0'time by 10000, producing 64b of quotient, the
|
||||||
high 32b of which are discared. This can probably be done by a clever multiply...
|
high 32b of which are discarded. This can probably be done by a clever multiply...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
quo = htod = 0;
|
quo = htod = 0;
|
||||||
|
|
54
sim_rev.h
54
sim_rev.h
|
@ -29,12 +29,64 @@
|
||||||
|
|
||||||
#define SIM_MAJOR 3
|
#define SIM_MAJOR 3
|
||||||
#define SIM_MINOR 0
|
#define SIM_MINOR 0
|
||||||
#define SIM_PATCH 0
|
#define SIM_PATCH 1
|
||||||
|
|
||||||
/* V3.0 revision history
|
/* V3.0 revision history
|
||||||
|
|
||||||
patch date module(s) and fix(es)
|
patch date module(s) and fix(es)
|
||||||
|
|
||||||
|
1 27-Jul-03 pdp1_cpu.c: updated to detect indefinite I/O wait
|
||||||
|
|
||||||
|
pdp1_drm.c: fixed incorrect logical, missing activate, break
|
||||||
|
|
||||||
|
pdp1_lp.c:
|
||||||
|
-- fixed bugs in instruction decoding, overprinting
|
||||||
|
-- updated to detect indefinite I/O wait
|
||||||
|
|
||||||
|
pdp1_stddev.c:
|
||||||
|
-- changed RIM loader to be "hardware"
|
||||||
|
-- updated to detect indefinite I/O wait
|
||||||
|
|
||||||
|
pdp1_sys.c: added block loader format support to LOAD
|
||||||
|
|
||||||
|
pdp10_rp.c: fixed bug in read header
|
||||||
|
|
||||||
|
pdp11_rq: fixed bug in user disk size (found by Chaskiel M Grundman)
|
||||||
|
|
||||||
|
pdp18b_cpu.c:
|
||||||
|
-- added FP15 support
|
||||||
|
-- added XVM support
|
||||||
|
-- added EAE support to the PDP-4
|
||||||
|
-- added PDP-15 "re-entrancy ECO"
|
||||||
|
-- fixed memory protect/skip interaction
|
||||||
|
-- fixed CAF to only reset peripherals
|
||||||
|
|
||||||
|
pdp18b_fpp.c: added FP15
|
||||||
|
|
||||||
|
pdp18b_lp.c: fixed bug in Type 62 overprinting
|
||||||
|
|
||||||
|
pdp18b_rf.c: fixed bug in set size routine
|
||||||
|
|
||||||
|
pdp18b_stddev.c:
|
||||||
|
-- increased PTP TIME for PDP-15 operating systems
|
||||||
|
-- added hardware RIM loader for PDP-7, PDP-9, PDP-15
|
||||||
|
|
||||||
|
pdp18b_sys.c: added FP15, KT15, XVM instructions
|
||||||
|
|
||||||
|
pdp8b_df.c, pdp8_rf.c: fixed bug in set size routine
|
||||||
|
|
||||||
|
hp2100_dr.c:
|
||||||
|
-- fixed drum sizes
|
||||||
|
-- fixed variable capacity interaction with SAVE/RESTORE
|
||||||
|
|
||||||
|
i1401_cpu.c: revised fetch to model hardware more closely
|
||||||
|
|
||||||
|
ibm1130: fixed bugs found by APL 1130
|
||||||
|
|
||||||
|
nova_dsk.c: fixed bug in set size routine
|
||||||
|
|
||||||
|
altairz80: fixed bug in real-time clock on Windows host
|
||||||
|
|
||||||
0 15-Jun-03 scp.c:
|
0 15-Jun-03 scp.c:
|
||||||
-- added ASSIGN/DEASSIGN
|
-- added ASSIGN/DEASSIGN
|
||||||
-- changed RESTORE to detach files
|
-- changed RESTORE to detach files
|
||||||
|
|
|
@ -528,7 +528,7 @@ if (map) map[objc] = tpos;
|
||||||
return objc;
|
return objc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find the preceding record length in a TPC file */
|
/* Find the preceding record in a TPC file */
|
||||||
|
|
||||||
t_addr sim_tape_tpc_fnd (UNIT *uptr, t_addr *map)
|
t_addr sim_tape_tpc_fnd (UNIT *uptr, t_addr *map)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
To: Users
|
To: Users
|
||||||
From: Bob Supnik
|
From: Bob Supnik
|
||||||
Subj: Simulator Usage, V3.0
|
Subj: Simulator Usage, V3.1
|
||||||
Date: 15-May-2004
|
Date: 15-Jul-2003
|
||||||
|
|
||||||
COPYRIGHT NOTICE
|
COPYRIGHT NOTICE
|
||||||
|
|
||||||
|
@ -155,8 +155,7 @@ Examples:
|
||||||
|
|
||||||
The Windows-specific Ethernet code uses the WinPCAP 3.0 package.
|
The Windows-specific Ethernet code uses the WinPCAP 3.0 package.
|
||||||
This package for windows simulates the libpcap package that is freely
|
This package for windows simulates the libpcap package that is freely
|
||||||
available for Unix systems. Note that WinPCAP DOES NOT SUPPORT dual
|
available for Unix systems.
|
||||||
CPU environments.
|
|
||||||
|
|
||||||
WinPCAP must be installed prior to building the PDP-11 and VAX
|
WinPCAP must be installed prior to building the PDP-11 and VAX
|
||||||
simulators with Ethernet support.
|
simulators with Ethernet support.
|
||||||
|
|
16
simh_faq.txt
16
simh_faq.txt
|
@ -199,25 +199,13 @@ the source kit.
|
||||||
|
|
||||||
2.2 How do I install SIMH with Ethernet support on Windows?
|
2.2 How do I install SIMH with Ethernet support on Windows?
|
||||||
|
|
||||||
First, you must download download and install the WinPCAP AutoInstaller and
|
The pre-compiled binaries contain Ethernet support. Before running these
|
||||||
developer's kit from
|
binaries, you must download download and install the WinPCAP AutoInstaller from
|
||||||
|
|
||||||
http://winpcap.polito.it
|
http://winpcap.polito.it
|
||||||
|
|
||||||
This creates a network packet driver in Windows for SIMH to attach to.
|
This creates a network packet driver in Windows for SIMH to attach to.
|
||||||
|
|
||||||
Second, you must download the Gnu C compiler. You can get a Windows compatible
|
|
||||||
GNU C compiler from:
|
|
||||||
|
|
||||||
http://www.mingw.org
|
|
||||||
|
|
||||||
Third, place the include (.h) files from the developer's kit in the C
|
|
||||||
compiler's include folder, and the libraries from the developer's kit in C
|
|
||||||
compiler's library folder.
|
|
||||||
|
|
||||||
Then, the batch file build_mingw_ether.bat can be used to build all the
|
|
||||||
simulators, with Ethernet suport where appropriate.
|
|
||||||
|
|
||||||
To use network support, you must either be an administrator on the Windows
|
To use network support, you must either be an administrator on the Windows
|
||||||
machine (implied in Windows 9X), or you must set the windows packet driver to
|
machine (implied in Windows 9X), or you must set the windows packet driver to
|
||||||
autostart when the system boots; see the WinPCAP FAQ page for detailed
|
autostart when the system boots; see the WinPCAP FAQ page for detailed
|
||||||
|
|
Loading…
Add table
Reference in a new issue