Merge branch 'master' into gh-pages

This commit is contained in:
Jeff Parsons 2017-04-02 11:04:39 -07:00
commit 68c41bf5d5
13 changed files with 1474 additions and 1041 deletions

View file

@ -20,8 +20,9 @@ for use with the [PDP-10 Test Machine with Debugger](/devices/pdp10/machine/ka10
This diagnostic "TESTS THE MULTIPLY INSTRUCTION AND THE MULTIPLY ALGORITHM." This diagnostic "TESTS THE MULTIPLY INSTRUCTION AND THE MULTIPLY ALGORITHM."
Resources for this diagnostic include: Information regarding this diagnostic includes:
- [Issues](#issues)
- [Instructions](#dakaktxt) - [Instructions](#dakaktxt)
- [History](#dakakhst) - [History](#dakakhst)
- [Source Code](#dakakmac) - [Source Code](#dakakmac)
@ -57,6 +58,37 @@ JavaScript parameters; e.g.:
embedPDP10(...,'{commands:"a 'dakakt.mac;../param.klm;../fixed.klm;dakakm.mac;../uuoerr.klm;../stor.klm'"}'); embedPDP10(...,'{commands:"a 'dakakt.mac;../param.klm;../fixed.klm;dakakm.mac;../uuoerr.klm;../stor.klm'"}');
Issues
------
As noted in [cpuops.js](/modules/pdp10/lib/cpuops.js), in the *doMUL()* function:
> The DAKAK diagnostic contains the following code:
036174: 200240 043643 MOVE 5,43643 ; [43643] = 400000000000
036175: 200300 043603 MOVE 6,43603 ; [43603] = 777777777777
036176: 200140 043604 MOVE 3,43604 ; [43604] = 000000000001
036177: 224240 000003 MUL 5,3 ; Multiply 400000000000 by 000000000001
036200: 312240 043604 CAME 5,43604 ; high order result in AC should be: 000000000001
036201: 003240 033721 UUO 5,33721 ;
036202: 312300 043602 CAME 6,43602 ; low order result in AC+1 should be: 000000000000
> The "natural" result is:
05=777777777777 06=400000000000
> And SIMH seems to agree. So why does the DEC diagnostic expect:
05=000000000001 06=000000000000
> The answer can be found in the [DECSYSTEM-10 and DECSYSTEM-20 Processor Reference Manual (June 1982)](http://archive.pcjs.org/pubs/dec/pdp10/kl10/AA-H391A-TK_DECsystem-10_DECSYSTEM-20_Processor_Reference_Jun1982.pdf),
in the description of the MUL instruction:
CAUTION: In the KA10, an AC operand of 2^35 is treated as though it were +2^35, producing the
incorrect sign in the product.
> This behavior is now simulated below for MODEL_KA10, at least to the extent that the diagnostic is happy.
--- ---
DAKAK.TXT DAKAK.TXT

View file

@ -21,8 +21,9 @@ for use with the [PDP-10 Test Machine with Debugger](/devices/pdp10/machine/ka10
This diagnostic "TESTS THE MULTIPY, INTERGER MULIPLY, DIVIDE AND INTERGER DIVIDE INSTRUCTIONS." Hopefully the tests work better This diagnostic "TESTS THE MULTIPY, INTERGER MULIPLY, DIVIDE AND INTERGER DIVIDE INSTRUCTIONS." Hopefully the tests work better
than their spell-checking. than their spell-checking.
Resources for this diagnostic include: Information regarding this diagnostic includes:
- [Issues](#issues)
- [Instructions](#dakaltxt) - [Instructions](#dakaltxt)
- [History](#dakalhst) - [History](#dakalhst)
- [Source Code](#dakalmac) - [Source Code](#dakalmac)
@ -41,6 +42,270 @@ This command:
will automatically read the [DAKAL.MAC](DAKAL.MAC.txt) source file (a slightly modified copy of [DAKALM.MAC](DAKALM.MAC.txt)), will automatically read the [DAKAL.MAC](DAKAL.MAC.txt) source file (a slightly modified copy of [DAKALM.MAC](DAKALM.MAC.txt)),
assemble it, and then load the binary image at the location specified in the file. assemble it, and then load the binary image at the location specified in the file.
Issues
------
The following DAKAL diagnostic test sequence produced correct results but still failed:
00=000000000000 01=000000000000 02=000000000000 03=000000000000
04=000000000000 05=000000000000 06=000000000000 07=000000000000
10=000000000000 11=000000000000 12=000000000001 13=000000000000
14=777777777777 15=525252525252 16=000000000016 17=000000000000
PC=030641 RA=00030626 EA=030626 PS=000000 OV=0 C0=0 C1=0 ND=0 PD=0
030641: 200600 044434 MOVE 14,44434 ;cycles=1
>> tr
00=000000000000 01=000000000000 02=000000000000 03=000000000000
04=000000000000 05=000000000000 06=000000000000 07=000000000000
10=000000000000 11=000000000000 12=000000000001 13=000000000000
14=525252525252 15=525252525252 16=000000000016 17=000000000000
PC=030642 RA=00044434 EA=044434 PS=000000 OV=0 C0=0 C1=0 ND=0 PD=0
030642: 200640 044435 MOVE 15,44435 ;cycles=1
>> tr
00=000000000000 01=000000000000 02=000000000000 03=000000000000
04=000000000000 05=000000000000 06=000000000000 07=000000000000
10=000000000000 11=000000000000 12=000000000001 13=000000000000
14=525252525252 15=000000000000 16=000000000016 17=000000000000
PC=030643 RA=00044435 EA=044435 PS=000000 OV=0 C0=0 C1=0 ND=0 PD=0
030643: 200500 044440 MOVE 12,44440 ;cycles=1
>> tr
00=000000000000 01=000000000000 02=000000000000 03=000000000000
04=000000000000 05=000000000000 06=000000000000 07=000000000000
10=000000000000 11=000000000000 12=000000000002 13=000000000000
14=525252525252 15=000000000000 16=000000000016 17=000000000000
PC=030644 RA=00044440 EA=044440 PS=000000 OV=0 C0=0 C1=0 ND=0 PD=0
030644: 224600 000012 MUL 14,12 ;cycles=1
>> tr
00=000000000000 01=000000000000 02=000000000000 03=000000000000
04=000000000000 05=000000000000 06=000000000000 07=000000000000
10=000000000000 11=000000000000 12=000000000002 13=000000000000
14=777777777776 15=652525252524 16=000000000016 17=000000000000
PC=030645 RA=00000012 EA=000012 PS=000000 OV=0 C0=0 C1=0 ND=0 PD=0
030645: 312600 044441 CAME 14,44441 ;cycles=1
>> tr
00=000000000000 01=000000000000 02=000000000000 03=000000000000
04=000000000000 05=000000000000 06=000000000000 07=000000000000
10=000000000000 11=000000000000 12=000000000002 13=000000000000
14=777777777776 15=652525252524 16=000000000016 17=000000000000
PC=030647 RA=00044441 EA=044441 PS=000000 OV=0 C0=0 C1=0 ND=0 PD=0
030647: 312640 044442 CAME 15,44442 ;cycles=1
The multiplication of 525252525252 * 2 produces 777777777776,652525252524, which is correct for the PDP-10's 72-bit "dual sign"
format. However, the first time I ran this test, it failed -- not because the result was wrong, but because the value calculated
for the expected result was wrong.
The source code for the test produces the expected results by performing 36-bit multiplication in the MACRO-10 Assembler:
775 ;MULTIPLY A FLOATING 1 BY 1010...101010
776 525252 525252 V1=N1
777 652525 252524 V2=N1*XX
but the expected result *my* MACRO-10 Mini-Assembler calculated was different:
>> dw 44442 l1
044442: 252525 252524
My result wasn't really the *wrong value*; it was the correct (albeit truncated) value in the *wrong format*. My expression
parser was performing simple JavaScript multiplication and then truncating the result to 36 bits; MACRO-10 performs a similar
calculation, but it also adjusts the sign of the low 36 bits to match the sign of the high 36 bits -- because that's what the
PDP-10 does, too.
My solution was to move the expression parser's *multiplication* code to its own function, *evalMUL()*, and then change
the PDP-10 Debugger to override *evalMUL()* with its own function that calls the PDP-10 CPU *doMUL()* function, guaranteeing
that all multiplication results are performed with the same 72-bit precision and returned in the same PDP-10 72-bit format
(before being truncated to 36 bits).
Unfortunately, this creates an incestuous relationship between CPU functionality being tested and the code testing it,
because it increases the likelihood that the multiplication tests will succeed even if/when they calculate incorrect results,
at least whenever the expected results are being calculated with the same multiplicands that the test itself uses.
So, as a precaution, I added some *DEBUG* code to the *evalMUL()* function that outputs all the instances where JavaScript
multiplication and PDP-10 multiplication differ, so that I can verify that all my PDP-10 results match those in DEC's
[MACRO-10 Listing](DAKAL.LST.txt), which I'm treating as "the gold standard."
Here's that output:
MUL(525252525252,000000000002) PDP-10: 652525252524 JavaScript: 252525252524 @030641
MUL(525252525252,000000000002) PDP-10: 652525252524 JavaScript: 252525252524 @030641
MUL(525252525252,000000000010) PDP-10: 652525252520 JavaScript: 252525252520 @030667
MUL(525252525252,000000000010) PDP-10: 652525252520 JavaScript: 252525252520 @030667
MUL(525252525252,000000000040) PDP-10: 652525252500 JavaScript: 252525252500 @030715
MUL(525252525252,000000000040) PDP-10: 652525252500 JavaScript: 252525252500 @030715
MUL(525252525252,000000000200) PDP-10: 652525252400 JavaScript: 252525252400 @030743
MUL(525252525252,000000000200) PDP-10: 652525252400 JavaScript: 252525252400 @030743
MUL(525252525252,000000001000) PDP-10: 652525252000 JavaScript: 252525252000 @030771
MUL(525252525252,000000001000) PDP-10: 652525252000 JavaScript: 252525252000 @030771
MUL(525252525252,000000004000) PDP-10: 652525250000 JavaScript: 252525250000 @031017
MUL(525252525252,000000004000) PDP-10: 652525250000 JavaScript: 252525250000 @031017
MUL(525252525252,000000020000) PDP-10: 652525240000 JavaScript: 252525240000 @031045
MUL(525252525252,000000020000) PDP-10: 652525240000 JavaScript: 252525240000 @031045
MUL(525252525252,000000100000) PDP-10: 652525200000 JavaScript: 252525200000 @031073
MUL(525252525252,000000100000) PDP-10: 652525200000 JavaScript: 252525200000 @031073
MUL(525252525252,000000400000) PDP-10: 652525000000 JavaScript: 252525000000 @031121
MUL(525252525252,000000400000) PDP-10: 652525000000 JavaScript: 252525000000 @031121
MUL(525252525252,000002000000) PDP-10: 652524000000 JavaScript: 252524000000 @031147
MUL(525252525252,000002000000) PDP-10: 652524000000 JavaScript: 252524000000 @031147
MUL(525252525252,000010000000) PDP-10: 652520000000 JavaScript: 252520000000 @031175
MUL(525252525252,000010000000) PDP-10: 652520000000 JavaScript: 252520000000 @031175
MUL(525252525252,000040000000) PDP-10: 652500000000 JavaScript: 252500000000 @031223
MUL(525252525252,000040000000) PDP-10: 652500000000 JavaScript: 252500000000 @031223
MUL(525252525252,000200000000) PDP-10: 652400000000 JavaScript: 252400000000 @031251
MUL(525252525252,000200000000) PDP-10: 652400000000 JavaScript: 252400000000 @031251
MUL(525252525252,001000000000) PDP-10: 652000000000 JavaScript: 252000000000 @031277
MUL(525252525252,001000000000) PDP-10: 652000000000 JavaScript: 252000000000 @031277
MUL(525252525252,004000000000) PDP-10: 650000000000 JavaScript: 250000000000 @031325
MUL(525252525252,004000000000) PDP-10: 650000000000 JavaScript: 250000000000 @031325
MUL(525252525252,020000000000) PDP-10: 640000000000 JavaScript: 240000000000 @031353
MUL(525252525252,020000000000) PDP-10: 640000000000 JavaScript: 240000000000 @031353
MUL(525252525252,100000000000) PDP-10: 600000000000 JavaScript: 200000000000 @031401
MUL(525252525252,100000000000) PDP-10: 600000000000 JavaScript: 200000000000 @031401
MUL(252525252525,000000000002) PDP-10: 125252525252 JavaScript: 525252525252 @031461
MUL(252525252525,000000000010) PDP-10: 125252525250 JavaScript: 525252525250 @031507
MUL(252525252525,000000000040) PDP-10: 125252525240 JavaScript: 525252525240 @031535
MUL(252525252525,000000000200) PDP-10: 125252525200 JavaScript: 525252525200 @031563
MUL(252525252525,000000001000) PDP-10: 125252525000 JavaScript: 525252525000 @031611
MUL(252525252525,000000004000) PDP-10: 125252524000 JavaScript: 525252524000 @031637
MUL(252525252525,000000020000) PDP-10: 125252520000 JavaScript: 525252520000 @031665
MUL(252525252525,000000100000) PDP-10: 125252500000 JavaScript: 525252500000 @031713
MUL(252525252525,000000400000) PDP-10: 125252400000 JavaScript: 525252400000 @031741
MUL(252525252525,000002000000) PDP-10: 125252000000 JavaScript: 525252000000 @031767
MUL(252525252525,000010000000) PDP-10: 125250000000 JavaScript: 525250000000 @032015
MUL(252525252525,000040000000) PDP-10: 125240000000 JavaScript: 525240000000 @032043
MUL(252525252525,000200000000) PDP-10: 125200000000 JavaScript: 525200000000 @032071
MUL(252525252525,001000000000) PDP-10: 125000000000 JavaScript: 525000000000 @032117
MUL(252525252525,004000000000) PDP-10: 124000000000 JavaScript: 524000000000 @032145
MUL(252525252525,020000000000) PDP-10: 120000000000 JavaScript: 520000000000 @032173
MUL(252525252525,100000000000) PDP-10: 100000000000 JavaScript: 500000000000 @032221
MUL(252525252525,000000000002) PDP-10: 125252525252 JavaScript: 525252525252 @032301
MUL(252525252525,000000000010) PDP-10: 125252525250 JavaScript: 525252525250 @032327
MUL(252525252525,000000000040) PDP-10: 125252525240 JavaScript: 525252525240 @032355
MUL(252525252525,000000000200) PDP-10: 125252525200 JavaScript: 525252525200 @032403
MUL(252525252525,000000001000) PDP-10: 125252525000 JavaScript: 525252525000 @032431
MUL(252525252525,000000004000) PDP-10: 125252524000 JavaScript: 525252524000 @032457
MUL(252525252525,000000020000) PDP-10: 125252520000 JavaScript: 525252520000 @032505
MUL(252525252525,000000100000) PDP-10: 125252500000 JavaScript: 525252500000 @032533
MUL(252525252525,000000400000) PDP-10: 125252400000 JavaScript: 525252400000 @032561
MUL(252525252525,000002000000) PDP-10: 125252000000 JavaScript: 525252000000 @032607
MUL(252525252525,000010000000) PDP-10: 125250000000 JavaScript: 525250000000 @032635
MUL(252525252525,000040000000) PDP-10: 125240000000 JavaScript: 525240000000 @032663
MUL(252525252525,000200000000) PDP-10: 125200000000 JavaScript: 525200000000 @032711
MUL(252525252525,001000000000) PDP-10: 125000000000 JavaScript: 525000000000 @032737
MUL(252525252525,004000000000) PDP-10: 124000000000 JavaScript: 524000000000 @032765
MUL(252525252525,020000000000) PDP-10: 120000000000 JavaScript: 520000000000 @033013
MUL(252525252525,100000000000) PDP-10: 100000000000 JavaScript: 500000000000 @033041
MUL(400000000000,400000000000) PDP-10: 400000000000 JavaScript: 000000000000 @033707 VERIFIED
MUL(400000000000,400000000000) PDP-10: 400000000000 JavaScript: 000000000000 @033707 VERIFIED
MUL(400000000000,400000000000) PDP-10: 400000000000 JavaScript: 000000000000 @033707 VERIFIED
MUL(400000000000,400000000000) PDP-10: 400000000000 JavaScript: 000000000000 @033707 VERIFIED
MUL(777777777776,777777777776) PDP-10: 000000000004 JavaScript: 000000000000 @033726
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @033726
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @033726
MUL(777777777775,777777777775) PDP-10: 000000000011 JavaScript: 000000000000 @033741
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @033741
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @033741
MUL(777777777773,777777777773) PDP-10: 000000000031 JavaScript: 000000000000 @033754
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @033754
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @033754
MUL(777777777767,777777777767) PDP-10: 000000000121 JavaScript: 000000000000 @033767
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @033767
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @033767
MUL(777777777757,777777777757) PDP-10: 000000000441 JavaScript: 000000000000 @034002
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @034002
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @034002
MUL(777777777737,777777777737) PDP-10: 000000002101 JavaScript: 000000000000 @034015
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @034015
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @034015
MUL(777777777677,777777777677) PDP-10: 000000010201 JavaScript: 000000000000 @034030
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @034030
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @034030
MUL(777777777577,777777777577) PDP-10: 000000040401 JavaScript: 000000000000 @034043
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @034043
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @034043
MUL(777777777377,777777777377) PDP-10: 000000201001 JavaScript: 000000000000 @034056
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @034056
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @034056
MUL(777777776777,777777776777) PDP-10: 000001002001 JavaScript: 000002000000 @034071
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @034071
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @034071
MUL(777777775777,777777775777) PDP-10: 000004004001 JavaScript: 000004000000 @034104
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @034104
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @034104
MUL(777777773777,777777773777) PDP-10: 000020010001 JavaScript: 000020000000 @034117
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @034117
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @034117
MUL(777777767777,777777767777) PDP-10: 000100020001 JavaScript: 000100000000 @034132
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @034132
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @034132
MUL(777777757777,777777757777) PDP-10: 000400040001 JavaScript: 000400000000 @034145
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @034145
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @034145
MUL(777777737777,777777737777) PDP-10: 002000100001 JavaScript: 002000000000 @034160
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @034160
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @034160
MUL(777777677777,777777677777) PDP-10: 010000200001 JavaScript: 010000000000 @034173
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @034173
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @034173
MUL(777777577777,777777577777) PDP-10: 040000400001 JavaScript: 040000000000 @034206
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @034206
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @034206
MUL(777777377777,777777377777) PDP-10: 200001000001 JavaScript: 200002000000 @034221
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @034221
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @034221
MUL(777776777777,777776777777) PDP-10: 000002000001 JavaScript: 000002000000 @034234
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @034234
MUL(000000777777,000000777777) PDP-10: 377776000001 JavaScript: 777776000001 @034234
MUL(777775777777,777775777777) PDP-10: 000004000001 JavaScript: 000004000000 @034247
MUL(000000777776,000000777776) PDP-10: 377774000004 JavaScript: 777774000004 @034247
MUL(000000777776,000000777776) PDP-10: 377774000004 JavaScript: 777774000004 @034247
MUL(777773777777,777773777777) PDP-10: 000010000001 JavaScript: 000010000000 @034262
MUL(000000777774,000000777774) PDP-10: 377770000020 JavaScript: 777770000020 @034262
MUL(000000777774,000000777774) PDP-10: 377770000020 JavaScript: 777770000020 @034262
MUL(777767777777,777767777777) PDP-10: 000020000001 JavaScript: 000020000000 @034275
MUL(000000777770,000000777770) PDP-10: 377760000100 JavaScript: 777760000100 @034275
MUL(000000777770,000000777770) PDP-10: 377760000100 JavaScript: 777760000100 @034275
MUL(777757777777,777757777777) PDP-10: 000040000001 JavaScript: 000040000000 @034310
MUL(000000777760,000000777760) PDP-10: 377740000400 JavaScript: 777740000400 @034310
MUL(000000777760,000000777760) PDP-10: 377740000400 JavaScript: 777740000400 @034310
MUL(777737777777,777737777777) PDP-10: 000100000001 JavaScript: 000100000000 @034323
MUL(000000777740,000000777740) PDP-10: 377700002000 JavaScript: 777700002000 @034323
MUL(000000777740,000000777740) PDP-10: 377700002000 JavaScript: 777700002000 @034323
MUL(777677777777,777677777777) PDP-10: 000200000001 JavaScript: 000200000000 @034336
MUL(000000777700,000000777700) PDP-10: 377600010000 JavaScript: 777600010000 @034336
MUL(000000777700,000000777700) PDP-10: 377600010000 JavaScript: 777600010000 @034336
MUL(777577777777,777577777777) PDP-10: 000400000001 JavaScript: 000400000000 @034351
MUL(000000777600,000000777600) PDP-10: 377400040000 JavaScript: 777400040000 @034351
MUL(000000777600,000000777600) PDP-10: 377400040000 JavaScript: 777400040000 @034351
MUL(777377777777,777377777777) PDP-10: 001000000001 JavaScript: 001000000000 @034364
MUL(000000777400,000000777400) PDP-10: 377000200000 JavaScript: 777000200000 @034364
MUL(000000777400,000000777400) PDP-10: 377000200000 JavaScript: 777000200000 @034364
MUL(776777777777,776777777777) PDP-10: 002000000001 JavaScript: 002000000000 @034377
MUL(000000777000,000000777000) PDP-10: 376001000000 JavaScript: 776001000000 @034377
MUL(000000777000,000000777000) PDP-10: 376001000000 JavaScript: 776001000000 @034377
MUL(775777777777,775777777777) PDP-10: 004000000001 JavaScript: 004000000000 @034412
MUL(000000776000,000000776000) PDP-10: 374004000000 JavaScript: 774004000000 @034412
MUL(000000776000,000000776000) PDP-10: 374004000000 JavaScript: 774004000000 @034412
MUL(773777777777,773777777777) PDP-10: 010000000001 JavaScript: 010000000000 @034425
MUL(000000774000,000000774000) PDP-10: 370020000000 JavaScript: 770020000000 @034425
MUL(000000774000,000000774000) PDP-10: 370020000000 JavaScript: 770020000000 @034425
MUL(767777777777,767777777777) PDP-10: 020000000001 JavaScript: 020000000000 @034440
MUL(000000770000,000000770000) PDP-10: 360100000000 JavaScript: 760100000000 @034440
MUL(000000770000,000000770000) PDP-10: 360100000000 JavaScript: 760100000000 @034440
MUL(757777777777,757777777777) PDP-10: 040000000001 JavaScript: 040000000000 @034453
MUL(000000760000,000000760000) PDP-10: 340400000000 JavaScript: 740400000000 @034453
MUL(000000760000,000000760000) PDP-10: 340400000000 JavaScript: 740400000000 @034453
MUL(737777777777,737777777777) PDP-10: 100000000001 JavaScript: 100000000000 @034466
MUL(000000740000,000000740000) PDP-10: 302000000000 JavaScript: 702000000000 @034466
MUL(000000740000,000000740000) PDP-10: 302000000000 JavaScript: 702000000000 @034466
MUL(677777777777,677777777777) PDP-10: 200000000001 JavaScript: 200000000000 @034501
MUL(000000700000,000000700000) PDP-10: 210000000000 JavaScript: 610000000000 @034501
MUL(000000700000,000000700000) PDP-10: 210000000000 JavaScript: 610000000000 @034501
MUL(577777777777,577777777777) PDP-10: 000000000001 JavaScript: 400000000000 @034514
MUL(000000600000,000000600000) PDP-10: 040000000000 JavaScript: 440000000000 @034514
MUL(377777777777,377777777777) PDP-10: 000000000001 JavaScript: 000000000000 @034527
MUL(777777377777,000001000000) PDP-10: 777777000000 JavaScript: 377777000000 @035347
MUL(777777377777,000001000000) PDP-10: 777777000000 JavaScript: 377777000000 @035347
MUL(000000000010,377777777777) PDP-10: 377777777770 JavaScript: 777777777770 @000000
MUL(000000000020,377777777777) PDP-10: 377777777760 JavaScript: 777777777760 @000000
--- ---
DAKAL.TXT DAKAL.TXT

File diff suppressed because one or more lines are too long

View file

@ -1431,7 +1431,7 @@ PDP10.opMULB = function(op, ac)
*/ */
PDP10.opIDIV = function(op, ac) PDP10.opIDIV = function(op, ac)
{ {
var dst = PDP10.doDIV.call(this, this.readWord(ac), 0, this.readWord(this.regEA)); var dst = PDP10.doDIV.call(this, this.readWord(this.regEA), this.readWord(ac));
if (dst < 0) return; if (dst < 0) return;
this.writeWord(ac, dst); this.writeWord(ac, dst);
this.writeWord((ac + 1) & 0o17, this.regEX); this.writeWord((ac + 1) & 0o17, this.regEX);
@ -1456,7 +1456,7 @@ PDP10.opIDIV = function(op, ac)
*/ */
PDP10.opIDIVI = function(op, ac) PDP10.opIDIVI = function(op, ac)
{ {
var dst = PDP10.doDIV.call(this, this.readWord(ac), 0, this.regEA); var dst = PDP10.doDIV.call(this, this.regEA, this.readWord(ac));
if (dst < 0) return; if (dst < 0) return;
this.writeWord(ac, dst); this.writeWord(ac, dst);
this.writeWord((ac + 1) & 0o17, this.regEX); this.writeWord((ac + 1) & 0o17, this.regEX);
@ -1481,7 +1481,7 @@ PDP10.opIDIVI = function(op, ac)
*/ */
PDP10.opIDIVM = function(op, ac) PDP10.opIDIVM = function(op, ac)
{ {
var dst = PDP10.doDIV.call(this, this.readWord(ac), 0, this.readWord(this.regEA)); var dst = PDP10.doDIV.call(this, this.readWord(this.regEA), this.readWord(ac));
if (dst < 0) return; if (dst < 0) return;
this.writeWord(this.regEA, dst); this.writeWord(this.regEA, dst);
}; };
@ -1505,9 +1505,10 @@ PDP10.opIDIVM = function(op, ac)
*/ */
PDP10.opIDIVB = function(op, ac) PDP10.opIDIVB = function(op, ac)
{ {
var dst = PDP10.doDIV.call(this, this.readWord(ac), 0, this.readWord(this.regEA)); var dst = PDP10.doDIV.call(this, this.readWord(this.regEA), this.readWord(ac));
if (dst < 0) return; if (dst < 0) return;
this.writeWord(this.regEA, dst); this.writeWord(this.regEA, this.writeWord(ac, dst));
this.writeWord((ac + 1) & 0o17, this.regEX);
}; };
/** /**
@ -1532,7 +1533,7 @@ PDP10.opDIV = function(op, ac)
{ {
var ext = this.readWord(ac); var ext = this.readWord(ac);
var dst = this.readWord((ac + 1) & 0o17); var dst = this.readWord((ac + 1) & 0o17);
dst = PDP10.doDIV.call(this, dst, ext, this.readWord(this.regEA)); dst = PDP10.doDIV.call(this, this.readWord(this.regEA), dst, ext);
if (dst < 0) return; if (dst < 0) return;
this.writeWord(ac, dst); this.writeWord(ac, dst);
this.writeWord((ac + 1) & 0o17, this.regEX); this.writeWord((ac + 1) & 0o17, this.regEX);
@ -1560,7 +1561,7 @@ PDP10.opDIVI = function(op, ac)
{ {
var ext = this.readWord(ac); var ext = this.readWord(ac);
var dst = this.readWord((ac + 1) & 0o17); var dst = this.readWord((ac + 1) & 0o17);
dst = PDP10.doDIV.call(this, dst, ext, this.regEA); dst = PDP10.doDIV.call(this, this.regEA, dst, ext);
if (dst < 0) return; if (dst < 0) return;
this.writeWord(ac, dst); this.writeWord(ac, dst);
this.writeWord((ac + 1) & 0o17, this.regEX); this.writeWord((ac + 1) & 0o17, this.regEX);
@ -1588,7 +1589,7 @@ PDP10.opDIVM = function(op, ac)
{ {
var ext = this.readWord(ac); var ext = this.readWord(ac);
var dst = this.readWord((ac + 1) & 0o17); var dst = this.readWord((ac + 1) & 0o17);
dst = PDP10.doDIV.call(this, dst, ext, this.readWord(this.regEA)); dst = PDP10.doDIV.call(this, this.readWord(this.regEA), dst, ext);
if (dst < 0) return; if (dst < 0) return;
this.writeWord(this.regEA, dst); this.writeWord(this.regEA, dst);
}; };
@ -1615,7 +1616,7 @@ PDP10.opDIVB = function(op, ac)
{ {
var ext = this.readWord(ac); var ext = this.readWord(ac);
var dst = this.readWord((ac + 1) & 0o17); var dst = this.readWord((ac + 1) & 0o17);
dst = PDP10.doDIV.call(this, dst, ext, this.readWord(this.regEA)); dst = PDP10.doDIV.call(this, this.readWord(this.regEA), dst, ext);
if (dst < 0) return; if (dst < 0) return;
this.writeWord(ac, this.writeWord(this.regEA, dst)); this.writeWord(ac, this.writeWord(this.regEA, dst));
this.writeWord((ac + 1) & 0o17, this.regEX); this.writeWord((ac + 1) & 0o17, this.regEX);
@ -1643,7 +1644,7 @@ PDP10.opDIVB = function(op, ac)
* by 2. * by 2.
* *
* The number of places shifted is specified by the result of the effective address calculation * The number of places shifted is specified by the result of the effective address calculation
* taken as a signed number (in twos complement notation) modulo 28 in magnitude. In other words * taken as a signed number (in twos complement notation) modulo 2^8 in magnitude. In other words
* the effective shift E is the number composed of bit 18 (which is the sign) and bits 28-35 of the * the effective shift E is the number composed of bit 18 (which is the sign) and bits 28-35 of the
* calculation result. Hence the programmer may specify the shift directly in the instruction * calculation result. Hence the programmer may specify the shift directly in the instruction
* (perhaps indexed) or give an indirect address to be used in calculating the shift. A positive E * (perhaps indexed) or give an indirect address to be used in calculating the shift. A positive E
@ -6226,28 +6227,53 @@ PDP10.doADD = function(dst, src)
}; };
/** /**
* doDIV(dst, ext, src) * doDIV(src, dst, ext)
* *
* Performs the division (DIV) of a 72-bit operand by a 36-bit operand. * Performs the division (DIV) of a 72-bit operand by a 36-bit operand.
* *
* @this {CPUStatePDP10} * @this {CPUStatePDP10}
* @param {number} dst (36-bit value)
* @param {number} ext (36-bit value extension)
* @param {number} src (36-bit divisor) * @param {number} src (36-bit divisor)
* @param {number} dst (36-bit value)
* @param {number} [ext] (36-bit value extension)
* @return {number} (dst / src) (the remainder is stored in regEX); -1 if error (no division performed) * @return {number} (dst / src) (the remainder is stored in regEX); -1 if error (no division performed)
*/ */
PDP10.doDIV = function(dst, ext, src) PDP10.doDIV = function(src, dst, ext)
{ {
var fNegQ = false, fNegR = false; var fNegQ = false, fNegR = false;
/*
* Perform all the same up-front checks that the PDP-10 performs; if we do our job correctly, then it
* will be impossible for the actual division operation to overflow (the asserts below should never fire).
*/
if (ext === undefined) {
if (!src) {
this.regPS |= PDP10.PSFLAG.DCK | PDP10.PSFLAG.AROV;
return -1;
}
ext = (dst > PDP10.INT_MASK)? PDP10.WORD_MASK : 0;
} else {
var srcAbs = (src < PDP10.INT_LIMIT? src : PDP10.TWO_POW36 - src);
var dstAbs = (dst < PDP10.INT_LIMIT? dst : PDP10.TWO_POW36 - dst);
var extAbs = (ext < PDP10.INT_LIMIT? ext : PDP10.TWO_POW36 - ext - (dstAbs? 1 : 0));
if (extAbs >= srcAbs) {
this.regPS |= PDP10.PSFLAG.DCK | PDP10.PSFLAG.AROV;
return -1;
}
}
/*
* We're done with the PDP-10's "dual sign" operands now; produce a (unified) signed 72-bit dividend.
*/
dst = PDP10.merge72.call(this, dst, ext); dst = PDP10.merge72.call(this, dst, ext);
ext = this.regEX; ext = this.regEX;
/*
* Make all the inputs positive now, to keep the division simple. Fix up the results when we're done.
*/
if (src > PDP10.INT_MASK) { if (src > PDP10.INT_MASK) {
src = PDP10.WORD_LIMIT - src; src = PDP10.WORD_LIMIT - src;
fNegQ = !fNegQ; fNegQ = !fNegQ;
} }
if (ext > PDP10.INT_MASK) { if (ext > PDP10.INT_MASK) {
if (dst) { if (dst) {
ext = PDP10.WORD_MASK - ext; ext = PDP10.WORD_MASK - ext;
@ -6259,11 +6285,6 @@ PDP10.doDIV = function(dst, ext, src)
fNegR = true; fNegQ = !fNegQ; fNegR = true; fNegQ = !fNegQ;
} }
if (ext >= src) {
this.regPS |= PDP10.PSFLAG.DCK | PDP10.PSFLAG.AROV;
return -1;
}
/* /*
* Initialize the four double-length 72-bit values we need for the division process. * Initialize the four double-length 72-bit values we need for the division process.
* *
@ -6314,7 +6335,7 @@ PDP10.doDIV = function(dst, ext, src)
}; };
/** /**
* doMUL(dst, src, fTruncate) * doMUL(dst, src, fTruncate, fExternal)
* *
* Performs the multiplication (MUL) of two signed 36-bit operands. * Performs the multiplication (MUL) of two signed 36-bit operands.
* *
@ -6323,8 +6344,10 @@ PDP10.doDIV = function(dst, ext, src)
* number (base 2^18). Each individual multiplication of these 18-bit "digits" will produce * number (base 2^18). Each individual multiplication of these 18-bit "digits" will produce
* a result within 2^36, well within JavaScript integer accuracy. * a result within 2^36, well within JavaScript integer accuracy.
* *
* PDP-10 "DAKAK" Diagnostic Notes * PDP-10 Diagnostic Notes
* ------------------------------- * -----------------------
*
* The "DAKAK" diagnostic contains the following code:
* *
* 036174: 200240 043643 MOVE 5,43643 ; [43643] = 400000000000 * 036174: 200240 043643 MOVE 5,43643 ; [43643] = 400000000000
* 036175: 200300 043603 MOVE 6,43603 ; [43603] = 777777777777 * 036175: 200300 043603 MOVE 6,43603 ; [43603] = 777777777777
@ -6353,10 +6376,11 @@ PDP10.doDIV = function(dst, ext, src)
* @this {CPUStatePDP10} * @this {CPUStatePDP10}
* @param {number} dst (36-bit value) * @param {number} dst (36-bit value)
* @param {number} src (36-bit value) * @param {number} src (36-bit value)
* @param {boolean} [fTruncate] (true to truncate the result to 36 bits) * @param {boolean} [fTruncate] (true to truncate the result to 36 bits; used by IMUL instructions)
* @param {boolean} [fExternal] (true if external caller; avoids modifying the CPU state)
* @return {number} (dst * src) (the high 36 bits of the result; the low 36 bits are stored in regEX) * @return {number} (dst * src) (the high 36 bits of the result; the low 36 bits are stored in regEX)
*/ */
PDP10.doMUL = function(dst, src, fTruncate) PDP10.doMUL = function(dst, src, fTruncate, fExternal)
{ {
var n1 = dst, n2 = src; var n1 = dst, n2 = src;
var fNeg = false, res, ext; var fNeg = false, res, ext;
@ -6366,7 +6390,7 @@ PDP10.doMUL = function(dst, src, fTruncate)
* we'll negate the result afterward if necessary. * we'll negate the result afterward if necessary.
*/ */
if (n1 > PDP10.INT_MASK) { if (n1 > PDP10.INT_MASK) {
if (this.model != PDP10.MODEL_KA10 || n1 != PDP10.INT_LIMIT) { if (fExternal || this.model != PDP10.MODEL_KA10 || n1 != PDP10.INT_LIMIT) {
n1 = PDP10.WORD_LIMIT - n1; n1 = PDP10.WORD_LIMIT - n1;
fNeg = !fNeg; fNeg = !fNeg;
} }
@ -6404,21 +6428,43 @@ PDP10.doMUL = function(dst, src, fTruncate)
} }
} }
ext = PDP10.split72.call(this, res, ext, fExternal);
if (fTruncate) { if (fTruncate) {
/* /*
* If ext is something OTHER than an extension of the res sign bit, then we have overflow. * Special code for IMUL. I originally tried to avoid calling split72() in this case, but the PDP-10
* still appears to be splitting the result of the multiplication into separately signed 36-bit values,
* so the simplest solution is to call split72() in all cases.
*/
res = this.regEX;
if (!fExternal) {
/*
* Regarding IMUL overflows, the original spec says:
*
* Set Overflow if the product is >= 2^35 or < -2^35 (ie, if the high order word of the double
* length product is not null); the high order word is lost.
*
* However, when the "DAKAL" diagnostic performs a sequence like this:
*
* 00=000000000000 01=000000000000 02=000000000000 03=400000036755
* 04=400000000000 05=000000000003 06=400000000000 07=000000000004
* 10=000000000000 11=000000000011 12=777777400000 13=777777777776
* 14=000000200000 15=400000037134 16=000000000016 17=000000000000
* PC=037145 RA=00400000 EA=400000 PS=000000 OV=0 C0=0 C1=0 ND=0 PD=0
* 037145: 220600 000013 IMUL 14,13 ;cycles=1
*
* it sets 14=777777400000 and leaves overflow clear; since the 'high order word" would be 777777777777,
* not null, I think the spec over-simplifies. So our check is more exhaustive: it verifies that ext is
* nothing more than an extension of the sign bit of res (ie, 0 if res is positive, -1 if res is negative).
* Any other combination of values implies an overflow.
*/ */
if ((ext || res > PDP10.INT_MASK) && (ext != PDP10.WORD_MASK || res <= PDP10.INT_MASK)) { if ((ext || res > PDP10.INT_MASK) && (ext != PDP10.WORD_MASK || res <= PDP10.INT_MASK)) {
this.regPS |= PDP10.PSFLAG.AROV; this.regPS |= PDP10.PSFLAG.AROV;
} }
/*
* Also note that, in the truncate case, we return the low order bits (res), rather than the
* the high order bits (ext) that split72() does.
*/
return res;
} }
ext = res;
return PDP10.split72.call(this, res, ext); }
return ext;
}; };
/** /**
@ -6490,29 +6536,30 @@ PDP10.merge72 = function(dst, ext)
var sign = (ext - (ext % PDP10.INT_LIMIT)); var sign = (ext - (ext % PDP10.INT_LIMIT));
/* /*
* Let's assert that the sign bits of both halves match. * For 72-bit inputs, the PDP-10 doesn't care whether or not the low word's sign
*/ * matches the high word's sign. The high word's sign bit is the controlling bit.
this.assert(sign == (dst - (dst % PDP10.INT_LIMIT)), "sign mismatch"); *
* this.assert(sign == (dst - (dst % PDP10.INT_LIMIT)), "sign mismatch");
/* *
* Compute value without the sign bit and add the low bit of extended in its place. * Compute value without the sign bit and add the low bit of extended in its place.
*/ */
dst = (dst % PDP10.INT_LIMIT) + ((ext * PDP10.INT_LIMIT) % PDP10.WORD_LIMIT); dst = (dst % PDP10.INT_LIMIT) + ((ext & 1) * PDP10.INT_LIMIT);
this.regEX = sign + Math.trunc(ext / 2); this.regEX = sign + Math.trunc(ext / 2);
return dst; return dst;
}; };
/** /**
* split72(res, ext) * split72(res, ext, fExternal)
* *
* Returns two 36-bit values with matching sign bits from a unified 72-bit result. * Returns two 36-bit values with matching sign bits from a unified 72-bit result.
* *
* @this {CPUStatePDP10} * @this {CPUStatePDP10}
* @param {number} res (36-bit value) * @param {number} res (36-bit value)
* @param {number} ext (36-bit value) * @param {number} ext (36-bit value)
* @param {boolean} [fExternal] (true if external caller; avoids modifying the CPU state)
* @return {number} (returns the upper 36 bits; the lower 36 bits are stored in regEX) * @return {number} (returns the upper 36 bits; the lower 36 bits are stored in regEX)
*/ */
PDP10.split72 = function(res, ext) PDP10.split72 = function(res, ext, fExternal)
{ {
/* /*
* We just produced a signed 72-bit result, whereas the PDP-10 stores 72-bit arithmetic values as two * We just produced a signed 72-bit result, whereas the PDP-10 stores 72-bit arithmetic values as two
@ -6525,9 +6572,24 @@ PDP10.split72 = function(res, ext)
var sign = ext - (ext % PDP10.INT_LIMIT); var sign = ext - (ext % PDP10.INT_LIMIT);
ext = ((ext * 2) % PDP10.WORD_LIMIT) + Math.trunc(res / PDP10.INT_LIMIT); ext = ((ext * 2) % PDP10.WORD_LIMIT) + Math.trunc(res / PDP10.INT_LIMIT);
res = sign + (res % PDP10.INT_LIMIT); res = sign + (res % PDP10.INT_LIMIT);
var signNew = ext - (ext % PDP10.INT_LIMIT); var signNew = ext - (ext % PDP10.INT_LIMIT);
if (sign != signNew) { if (signNew != sign) {
ext = sign + (ext - signNew); /*
* I used to restore ext's original sign (ext = sign + (ext - signNew)), but the PDP-10's defined
* behavior for multiplication overflow (ie, whenever both operands are 0o400000000000) is to set both
* res and ext to 0o400000000000.
*
* To quote the original spec for the MUL instruction:
*
* If both operands are -2^35 set Overflow; the double length result stored is -2^70.
*/
res = ext;
}
if (fExternal) return res;
if (res == PDP10.INT_LIMIT && ext == PDP10.INT_LIMIT) {
this.regPS |= PDP10.PSFLAG.AROV; this.regPS |= PDP10.PSFLAG.AROV;
} }
this.regEX = res; this.regEX = res;

View file

@ -510,7 +510,7 @@ class CPUStatePDP10 extends CPUPDP10 {
*/ */
getXC() getXC()
{ {
return this.regXC >= 0? this.regXC : this.regPC; return this.regXC >= 0? this.regXC : ((this.regRA & PDP10.OPCODE.I_FIELD)? this.lastPC : this.regPC);
} }
/** /**
@ -546,8 +546,9 @@ class CPUStatePDP10 extends CPUPDP10 {
*/ */
setPC(addr) setPC(addr)
{ {
this.regPC = addr % PDP10.ADDR_LIMIT; this.regRA = 0;
this.regXC = -1; this.regXC = -1;
this.regPC = addr % PDP10.ADDR_LIMIT;
} }
/** /**

View file

@ -507,6 +507,37 @@ class DebuggerPDP10 extends Debugger {
} }
} }
/**
* evalMUL(dst, src)
*
* Overrides the standard multiplication function with one that honors PDP-10 semantics and precision.
*
* @this {DebuggerPDP10}
* @param {number} dst
* @param {number} src
* @return {number} (dst * src)
*/
evalMUL(dst, src)
{
/*
* The CPU requires that all 36-bit inputs/outputs be UNSIGNED, whereas our expression evaluator allows signed
* inputs/outputs. So we perform two's complement conversions on all inputs/outputs as needed.
*/
if (dst < 0) dst += PDP10.WORD_LIMIT;
if (src < 0) src += PDP10.WORD_LIMIT;
var result = PDP10.doMUL.call(this.cpu, dst, src, false, true);
if (result >= PDP10.INT_LIMIT) result -= PDP10.WORD_LIMIT;
if (MAXDEBUG) {
var resultJS = this.truncate(dst * src);
if (resultJS !== result) {
var sReference = this.macro10? (" @" + this.toStrBase(this.macro10.nLocation)) : "";
var sResults = "PDP-10: " + this.toStrBase(result, 36) + " JavaScript: " + this.toStrBase(resultJS, 36);
this.println("MUL(" + this.toStrBase(dst, 36) + "," + this.toStrBase(src, 36) + ") " + sResults + sReference);
}
}
return result;
}
/** /**
* parseAddr(sAddr, dbgAddr) * parseAddr(sAddr, dbgAddr)
* *
@ -3908,7 +3939,7 @@ class DebuggerPDP10 extends Debugger {
*/ */
doTest() doTest()
{ {
if (DEBUG) { if (MAXDEBUG) {
var ops = {}, aOpXXX = []; var ops = {}, aOpXXX = [];
var op, opXXX, opCode, sOperation; var op, opXXX, opCode, sOperation;
for (op = 0o00000; op <= 0o77774; op += 4) { for (op = 0o00000; op <= 0o77774; op += 4) {

View file

@ -426,6 +426,22 @@ class Debugger extends Component
return ((((dst / Debugger.TWO_POW32)|0) ^ ((src / Debugger.TWO_POW32)|0)) * Debugger.TWO_POW32) + ((dst ^ src) >>> 0); return ((((dst / Debugger.TWO_POW32)|0) ^ ((src / Debugger.TWO_POW32)|0)) * Debugger.TWO_POW32) + ((dst ^ src) >>> 0);
} }
/**
* evalMUL(dst, src)
*
* I could have adapted the code from /modules/pdp10/lib/cpuops.js:PDP10.doMUL(), but it was simpler to
* write this base method and let the PDP-10 Debugger override it with a call to the *actual* doMUL() method.
*
* @this {Debugger}
* @param {number} dst
* @param {number} src
* @return {number} (dst * src)
*/
evalMUL(dst, src)
{
return dst * src;
}
/** /**
* truncate(v, nBits, fUnsigned) * truncate(v, nBits, fUnsigned)
* *
@ -457,15 +473,21 @@ class Debugger extends Component
} }
else { else {
if (nBits <= 32) { if (nBits <= 32) {
vNew = v | 0; vNew = (v << (32 - nBits)) >> (32 - nBits);
} else { }
else {
limit = Math.pow(2, nBits - 1); limit = Math.pow(2, nBits - 1);
if (v < -limit) { if (v >= limit) {
if (v < -limit * 2) vNew = v % (limit * 2); vNew = (v % limit);
vNew += (limit * 2); if (((v / limit)|0) & 1) vNew -= limit;
} else if (vNew >= limit) { } else if (v < -limit) {
if (v >= limit * 2) vNew = v % (limit * 2); vNew = (v % limit);
vNew -= (limit * 2); // the sign bit was set in this overly large value, so make it negative if ((((-v - 1) / limit) | 0) & 1) {
if (vNew) vNew += limit;
}
else {
if (!vNew) vNew -= limit;
}
} }
} }
} }
@ -513,7 +535,7 @@ class Debugger extends Component
var val1 = aVals.pop(); var val1 = aVals.pop();
switch(chOp) { switch(chOp) {
case '*': case '*':
valNew = val1 * val2; valNew = this.evalMUL(val1, val2);
break; break;
case '/': case '/':
if (!val2) return false; if (!val2) return false;
@ -656,6 +678,9 @@ class Debugger extends Component
} }
} }
v = this.parseArray(asValues, iStart, iValue-1, this.nBase, fQuiet); v = this.parseArray(asValues, iStart, iValue-1, this.nBase, fQuiet);
if (v != null && nUnary) {
v = this.parseUnary(v, nUnary);
}
sValue = (iValue < iLimit? asValues[iValue++].trim() : ""); sValue = (iValue < iLimit? asValues[iValue++].trim() : "");
sOp = (iValue < iLimit? asValues[iValue++] : ""); sOp = (iValue < iLimit? asValues[iValue++] : "");
} }
@ -991,7 +1016,7 @@ class Debugger extends Component
} }
/** /**
* parseValue(sValue, sName, fQuiet, nUnary) * parseUnary(value, nUnary)
* *
* nUnary is actually a small "stack" of unary operations encoded in successive pairs of bits. * nUnary is actually a small "stack" of unary operations encoded in successive pairs of bits.
* As parseExpression() encounters each unary operator, nUnary is shifted left 2 bits, and the * As parseExpression() encounters each unary operator, nUnary is shifted left 2 bits, and the
@ -1004,6 +1029,35 @@ class Debugger extends Component
* then we'll have to switch to a more "expensive" approach (eg, an actual array of unary operators). * then we'll have to switch to a more "expensive" approach (eg, an actual array of unary operators).
* *
* @this {Debugger} * @this {Debugger}
* @param {number} value
* @param {number} nUnary
* @return {number}
*/
parseUnary(value, nUnary)
{
while (nUnary) {
switch(nUnary & 0o3) {
case 1:
value = -this.truncate(value);
break;
case 2:
value = this.evalXOR(value, -1); // this is easier than adding an evalNOT()...
break;
case 3:
var bit = 35; // simple left-to-right zero-bit-counting loop...
while (bit >= 0 && !this.evalAND(value, Math.pow(2, bit))) bit--;
value = 35 - bit;
break;
}
nUnary >>>= 2;
}
return value;
}
/**
* parseValue(sValue, sName, fQuiet, nUnary)
*
* @this {Debugger}
* @param {string|undefined} sValue * @param {string|undefined} sValue
* @param {string|null} [sName] is the name of the value, if any * @param {string|null} [sName] is the name of the value, if any
* @param {boolean} [fQuiet] * @param {boolean} [fQuiet]
@ -1040,23 +1094,7 @@ class Debugger extends Component
} }
} }
if (value != null) { if (value != null) {
while (nUnary) { value = this.truncate(this.parseUnary(value, nUnary));
switch(nUnary & 0o3) {
case 1:
value = -this.truncate(value);
break;
case 2:
value = this.evalXOR(value, -1); // this is easier than adding an evalNOT()...
break;
case 3:
var bit = 35; // simple left-to-right zero-bit-counting loop...
while (bit >= 0 && !this.evalAND(value, Math.pow(2, bit))) bit--;
value = 35 - bit;
break;
}
nUnary >>>= 2;
}
value = this.truncate(value);
} else { } else {
if (!fQuiet) { if (!fQuiet) {
this.println("invalid " + (sName? sName : "value") + ": " + sValue); this.println("invalid " + (sName? sName : "value") + ": " + sValue);

View file

@ -14,7 +14,8 @@ directory. If a PDF was not searchable, it was "OCR'ed" before being archived b
PDP-10 Hardware Publications PDP-10 Hardware Publications
---------------------------- ----------------------------
- [PDP-10 System Reference Manual (1968)](http://archive.pcjs.org/pubs/dec/pdp10/ka10/DEC-10-HGAA-D_PDP-10_System_Reference_Manual_May1968.pdf) [[Original PDF](http://bitsavers.trailing-edge.com/pdf/dec/pdp10/KA10/DEC-10-HGAA-D_PDP-10_System_Reference_Manual_May1968.pdf)] - [PDP-10 System Reference Manual (May 1968)](http://archive.pcjs.org/pubs/dec/pdp10/ka10/DEC-10-HGAA-D_PDP-10_System_Reference_Manual_May1968.pdf) [[Original PDF](http://bitsavers.trailing-edge.com/pdf/dec/pdp10/KA10/DEC-10-HGAA-D_PDP-10_System_Reference_Manual_May1968.pdf)]
- [DECSYSTEM-10/DECSYSTEM-20 Processor Reference Manual (June 1982)](http://archive.pcjs.org/pubs/dec/pdp10/tops10/AA-H391A-TK_DECsystem-10_DECSYSTEM-20_Processor_Reference_Jun1982.pdf) [[Original PDF](http://bitsavers.org/pdf/dec/pdp10/TOPS10_softwareNotebooks/vol05/AA-H391A-TK_DECsystem-10_DECSYSTEM-20_Processor_Reference_Jun1982.pdf)]
PDP-10 Software Publications PDP-10 Software Publications
---------------------------- ----------------------------

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long