Added the DAKAG PDP-10 diagnostics, implemented PUSHJ and POPJ instructions, and improved the debugging of XCT sequences

This commit is contained in:
Jeff 2017-03-29 13:26:23 -07:00 • committed by Jeff Parsons
commit c045e78395
9 changed files with 6252 additions and 252 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,278 @@
---
layout: page
title: PDP-10 KA10 Basic Instruction Diagnostic #7
permalink: /apps/pdp10/diags/klad/dakag/
machines:
- id: testka10
type: pdp10
config: /devices/pdp10/machine/ka10/test/debugger/machine.xml
debugger: true
commands: a 30724 DAKAG.MAC
---
PDP-10 KA10 Basic Instruction Diagnostic #7
-------------------------------------------
The *PDP-10 KA10 Basic Instruction Diagnostic #7* (MAINDEC-10-DAKAG) test code has been extracted from
[DAKAGM.MAC](DAKAGM.MAC.txt) [[original](http://pdp-10.trailing-edge.com/klad_sources/01/klad.sources/dakagm.mac.html)]
for use with the [PDP-10 Test Machine with Debugger](/devices/pdp10/machine/ka10/test/debugger/) below.
Resources for this test include:
- [Instructions](#dakagtxt)
- [History](#dakaghst)
- [Source Code](#dakagmac)
- [MACRO-10 Listing](DAKAG.LST.txt)
- [Additional Information](http://archive.pcjs.org/apps/pdp10/diags/klad/dakag/DAKAG.SEQ.txt)
{% include machine.html id="testka10" %}
The Debugger's assemble ("a") command can be used to test the new built-in
[MACRO-10 Mini-Assembler](/modules/pdp10/lib/macro10.js), which supports a subset
of the [MACRO-10](http://archive.pcjs.org/pubs/dec/pdp10/tops10/02_1973AsmRef_macro.pdf) assembly language.
This command:
a 30724 DAKAG.MAC
will automatically read the [DAKAG.MAC](DAKAG.MAC.txt) source file (a slightly modified copy of [DAKAGM.MAC](DAKAGM.MAC.txt)),
assemble it, and then load the binary output at the specified address.
---
DAKAG.TXT
---------
```
MAINDEC-10-DAKAG.TXT
IDENTIFICATION
--------------
PRODUCT CODE: MAINDEC-10-DAKAG-B-D
PRODUCT NAME: DECSYSTEM10 PDP-10 KA10 BASIC
INSTRUCTION DIAGNOSTIC (7)
FUNCTION: PUSH, POP, XCT, BASIC SHIFT/ROTATE
VERSION: 0.2
DATE RELEASED: JANUARY 1977
MAINTAINED BY: DIAGNOSTIC ENGINEERING GROUP
AUTHOR: JOHN R. KIRCHOFF
COPYRIGHT(C) 1976,1977
DIGITAL EQUIPMENT CORPORATION
MARLBORO, MASS. 01752
THIS SOFTWARE IS FURNISHED UNDER A LICENSE FOR USE ONLY
ON A SINGLE COMPUTER SYSTEM AND MAY BE COPIED ONLY WITH
THE INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE,
OR ANY OTHER COPIES THEREOF, MAY NOT BE PROVIDED OR OTHERWISE
MADE AVAILABLE TO ANY OTHER PERSON EXECPT FOR USE ON SUCH SYSTEM
AND TO ONE WHO AGREES TO THESE LICENSE TERMS. TITLE TO AND
OWNERSHIP OF THE SOFTWARE SHALL AT ALL TIMES REMAIN IN DEC.
THE INFORMATION IN THIS DOCUMENT IS SUBJECT TO CHANGE WITHOUT
NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL
EQUIPMENT CORPORATION.
DEC ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DEC.
MAINDEC-10-DAKAG.TXT
PAGE 2
TABLE OF CONTENTS
-----------------
1.0 ABSTRACT
2.0 REQUIREMENTS
2.1 EQUIPMENT
2.2 STORAGE
2.3 PRELIMINARY PROGRAMS
3.0 PROGRAM PROCEDURES
3.1 LOADING PROCEDURE
3.2 STARTING PROCEDURE
3.3 OPERATING PROCEDURE
4.0 ERRORS
5.0 ITERATION COUNTER
6.0 CYCLE TIME
7.0 OPERATIONAL VARIATIONS
8.0 MISCELLANEOUS
9.0 LISTING
MAINDEC-10-DAKAG.TXT
PAGE 3
1.0 ABSTRACT
THIS PDP-10 KA10 BASIC INSTRUCTION DIAGNOSTIC IS THE
SEVENTH IN A SERIES OF PDP-10 KA10 PROCESSOR DIAGNOSTICS.
THE DIAGNOSTIC TESTS THE PUSH, POP, XCT AND BASIC
SHIFT ROTATE INSTRUCTIONS.
2.0 REQUIREMENTS
2.1 EQUIPMENT
A PDP-10 KA10 WITH A MINIMUM OF 32K OF MEMORY
PAPER TAPE READER
DECTAPE (OPTIONAL)
CONSOLE TELETYPE
2.2 STORAGE
THE PROGRAM RUNS WITHIN 32K OF MEMORY.
2.3 PRELIMINARY PROGRAMS
CONSOLE FUNCTIONS WORKING PROPERLY
PAPER TAPE OR DECTAPE READ-IN WORKING PROPERLY
PREVIOUS PROCESSOR DIAGNOSTICS
MAINDEC-10-DAKAG.TXT
PAGE 4
3.0 PROGRAM PROCEDURES
3.1 LOADING PROCEDURE
PAPER TAPE - HARDWARE READ-IN (READER DEVICE CODE 104)
DECTAPE - LOAD WITH DIAMON (DECTAPE DEVICE CODE 320)
3.2 STARTING PROCEDURE
STAND-ALONE STARTING ADDRESS IS 30000.
IF THE DIAGNOSTIC FAILS TO START CORRECTLY TRY STARTING AT THE
FIRST TEST INSTEAD OF AT THE BEGINNING OF THE CONTROL SEQUENCE.
(SEE LISTING).
3.3 OPERATING PROCEDURE
ONCE STARTED THE PROGRAM WILL CYCLE CONTINUALLY UNTIL STOPPED
OR AN ERROR OCCURS.
4.0 ERRORS
ERRORS ARE IN THE FORM OF HALT INSTRUCTIONS. THE LISTING
SHOULD BE CONSULTED TO DETERMINE THE CAUSE OF THE ERROR. A
NO OPERATION (JUMP) INSTRUCTION FOLLOWS EACH HALT. THIS
MAY BE USEFUL IN CONSTRUCTING A SCOPE LOOP TO CYCLE ON THE
FAILING INSTRUCTION.
5.0 ITERATION COUNTER
THE ITERATION COUNT OF THE PROGRAM IS DISPLAYED IN THE MEM-
ORY INDICATORS (MI). THIS COUNT IS A DECREMENTING COUNT AND
INITIALLY STARTS AT -1 IN STAND-ALONE OPERATION.
6.0 CYCLE TIME
THE CYCLE TIME OF THE PROGRAM IS IN THE MILLISECOND RANGE AND
IS THEREFORE SUITABLE FOR TAKING MARGINS, VIBRATION TESTS, ETC.
MAINDEC-10-DAKAG.TXT
PAGE 5
7.0 OPERATIONAL VARIATIONS
A. DIAGNOSTIC MONITOR
THE PROGRAM IS USABLE WITH THE DIAGNOSTIC MONITOR TO PRO-
VIDE RELIABILITY TESTS, ACCEPTANCE TESTS, AND/OR TO PRO-
VIDE A QUICK METHOD OF ISOLATION OF A FAULT TO A PARTICULAR
AREA OF THE PROCESSOR. CERTAIN PROCEDURES ARE USED WHEN
THE PROGRAM IS USED IN THIS MANNER. THEY ARE:
1. THE DIAGNOSTIC MONITOR TRANSFERS CONTROL TO THE PRO-
GRAM AND STARTS IT AT LOCATION 30002.
2. MONCTL - LOCATION 30043 IS USED AS THE DIAGNOSTIC MON-
ITOR CONTROL FLAG WORD.
B. USER MODE
THE PROGRAM WILL OPERATE IN USER MODE AND AS SUCH PROVIDES
ASSURANCE THAT THE PROCESSOR IS PERFORMING ALL FUNCTIONS
CORRECTLY. USER MODE STARTING ADDRESS IS 30000.
C. SYSTEM EXERCISER
STARTING ADDRESS IS 30003. NO DATA SWITCHES ARE USED BY
THIS PROGRAM.
8.0 MISCELLANEOUS
NONE
9.0 LISTING
```
DAKAG.HST
---------
THIS IS A HISTORY OF THE DEVELOPMENT OF MAINDEC-10-DAKAG
************************************************************************
PRODUCT CODE: MAINDEC-10-DAKAG
PRODUCT NAME: BASIC INSTRUCTION DIAGNOSTIC #7
DATE RELEASED: JANUARY 1977
VERSION: 0.2
UPDATE AUTHOR: JOHN R. KIRCHOFF
CHANGES MADE:
1. UPGRADE TO ALLOW COMPATABILITY WITH THE SUBROUTINE PACKAGE.
************************************************************************
ORIGINAL VERSION: 0.1
ORIGINAL AUTHOR: RICHARD MALISKA
ORIGINAL RELEASE: 16-MAR-72
************************************************************************
DAKAG.MAC
---------
[[Download](DAKAG.MAC.txt)]
{% highlight text %}
{% include_relative DAKAG.MAC.txt %}
{% endhighlight %}

View file

@ -336,17 +336,18 @@ PDP10.opILDB = function(op, ac)
* is with regEA containing the address of the bits to be loaded.
*
* We can implement this as a simple combination of opIBP() and opLDB(), but taking care that we only call
* opIBP() on phase 1.
* opIBP() on phase 1 (and only if the BIS flag is not set).
*/
if (this.regBP < 0) {
if (!(this.regPS & PDP10.PSFLAG.BIS)) {
PDP10.opIBP.call(this, op, ac);
this.regPS |= PDP10.PSFLAG.BIS;
}
PDP10.opLDB.call(this, op, ac);
};
/**
* opLDB(0o135000): Load Byte
*
*z
* From the DEC PDP-10 System Reference Manual (May 1968), p. 2-16:
*
* Retrieve a byte of S bits from the location and position specified by the pointer contained in location E,
@ -393,6 +394,7 @@ PDP10.opLDB = function(op, ac)
w = Math.trunc(w / Math.pow(2, p)) % Math.pow(2, s);
}
this.writeWord(ac, w);
this.regPS &= ~PDP10.PSFLAG.BIS;
this.regBP = -1;
};
@ -422,10 +424,11 @@ PDP10.opIDPB = function(op, ac)
* is with regEA containing the address of the bits to be stored.
*
* We can implement this as a simple combination of opIBP() and opDDB(), but taking care that we only call
* opIBP() on phase 1.
* opIBP() on phase 1 (and only if the BIS flag is not set).
*/
if (this.regBP < 0) {
if (!(this.regPS & PDP10.PSFLAG.BIS)) {
PDP10.opIBP.call(this, op, ac);
this.regPS |= PDP10.PSFLAG.BIS;
}
PDP10.opDPB.call(this, op, ac);
};
@ -471,6 +474,7 @@ PDP10.opDPB = function(op, ac)
var b = ((this.readWord(ac) % Math.pow(2, s)) * Math.pow(2, p)) % PDP10.WORD_LIMIT;
w = (w - (w % Math.pow(2, p + s))) + b + (w % Math.pow(2, p));
this.writeWord(this.regEA, w);
this.regPS &= ~PDP10.PSFLAG.BIS;
this.regBP = -1;
};
@ -2323,7 +2327,19 @@ PDP10.opXCT = function(op, ac)
};
/**
* opPUSHJ(0o260000)
* opPUSHJ(0o260000): Push Down and Jump
*
* From the DEC PDP-10 System Reference Manual (May 1968), p. 2-62:
*
* Add 1000001 [base 8] to AC to increment both halves by one and place the result back in AC. If the addition
* causes the count in AC left to reach zero, set the Pushdown Overflow flag. Then place the current contents of
* the flags (as described above) in the left half of the location now addressed by AC right and the contents of
* PC in the right half of that location (at this time PC contains an address one greater than the location of
* the PUSHJ instruction). Take the next instruction from location E and continue sequential operation from there.
*
* The flags are unaffected except Byte Interrupt, which is cleared. The original contents of the location added
* to the list are lost. If this instruction is executed as a result of a priority interrupt or in unrelocated
* 41 or 61 while the processor is in user mode, bit 5 of the PC word stored is 1 and the processor leaves user mode.
*
* @this {CPUStatePDP10}
* @param {number} op
@ -2331,7 +2347,12 @@ PDP10.opXCT = function(op, ac)
*/
PDP10.opPUSHJ = function(op, ac)
{
this.opUndefined(op);
var p = (this.readWord(ac) + 0o000001000001) % PDP10.WORD_LIMIT;
this.writeWord(ac, p);
if (!((p / PDP10.HALF_SHIFT)|0)) this.regPS |= PDP10.PSFLAG.PDOV;
this.writeWord(p & PDP10.ADDR_MASK, this.getPS() * PDP10.HALF_SHIFT + this.getPC());
this.regPS &= ~PDP10.PSFLAG.BIS; // TODO: Verify that BIS is cleared AFTER calling getPS()
this.setPC(this.regEA);
};
/**
@ -2370,16 +2391,16 @@ PDP10.opPUSH = function(op, ac)
* This is the behavior that is clearly documented by DEC.
*/
p += 0o000001000001;
this.writeWord(p & PDP10.HALF_MASK, this.readWord(this.regEA));
this.writeWord(p & PDP10.ADDR_MASK, this.readWord(this.regEA));
if (p >= PDP10.WORD_LIMIT) p -= PDP10.WORD_LIMIT;
if (!((p / PDP10.HALF_SHIFT)|0)) this.regPS |= PDP10.PSFLAG.PDOV;
} else {
/*
* This is the SIMH behavior, which appears to increment each half of AC independently.
*/
var addr = (p + 1) & PDP10.HALF_MASK;
var addr = (p + 1) & PDP10.ADDR_MASK;
this.writeWord(addr, this.readWord(this.regEA));
p = (p + 0o000001000000) - (p & PDP10.HALF_MASK) + addr;
p = (p + 0o000001000000) - (p & PDP10.ADDR_MASK) + addr;
if (p >= PDP10.WORD_LIMIT) {
p -= PDP10.WORD_LIMIT;
this.regPS |= PDP10.PSFLAG.PDOV;
@ -2407,7 +2428,7 @@ PDP10.opPUSH = function(op, ac)
PDP10.opPOP = function(op, ac)
{
var p = this.readWord(ac);
var src = this.readWord(p & PDP10.HALF_MASK);
var src = this.readWord(p & PDP10.ADDR_MASK);
this.writeWord(this.regEA, src);
if (this.regEA == ac) p = src; // this avoids re-reading the accumulator if the write just overwrote it
p -= 0o000001000001;
@ -2417,7 +2438,16 @@ PDP10.opPOP = function(op, ac)
};
/**
* opPOPJ(0o263000)
* opPOPJ(0o263000): Pop Up and Jump
*
* From the DEC PDP-10 System Reference Manual (May 1968), p. 2-63:
*
* Subtract 1000001 [base 8] from AC to decrement both halves by one and place the result back in AC.
* If the subtraction causes the count in AC left to reach -1, set the Pushdown Overflow flag. Take the
* next instruction from the location addressed by the right half of the location that was addressed by
* AC right prior to the decrementing, and continue sequential operation from there.
*
* SIDEBAR: The effective address E is ignored.
*
* @this {CPUStatePDP10}
* @param {number} op
@ -2425,7 +2455,13 @@ PDP10.opPOP = function(op, ac)
*/
PDP10.opPOPJ = function(op, ac)
{
this.opUndefined(op);
var p = this.readWord(ac);
var pc = this.readWord(p & PDP10.ADDR_MASK);
p -= 0o000001000001;
if (p < 0) p += PDP10.WORD_LIMIT;
if (((p / PDP10.HALF_SHIFT)|0) == PDP10.HALF_MASK) this.regPS |= PDP10.PSFLAG.PDOV;
this.writeWord(ac, p);
this.setPC(pc & PDP10.ADDR_MASK);
};
/**
@ -2448,7 +2484,7 @@ PDP10.opPOPJ = function(op, ac)
PDP10.opJSR = function(op, ac)
{
this.writeWord(this.regEA, this.getPS() * PDP10.HALF_SHIFT + this.getPC());
this.regPS &= ~PDP10.PSFLAG.BIS; // TODO: Verify that BIS is cleared AFTER writing
this.regPS &= ~PDP10.PSFLAG.BIS; // TODO: Verify that BIS is cleared AFTER calling getPS()
this.setPC(this.regEA + 1);
};
@ -2472,7 +2508,7 @@ PDP10.opJSR = function(op, ac)
PDP10.opJSP = function(op, ac)
{
this.writeWord(ac, this.getPS() * PDP10.HALF_SHIFT + this.getPC());
this.regPS &= ~PDP10.PSFLAG.BIS; // TODO: Verify that BIS is cleared AFTER writing
this.regPS &= ~PDP10.PSFLAG.BIS; // TODO: Verify that BIS is cleared AFTER calling getPS()
this.setPC(this.regEA);
};

View file

@ -500,6 +500,19 @@ class CPUStatePDP10 extends CPUPDP10 {
return this.regPC;
}
/**
* getXC()
*
* NOTE: This function is nothing more than a convenience, and we fully expect it to be inlined at runtime.
*
* @this {CPUStatePDP10}
* @return {number}
*/
getXC()
{
return this.regXC >= 0? this.regXC : this.regPC;
}
/**
* getLastAddr()
*
@ -534,6 +547,7 @@ class CPUStatePDP10 extends CPUPDP10 {
setPC(addr)
{
this.regPC = addr % PDP10.ADDR_LIMIT;
this.regXC = -1;
}
/**

View file

@ -3344,7 +3344,7 @@ class DebuggerPDP10 extends Debugger {
this.println(this.getRegDump(fMisc));
if (fInstruction) {
this.setAddr(this.dbgAddrCode, cpu.getPC());
this.setAddr(this.dbgAddrCode, cpu.getXC());
this.doUnassemble(this.toStrAddr(this.dbgAddrCode));
}
}
@ -3881,7 +3881,7 @@ class DebuggerPDP10 extends Debugger {
*/
doCommands(sCmds, fSave)
{
if (sCmds) {
if (sCmds != null) {
this.aCommands = this.parseCommand(sCmds, fSave);
}
var sCmd;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long