Merge branch 'master' into gh-pages
This commit is contained in:
commit
68c41bf5d5
13 changed files with 1474 additions and 1041 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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
Loading…
Reference in a new issue