Selt-Test ASM

//
// This is a test of a VESPA processor.
//
// Testing hardware with software running on that same questionable 
// hardware is not trivial, so we will start out by being somewhat
// skeptical that things actually work, and we will get more
// sophisticated as we build confidence.    
// 
//------------------------------------------------------------------------
// USER REQUIREMENTS
//------------------------------------------------------------------------
// 
//   When a HALT instruction is encountered...... 
//     the user must somehow 
//      - output the current values of Registers 1, 2, 3, and 5, and 
//      - output the program counter 
//	
//------------------------------------------------------------------------
// OUTPUT SUMMARY
//------------------------------------------------------------------------
//
//  PC (Program Counter) 
//     < 0x0800 - initial sanity checks failed
//     > 0x0800 - sanity tests passed
//       - see registers 1, 2, 3, and 5 for test results
//
//  Registers 1, 2, 3, and 5
//    test result details - IF - the initial sanity tests passed
//
//  Register 0 
//    an easy way to watch the progress thru this test program 
//
//------------------------------------------------------------------------
// OUTPUT DETAILS
//------------------------------------------------------------------------
//      
//  The value of the program counter will tell which of the HLT
//  instructions was executed.  
//    - The first HALT instructions appear in the intial sanity checks.
//      A HALT with a program counter less than 0x0800 indicates
//      that there was a HALT during initial sanity checking.
//        HALT address
//               < 0100  - initial branch tests failed
//         0100 -> 0200  - setting the -equal- condition code testing failed
//         0200 -> 0300  - load-immediate and -equal- condition code testing failed
//         0300 -> 0400  - load-immediate, compare, or, and -equal- cc testing failed
//         0400 -> 0500  - using registers 0 thru 7
//    - If the HALT is at a program counter value greater than 
//      0x0800, then the initial sanity checks passed.
//
//  If the initial sanity checks are passed, then Registers 1, 2, and 3  
//  will be used as indicators showing which tests are successfully 
//  executed in some general categories.  The registers are used as
//  -bit-masks- with a bit turned on for each test category successfully executed.
//  This technique allows the values in these registers to simultaneously
//    indicate which tests passed,
//    indicate which tests failed.
//  At least during processor development and debug the indication of 
//  which tests did -not- pass will be exceedingly useful.  Note that there
//  is not a bit for each and every test.  Instead, each bit represents a
//  -small- group of similar tests.
//
//   Reg 1 - Category 1 - basic register useage, memory access, and condition code
//   Reg 2 - Category 2 - alu operations
//   Reg 3 - Category 3 - more complex operations, data hazards
//
//  (in the following list the value under the -label- column is the assembler
//   label at the start of this test section - possibly handy if you want to
//   quickly locate the implementation for a particular test.)   
//		
//   The tests are performed in the same order as the bits are listed here.  This
//   is done because if there are multiple failures the first failure is probably
//   the more interesting.  This is because subsequent failures can be the result
//   of innocently using a function previously found to be incorrect.
//
//     Register 1 - bit mask values          -binary-           -hex-    -label-
//       verify-register-access        0..0100000000000000     x0..4000    RA0
//       load-immediate-positive       0..0010000000000000     x0..2000    LI0
//       load/store                    0..0001000000000000     x0..1000    LS0
//       load-immediate-negative       0..0000100000000000     x0..0800    LI10 
//       more load-immediate           0..0000010000000000     x0..0400    LI15
//       -N- condition code            0..0000001000000000     x0..0200    CN0
//       -Z- condition code            0..0000000100000000     x0..0100    CZ0
//       -V- condition code            0..0000000010000000     x0..0080    CV0
//       -C- condition code            0..0000000001000000     x0..0040    CC0
//     Register 2 - bit mask values
//       compare register              0..0100000000000000     x0..4000    CP0
//       compare immediate             0..0010000000000000     x0..2000    CP14
//       add register                  0..0001000000000000     x0..1000    AD0
//       add immediate                 0..0000100000000000     x0..0800    AD11
//       subtract register             0..0000010000000000     x0..0400    SU0
//       subtract immediate            0..0000001000000000     x0..0200    SU11
//       and register                  0..0000000100000000     x0..0100    AN0
//       and immediate                 0..0000000010000000     x0..0080    AN7
//       or register                   0..0000000001000000     x0..0040    OR0
//       or immediate                  0..0000000000100000     x0..0020    OR7
//       not                           0..0000000000010000     x0..0010    NT0
//     Register 3 - bit mask values
//       BGE and BLT tests             0..0100000000000000     x0..4000    CX0
//       BGT and BLE tests             0..0010000000000000     x0..2000    CX10
//       ALU pass-thru tests           0..0001000000000000     x0..1000    PT0
//       load-indexed                  0..0000100000000000     x0..0800    LX0
//       store-indexed                 0..0000010000000000     x0..0400    SX0
//       branch - next instruction     0..0000001000000000     x0..0200    BC0
//       branch - negative offset      0..0000000100000000     x0..0100    BC10
//       jump                          0..0000000010000000     x0..0080    JP0
//       jump-and-link                 0..0000000001000000     x0..0040    JL0
//       hazard recently modified reg  0..0000000000100000     x0..0020    DH0
//       hazard recently modified reg  0..0000000000010000     x0..0010    DH5
//       hazard recently modified reg  0..0000000000001000     x0..0008    DH10
//       hazard recently loaded reg    0..0000000000000100     x0..0004    DH20
//       really risky tests            0..0000000000000010     x0..0002    RR0 
//
//
//  Register 5 is a simple count of the tests passed.
//
//  Register 0 is loaded with the bit-mask value for each test - when that
//    test is completed.  This happens if the test is successful or not.
//    So watching the value of Reg 0 let-s you keep track of the last
//    test which was completed.        
//
//------------------------------------------------------------------------
// OUTPUT AFTER PERFECT EXECUTION
//------------------------------------------------------------------------
//      
// If -all- tests have been passed, then, when we halt...
//   the PC will be greater than 0x0800
//   Register 1 will contain  00007FC0 
//   Register 2 will contain  00007FF0
//   Register 3 will contain  00007FFE
//   Register 5 will contain  0000006E  (110 - decimal)
//
// Approximately 1100 (decimal) instructions will be executed. 
//
// Note - it is not considered good form to simply set the VESPA 
//        registers to these values and terminate without actually
//        doing much of anything.  Initially that might look 
//        exceedingly successful, but....    
//
//------------------------------------------------------------------------
// Let-s begin
//------------------------------------------------------------------------
// The first thing we are going to do is test that we can BRANCH forward
// correctly.  (We will worry about branch back, or with a negative
// offset later.)  (We will also worry about setting and testing the
// condition code later.)  
// If we cannot branch, then it is going to be pretty hard to alter our
// instruction sequence based on the results of any testing.
//
// If this branch testing should FAIL, we will HALT with a program 
// counter which is less than 100 (hex). 
//
       NOP                  ; do nothing be sure we can increment the PC 
       BRA   B11            ; branch (always) - be sure we compute a br addr 
//                  Note that -branch-delay- processing means that somewhere,
//                  somehow some -nop- instructions are being inserted after a branch.
//                  We put one here to be -very- sure since we are not very trusting yet.  
       NOP                  ; nop just to be sure we do not have branch delay problems
       HLT                  ; if we did not branch we should just stop here
       HLT                  ; it should not be possible to get here, but...
       HLT                  ; it should not be possible to get here, but...
B11:   BRA   B12            ; let-s try another branch
//                  This branch target B11 is surrounded by HLT instructions
//                  so if the branch address was computed incorrectly we 
//                  are probably going to hit one of the HLT instructions.  
       NOP                  ; nop just to be sure we do not have branch delay problems
       HLT                  ; again - should not get here
       HLT                  ; or here
       HLT                  ; or here
       NOP                  ; or here 
B12:   NOP                  ; but we should have gotten here
       NOP                  ; just insert a filler
       NOP                  ; and another filler
//                  Now let-s be sure we do not have some problem with branch-delay
//                  processing.  
       BRA   B13            ; branch again
       HLT                  ; if the next instruction is executed we halt
       HLT                  ; should not be able to get here
       HLT                  ; or here
B13:   BRA   B20            ; finally let-s go on to the next tests
//
// Well, it seems that we can branch forward. (At least some)
// And, the next instruction after a branch is -not- being executed. 
//  
//------------------------------------------------------------------------
// Now, let-s see about some setting and testing of the -equal- condition code 
//------------------------------------------------------------------------
// We are going to worry first about -equal- or -zero- setting and testing
// of the condition code.  After all, if we want to know if the result of 
// a test was successful we need to check to see if the result was equal
// to an expected value.  
       .ORG   0x100         ; set the instruction address
//                  Note - we are setting the location - to group HALT
//                  addresses for this early testing
// If this initial testing of setting and testing the -equal- condition code
// should FAIL, we will HALT with a program counter in the 0x1xx range.
//
// The goal of this testing is to check that we can -probably- set and test
// the -equal- or -zero- bit of the condition code. 
//
// Of course this implicitly tests some ALU operations also because you have
// to use the ALU to set the condition code bits.
//
// We will be using register zero for these tests to minimize any difficulty
// in correctly computing the address of a register in the register array 
// 
B20:   NOP                  ; well, here we are after branch testing
       LDI    R0,#0         ; phooey - trapped
// verilog requires a reg be -set- before it can be used - oh well
       NOP
       NOP
       SUB   R0,R0,R0       ; subtracting something from itself should be zero
//                  Note - this did not require any loading of the register
//                  to set an initial value
       BEQ   B21            ; we really should take this branch
       HLT                  ; if we are here then either setting the -equal-
//                            condition code or BEQ is not working so well
B21:   NOP                  ; good - it looks like BEQ worked
//                  If that is true - and we really set and tested the condition 
//                  code - then a BNE should not be taken
       BNE   B22            ; we should -not- take this branch
       BRA   B23            ; which means we should get here
B22:   HLT                  ; setting or testing the -equal- condition code
//                            failed if we have gotten here
B23:   NOP                  ; it -seems- we were successful     
//                  It seems that we set, and tested, the -equal- condition code bit
       BRA   B30            ; move on to the next tests
       HLT                  ; should not be able to get here 
// 
// It appears that we can test and set the -equal- condition code bit. 
// Of course it is possible that the condition code bit is just always
// being set to an -ON- value.
//    
//------------------------------------------------------------------------
// Now, let-s test Load-Immediate actually putting a known value in a register.
// At the same time we can continue testing the -equal- condition code bit.   
//------------------------------------------------------------------------
// We are going to attempt the LOAD IMMEDIATE instruction - using register 0.
       .ORG   0x200         ; set the instruction address
// If this initial testing of LOAD IMMEDIATE should fail, then we will HALT
// with a program counter in the 0x2xx range.
//
// The goal of this testing is to check that we can -probably- load a value
// into a register - and we are going to try to be sure that the -equal- 
// condition code bit is not just always set on.  
// 
B30:   NOP                  ; well, here we are after condition code testing
//                  We should be able to assume register zero still contains
//                  the value zero.  
       ADD   R0,R0,R0       ; adding zero to zero should be, well, zero
       BEQ   B31            ; and we should take this branch 
       HLT                  ; stop here if we had condition code troubles
B31:   LDI   R0,#1          ; ok - let-s try to load -1- into register 0
//                  If we have succeeded, then if we add the register to itself
//                  we should have a non-zero result, and the -equal- condition code
//                  bit should now be -OFF-.  We are starting to live dangerously.
       ADD   R0,R0,R0       ; we should have 2 in reg 0, and not an -equal- cond code
       BEQ   B32            ; we should therefore -not- take this branch
//                  If we got here things are going pretty well.  We have loaded 
//                  -something- in R0, -and- determined that it is non-zero, -and-
//                  we have verified that the -equal- condition code bit is not
//                  being set on all the time.
       BRA   B40            ; branch to next section if this worked        
B32:   HLT                  ; we did not set, or test the condition code correctly
       HLT                  ; should not be able to get here 
//
// Well, it seems that we really can set and test the -equal- cond code.
// Also load-immediate will put something non-zero in a register. 
// 
//------------------------------------------------------------------------
// Now, let-s try just a tiny bit more before just going wild 
//------------------------------------------------------------------------
// We are going to attempt the LOAD IMMEDIATE instruction - using register
// one - and - then we will attempt a COMPARE and OR. 
       .ORG   0x300         ; set the instruction address
// If this testing should fail we HALT with a PC in the 0x03xx range.
//
// The goal of this testing is to check that we can use registers other 
// than zero, and we can do some arithmetic operations.
// 
B40:   NOP                  ; well, here we are after and initial load-immediate
//                  Building on our previous successes we are going to assume
//                  that register zero contains -2-.  And now we will try to load
//                  another value in another register, and do a couple comparisons
//                  and subtractions.  
       LDI   R1,#1          ; let-s try to put a -1- into register 1
       NOP                  ; nop to avoid any data hazards
       NOP                  ; nop to avoid any data hazards
       NOP                  ; nop to avoid any data hazards
       SUB   R0,R0,R1       ; try to subtract R1 from R0 - result should be 1
       BNE   B41            ; we should take this branch           
       HLT                  ; problem if we get here
B41:   NOP                  ; nop to avoid any data hazards
       SUB   R0,R0,R1       ; try to subtract R1 from R0 - result should be zero
       BNE   B42            ; so this time we should -not- take this branch   
       BEQ   B43            ; and then we should take this branch
       HLT                  ; if we got here we did not take -any- branch - very wrong
B42:   HLT                  ; if we got here we took a BNE that we should not have taken
       HLT                  ; it should be impossible to get here
B43:   NOP                  ; and if we got here we did it correctly - and R0 contains zero
       OR    R0,R0,R1       ; let-s try an -or- operation - result should be 1
       NOP                  ; nop to avoid any data hazards
       NOP                  ; nop to avoid any data hazards
       NOP                  ; nop to avoid any data hazards
       ADD   R0,R0,R0       ; and then add the result to itself - result should be 2
       BNE   B45            ; we should branch because the result should be -2-
       HLT                  ; halt if something (probably the -or-) did not work
B45:   NOP                  ; nop to avoid any data hazards
       LDI   R1,#2          ; let-s try to put a -2- into register 1
       NOP                  ; nop to avoid any data hazards
       NOP                  ; nop to avoid any data hazards
       NOP                  ; nop to avoid any data hazards
       CMP   R1,R1          ; and now let-s try a cmp - result should be equal
       BEQ   B46            ; and we should take this branch
       HLT                  ; halt if the compare failed - or did not set the cond code        
B46:   NOP                  ; nop to avoid any data hazards
       BRA   B50            ; let-s go start doing some serious testing  
//
// Well, it seems that we really can do some basic functions.
// Now let-s be reasonably sure we can use at least registers 0 thru 7
//
//------------------------------------------------------------------------
// Now, let-s try addressing all the registers 0 thru 7 
//------------------------------------------------------------------------
       .ORG   0x400         ; set the instruction address
// If this initial testing of the registers zero thru seven
// should fail, then we will HALT with a program counter in the 0x4xx range.
// 
B50:   NOP                  ; well, here we are with some basic stuff working
       LDI   R0,#1          ; load R0 with 1 
       LDI   R1,#2          ; load R1 with 2 
       LDI   R3,#3          ; load R3 with 3
       NOP                  ; nop to avoid any data hazards
       ADD   R2,R0,R1       ; load R2 with 3
       NOP                  ; nop to avoid any data hazards
       NOP                  ; nop to avoid any data hazards
       CMP   R2,R3          ; hopefully verify we loaded regs 0 thru 3
       BEQ   B51            ; should branch
       HLT                  ; halt if we cannot use the regs
B51:   LDI   R4,#4          ; load R4 with 4
       LDI   R5,#5          ; load R5 with 5
       LDI   R7,#9          ; load R7 with 9
       NOP                  ; nop to avoid any data hazards
       ADD   R6,R4,R5       ; load R6 with 9
       NOP                  ; nop to avoid any data hazards
       NOP                  ; nop to avoid any data hazards
       CMP   R6,R7          ; hopefully verify we loaded regs 4 thru 7
       BEQ   B52            ; should branch
       HLT                  ; halt if we cannot use the regs
//                  It seems we can use regs 0 thru 7 -but- not being a
//                  very trusting soul we should probably check that some
//                  wierd problem has not made it so when we address reg 4 
//                  we really get reg 0, reg 5 is really reg 1, etc.  
B52:   LDI   R0,#17         ; load R0 with 17
       LDI   R4,#2          ; load R4 with 2 (should 0 and 4 be the same this is a problem)
       LDI   R2,#3          ; load R2 with 3 
       NOP                  ; nop to avoid any data hazards
       NOP                  ; nop to avoid any data hazards
       ADD   R6,R0,R4       ; load R6 with 19     
       LDI   R7,#19         ; load R7 with 19 
       LDI   R3,#4          ; trash R7 should R3 and R7 be somehow the same
       NOP                  ; nop to avoid any data hazards
       NOP                  ; nop to avoid any data hazards
       CMP   R6,R7          ; compare R6 and R7
       BEQ   B60            ; should branch
       HLT                  ; halt if we cannot use the regs
//
// Well, it seems that we can do some basic operations.
// We have verified a -very- limited set of.....
//   branch, load-immediate, add, subtract, or, compare.
// And we seem to be able to use at least regs 0 thru 7.
// At least we seem to have the functions working that we want to 
// use to -keep-score- for the remaining tests.
//
//------------------------------------------------------------------------
// So let-s begin
//------------------------------------------------------------------------
//
// First let-s declare some data areas that we are going to be
// using later.
//
       .ORG   0x600         ; set the instruction address
WP1:   .word  0x1           ; a plus one in memory
WP2:   .word  0x2           ; a plus two in memory
WP4:   .word  0x4           ; a plus four in memory
W22P:  .word  0x001FFFFF    ; largest 22-bit positive number 2,097,151
WPM:   .word  0x7FFFFFFF    ; largest positive number
WMM:   .word  0x80000000    ; largest negative number
W22M:  .word  0xFFE00000    ; largest 22-bit negative number 2,097,152
WM2:   .word  0xFFFFFFFE    ; a minus two in memory
WM1:   .word  0xFFFFFFFF    ; a minus one in memory
W17P:  .word  0x0000FFFC    ; a 17-bit positive value
WP1X:  .word  0x1           ; another plus one in memory
       .ORG   0x640         ; set the instruction address
WX1:   .word  0x0
WX2:   .word  0x0
WX3:   .word  0x0  
//  
// And next we are going to drop some code here at a fixed known address
// that we are going to use for -jump- targets much later
//  target for first jump test
       .org   0x700         ; set the instruction address
       ADD    R10,R10,#1    ; increment an indicator
       BRA    JP1           ; and go back
// target for second jump test - we are really trying for 0720 by using
// 0710 + offset 0010.  But if the offset is not used properly we might hit 0710
       .org   0x710         ; set the instruction address
       ADD    R10,R10,#16   ; increment an indicator
       BRA    JP4           ; and go back
       .org   0x720         ; set the instruction address
       ADD    R10,R10,#2    ; increment an indicator
       BRA    JP4           ; and go back
// target for third jump test - we are really trying for 0730 by using
// 0740 - offset 0010.  But if the offset is not used properly we might hit 0740
       .org   0x730         ; set the instruction address
       ADD    R10,R10,#4    ; increment an indicator
       BRA    JP7           ; and go back
       .org   0x740         ; set the instruction address
       ADD    R10,R10,#16    ; increment an indicator
       BRA    JP7           ; and go back
// target for fourth jump test - we are really trying for 0750 by using
// -10 + offset 0760.  But if the offset is not used properly we might hit 0760
       .org   0x750         ; set the instruction address
       ADD    R10,R10,#8    ; increment an indicator
       BRA    JP10          ; and go back
       .org   0x760         ; set the instruction address
       ADD    R10,R10,#16   ; increment an indicator
       BRA    JP10          ; and go back
//  target for first jump and link test
       .org   0x780         ; set the instruction address
       ADD    R10,R10,#1    ; increment an indicator
       BRA    JL1           ; and go back
//  target for second jump and link test
       .org   0x790         ; set the instruction address
JL4:   LDI    R9,#0x07B0    ; set up jump target address
       LDI    R8,#0         ; clear link register
       NOP
       NOP
       JMPL   R8,R9         ; jump and link - to address 0x07B0 
       .org   0x7B0         ; set the instruction address
       BRA    JL5           ; and go back
//
//------------------------------------------------------------------------
// Now, let-s start some serious testing. 
//------------------------------------------------------------------------
// First - we initialize the registers we are going to use to keep
// track of just how well things are working
//
// And a couple of -notation- things.....
//      - from here on we are not going to put a comment saying why
//        nop-s are inserted - it should be obvious and understood
//      - code and comments shifted 2 positions to the right are
//        -score-keeping- code only and are not -really- part of 
//        the code which is actually performing some test 
//------------------------------------------------------------------------
       .ORG   0x800         ; set the instruction address
B60:   NOP                  ; well, here we are after the sanity checks
       SUB   R1,R1,R1       ; clear indicator register
       SUB   R2,R2,R2       ; clear indicator register
       SUB   R3,R3,R3       ; clear indicator register
       SUB   R5,R5,R5       ; scorekeeping register - nothing passed yet
       LDI   R6,#1          ; scorekeeping incrementing value 
//------------------------------------------------------------------------
// Verify all registers can be used
//
// reference registers 8, 9, 10, and 11
// reference registers 12, 13, 14, and 15
// reference registers 16, 17, 18, and 19
// reference registers 20, 21, 22, and 23
// reference registers 24, 25, 26, and 27
// reference registers 28, 29, 30, and 31
//
//   success flag - REG 1 - 00004000   
//------------------------------------------------------------------------
 RA0:    SUB   R7,R7,R7       ; clear local score
// reference registers 8, 9, 10, and 11
       LDI   R8,#1          ; load R8 with 1 
       LDI   R9,#2          ; load R9 with 2 
       LDI   R11,#3         ; load R11 with 3
       NOP         
       ADD   R10,R8,R9      ; load R10 with 3
       NOP               
       NOP              
       CMP   R10,R11        ; hopefully verify we loaded regs 8 thru 11
       BEQ   RA1            ; should branch
       BRA   RA2           
RA1:     ADD   R7,R7,R6       ; increment score  
// reference registers 12, 13, 14, and 15
RA2:   LDI   R12,#4         ; load R12 with 4
       LDI   R13,#5         ; load R13 with 5
       LDI   R15,#9         ; load R15 with 9
       NOP              
       ADD   R14,R12,R13    ; load R14 with 9
       NOP               
       NOP                
       CMP   R14,R15        ; hopefully verify we loaded regs 12 thru 15
       BEQ   RA3            ; should branch
       BRA   RA4
RA3:     ADD   R7,R7,R6       ; increment score
// reference registers 16, 17, 18, and 19
RA4:   LDI   R16,#10        ; load R16 with 10
       LDI   R17,#11        ; load R17 with 11
       LDI   R19,#21        ; load R19 with 21
       NOP               
       ADD   R18,R16,R17    ; load R18 with 21
       NOP                 
       NOP                
       CMP   R18,R19        ; hopefully verify we loaded regs 16 thru 19 
       BEQ   RA5            ; should branch
       BRA   RA6
RA5:     ADD   R7,R7,R6       ; increment score
// reference registers 20, 21, 22, and 23
RA6:   LDI   R20,#10        ; load R20 with 10
       LDI   R21,#11        ; load R21 with 11
       LDI   R23,#21        ; load R23 with 21
       NOP               
       ADD   R22,R20,R21    ; load R22 with 21
       NOP            
       NOP               
       CMP   R22,R23        ; hopefully verify we loaded regs 20 thru 23 
       BEQ   RA7            ; should branch
       BRA   RA8
RA7:     ADD   R7,R7,R6       ; increment score
// reference registers 24, 25, 26, and 27
RA8:   LDI   R24,#12        ; load R24 with 12
       LDI   R25,#13        ; load R25 with 13
       LDI   R27,#25        ; load R27 with 25
       NOP                
       ADD   R26,R24,R25    ; load R26 with 25
       NOP               
       NOP                 
       CMP   R26,R27        ; hopefully verify we loaded regs 24 thru 27 
       BEQ   RA9            ; should branch
       BRA   RA10
RA9:     ADD   R7,R7,R6       ; increment score
// reference registers 28, 29, 30, and 31
RA10:  LDI   R28,#14        ; load R28 with 14
       LDI   R29,#15        ; load R29 with 15
       LDI   R31,#29        ; load R31 with 29
       NOP                
       ADD   R30,R28,R29    ; load R30 with 29
       NOP               
       NOP            
       CMP   R30,R31        ; hopefully verify we loaded regs 28 thru 31 
       BEQ   RA11           ; should branch
       BRA   RA12
RA11:    ADD   R7,R7,R6       ; increment score
RA12:    LDI   R4,#6          ; number of groups of 4 registers tested
         LDI   R0,#0x4000     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   LI0            ; if not skip setting the indicator bit
         OR    R1,R1,R0       ; set test passed flag  
//------------------------------------------------------------------------
// Load Immediate tests - positive numbers
//  
// load-immediate - zero
// load-immediate - positive number
// load-immediate - max positive number
//
//   success flag - REG 1 - 00002000   
//------------------------------------------------------------------------
LI0:     SUB   R7,R7,R7 
// load-immediate - zero
       LDI   R8,#0          ; hopefully load (immediate) zero
       SUB   R9,R9,R9
       NOP             
       NOP               
       ADD   R8,R8,R9       ; use add to set condition code based on reg 8
       BEQ   LI1            ; branch if successful
       BRA   LI2
LI1:     ADD   R7,R7,R6       ; increment score
// load-immediate - positive number
LI2:   LDI   R8,#2          ; hopefully load (immediate) positive number                    
       NOP              
       NOP              
       ADD   R8,R8,R9       ; use add to set condition code based on reg 8
       BNE   LI3            ; branch if successful
       BRA   LI4
LI3:     ADD   R7,R7,R6       ; increment score
// load-immediate - max positive number
LI4:   LDI   R8,#2097151    ; hopefully load max immediate pos num (3FFFFF)
       NOP                
       NOP                 
       ADD   R8,R8,R9       ; use add to set condition code based on reg 8
       BNE   LI5            ; branch if successful
       BRA   LI6
LI5:     ADD   R7,R7,R6       ; increment score
LI6:     LDI   R4,#3          ; number of tests
         LDI   R0,#0x2000     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   L01            ; if not skip setting the indicator bit
         OR    R1,R1,R0       ; set test passed flag  
//------------------------------------------------------------------------
// Constants set-up
//   Ok, Load-immediate of a positive value either works, or we know about
//   the failure.  We are going to use LDI to load up a few values into
//   some registers to hopefully save just a bit of time and effort as
//   we go along here.
//
// Reg 12 - 2
// Reg 13 - 3
// Reg 14 - 4
// Reg 15 - 5
// Reg 16 - 6  
//------------------------------------------------------------------------
L01:   LDI   R12,#2         ; load a -2- in reg 12
       LDI   R13,#3         ; load a -3- in reg 13
       LDI   R14,#4         ; load a -4- in reg 14
       LDI   R15,#5         ; load a -5- in reg 15
       LDI   R16,#6         ; load a -6- in reg 16  
       SUB   R20,R20,R20    ; clear indicator register
//------------------------------------------------------------------------
// Load / Store -or- Memory Access tests
//   We start out loading the same value from two different places in 
//   memory.  If our memory addressing is messed up these two loads will
//   -probably- not result in loading the same value.
//   Note - we do -not- test the maximum address allowed by load/store.
//   This is because we do not know the implemented size of the memory when
//   we run this test so......
//
// load - positive number
// load - negative number
// store
//   
//   success flag - REG 1 - 00001000   
//------------------------------------------------------------------------
LS0:     SUB   R7,R7,R7 
// load - positive number
       LD    R8,WP1X        ; hopefully load one from memory
       LD    R9,WP1         ; hopefully load one from memory
       NOP                
       NOP                 
       SUB   R9,R8,R9       ; subtract - should give zero
       BEQ   LS2            ; branch if successful
       BRA   LS3
LS2:     ADD   R7,R7,R6       ; increment score
LS3:   ADD   R8,R8,R8       ; should give us two
       LD    R9,WP2         ; hopefully load a two from memory 
       NOP               
       NOP                
       SUB   R9,R8,R9       ; subtract - should give zero
       BEQ   LS4            ; branch if successful
       BRA   LS5
LS4:     ADD   R7,R7,R6       ; increment score
// load - negative number
LS5:   LD    R9,WM2         ; hopefully load a minus two from memory 
       NOP               
       NOP                
       ADD   R9,R8,R9       ; add - should give zero
       BEQ   LS6            ; branch if successful
       BRA   LS7
LS6:     ADD   R7,R7,R6       ; increment score
// store
LS7:   ST    WX2,R8         ; hopefully store two in memory
       SUB   R9,R9,R9       ; clear R9 just to be sure
       NOP               
       NOP              
       LD    R9,WX2         ; now load the value back from memory
       NOP                 
       NOP                
       SUB   R9,R9,R8       ; and subtract - should be zero again 
       BEQ   LS8            ; branch if successful
       BRA   LS9
LS8:     ADD   R7,R7,R6       ; increment score
LS9:     LDI   R4,#4          ; number of tests
         LDI   R0,#0x1000     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   LI10           ; if not skip setting the indicator bit
         OR    R1,R1,R0       ; set test passed flag  
//------------------------------------------------------------------------
// Load Immediate tests - negative numbers
//   Note that we have not checked out -compare- using negative values
//   yet so we probably do not want to use -compare- to check that we
//   have loaded a negative value
//
// load immediate - negative number
// load immediate - largest negative number
//     
//   success flag - REG 1 - 00000800   
//------------------------------------------------------------------------
LI10:    SUB   R7,R7,R7 
// load immediate - negative number
       LDI   R8,#-1         ; hopefully load (immediate) minus one
       LD    R9,WP1         ; load positive one 
       NOP              
       NOP                 
       ADD   R10,R8,R9      ; use add which sets the cond code to compare the values
       BEQ   LI11           ; branch if successful
       BRA   LI12             
LI11:    ADD   R7,R7,R6       ; increment score
// load immediate - largest negative number
LI12:  NOP
//     LDI   R8,#-2097152   ; hopefully load largest immediate negative num
       // assembler will not allow this value - so we do it the hard way
       // After changing the assembler the opcode for LDI is 11 and not 10
       // so had to change the line.
       // .word 0x52200000

	.word 0x5A200000
       LD    R9,W22M        ; load largest immediate negative num from memroy
       SUB   R9,R9,R8       ; subtract - result should be zero
       BEQ   LI13           ; branch if successful
       BRA   LI14             
LI13:    ADD   R7,R7,R6       ; increment score
LI14:    LDI   R4,#2          ; number of tests
         LDI   R0,#0x0800     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   LI15           ; if not skip setting the indicator bit
         OR    R1,R1,R0       ; set test passed flag  
//------------------------------------------------------------------------
// Load Immediate tests 
//   It is possible that load-immed is loading everything shifted by a 
//   bit or two.  So far our testing would not have detected that very well
//
// load immediate - verify the positive value loaded
// load immediate - verify the negative value loaded
//      
//   success flag - REG 1 - 00000400   
//------------------------------------------------------------------------
LI15:     SUB   R7,R7,R7 
// load immediate - verify the positive value loaded
       LDI   R8,#1          ; hopefully load (immediate) -one- into a register
       LD    R9,WP1         ; load -one- into a register from memory
       NOP                 
       NOP                 
       CMP   R8,R9          ; compare one and one
       BEQ   LI16           ; branch if successful
       BRA   LI17 
LI16:    ADD   R7,R7,R6       ; increment score
// load immediate - verify the negative value loaded
LI17:  LDI   R8,#-1         ; hopefully load (immediate) -minus-one- into a register
       LD    R9,WM1         ; load -minus-one- into a register from memory
       NOP                 
       NOP                
       CMP   R8,R9          ; compare minus-one and minus-one
       BEQ   LI18           ; branch if successful
       BRA   LI19
LI18:    ADD   R7,R7,R6       ; increment score
LI19:    LDI   R4,#2          ; number of tests                
         LDI   R0,#0x0400     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   CN0            ; if not skip setting the indicator bit
         OR    R1,R1,R0       ; set test passed flag      
//------------------------------------------------------------------------
// Condition code tests for the -N- bit
//   It would seem valid to argue that if an operation sets the -N- bit 
//   correctly, then the -operation- causing the bit to be set does not
//   matter so it is not necessary to test more than one instruction.  
//   However, Murphy's Law indicates that testing only one operation
//   is probably not a good idea. 
//
// set the -N- bit with a subtract
// clear the -N- bit with a subtract
// set the -N- bit with an add
// clear the -N- bit with an add
//   
//   success flag - REG 1 - 00000200   
//------------------------------------------------------------------------
CN0:     SUB   R7,R7,R7 
// set the -N- bit with a subtract
       LDI   R8,#1          ; load reg 8 with 1
       SUB   R9,R9,R9       ; load reg 9 with 0   
       NOP                
       NOP               
       SUB   R9,R9,R8       ; load reg 9 with minus 1 - hopefully set N bit
       BMI   CN1            ; branch if successful
       BRA   CN2
CN1:     ADD   R7,R7,R6       ; increment score
// clear the -N- bit with a subtract
CN2:   LDI   R8,#1          ; load reg 8 with 1 
       NOP                
       NOP               
       SUB   R9,R12,R8      ; load reg 9 with 1 - hopefully clear N (or set not-N) 
       BPL   CN3            ; branch if successful 
       BRA   CN4 
CN3:     ADD   R7,R7,R6       ; increment score
// set the -N- bit with an add
CN4:   LDI   R8,#-1         ; load reg 8 with minus 1 
       LDI   R9,#-2         ; load reg 9 with minus 2
       NOP                
       NOP               
       ADD   R9,R9,R8       ; load reg 9 with 1 - hopefully set N  
       BMI   CN5            ; branch if successful 
       BRA   CN6 
CN5:     ADD   R7,R7,R6       ; increment score
// clear the -N- bit with an add
CN6:   LDI   R8,#1          ; load reg 8 with 1
       NOP                
       NOP               
       ADD   R9,R12,R8      ; load reg 9 with 3 - hopefully clear N (or set not-N)
       BPL   CN7            ; branch if successful
       BRA   CN8
CN7:     ADD   R7,R7,R6       ; increment score
CN8:     LDI   R4,#4          ; number of tests
         LDI   R0,#0x0200     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   CZ0            ; if not skip setting the indicator bit
         OR    R1,R1,R0       ; set test passed flag  
//------------------------------------------------------------------------
// Condition code tests for the -Z- bit
//
// subtract giving zero - setting the -Z- bit
// subtract with a negative result - clearing the -Z- bit
// add giving a positive result - clearing -Z- bit
// add giving zero - setting the -Z- bit
//   
//   success flag - REG 1 - 00000100   
//------------------------------------------------------------------------
CZ0:     SUB   R7,R7,R7 
// subtract giving zero and setting the -Z- bit
       SUB   R9,R9,R9       ; load reg 9 with 0   - hopefully set Z bit
       BEQ   CZ1            ; branch if successful
       BRA   CZ2
CZ1:     ADD   R7,R7,R6       ; increment score
// subtract with a negative result - clearing the -Z- bit
CZ2:   LDI   R8,#1          ; load reg 8 with 1
       NOP
       NOP
       SUB   R9,R9,R8       ; subtract - giving a neg result and hopefully clearing the Z bit
       BNE   CZ3            ; branch if successful
       BRA   CZ4
CZ3:     ADD   R7,R7,R6       ; increment score 
// add giving a positive result and clearing -Z- bit
CZ4:   SUB   R9,R9,R9       ; clear reg 9
       NOP
       NOP
       ADD   R9,R9,R6       ; add - giving a pos result and hopefully clearing the Z bit  
       BNE   CZ5            ; branch if successful
       BRA   CZ6
CZ5:     ADD   R7,R7,R6       ; increment score 
// add giving zero and setting the -Z- bit
CZ6:   LDI   R9,#1          ; load reg 9 with 1
       LD    R8,WM1         ; load reg 8 with minus 1
       NOP
       NOP
       ADD   R9,R9,R8       ; add - giving zero result and hopefully setting Z bit 
       BEQ   CZ7            ; branch if successful
       BRA   CZ8
CZ7:     ADD   R7,R7,R6       ; increment score
CZ8:     LDI   R4,#4          ; number of tests
         LDI   R0,#0x0100     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   CV0            ; if not skip setting the indicator bit
         OR    R1,R1,R0       ; set test passed flag  
//------------------------------------------------------------------------
// Condition code tests for the -V- bit
//
// add to the biggest pos number causing an overflow and setting the V bit
// add not causing an overflow and clearing the V bit
// add to the biggest neg number causing an overflow and setting the V bit
// add not causing an overflow and clearing the V bit
// subtract from the biggest neg num causing an overflow and setting the V bit
// subtract not causing an overflow and clearing the V bit
//
//   success flag - REG 1 - 00000080   
//------------------------------------------------------------------------
CV0:     SUB   R7,R7,R7 
// add to the biggest pos number causing an overflow and setting the V bit
       LD    R8,WPM         ; load reg 8 with biggest positive number
       LDI   R9,#1          ; load reg 9 with one
       NOP                 
       NOP              
       ADD   R10,R8,R9      ; add and hopefully set V bit
       BVS   CV1            ; branch if successful
       BRA   CV2
CV1:     ADD   R7,R7,R6       ; increment score
// add not causing an overflow and clearing the V bit
CV2:   SUB   R8,R8,R12      ; subtract two
       NOP                
       NOP                
       ADD   R10,R8,R9      ; add and hopefully clear V bit (or set not-V)
       BVC   CV3            ; branch if successful
       BRA   CV4
CV3:     ADD   R7,R7,R6       ; increment score
// add to the biggest neg number causing an overflow and setting the V bit
CV4:   LD    R8,WMM         ; load reg 8 with biggest negative number
       LDI   R9,#-1         ; load reg 9 with minus one
       NOP                
       NOP                 
       ADD   R10,R8,R9      ; add and hopefully set V bit
       BVS   CV5            ; branch if successful
       BRA   CV6
CV5:     ADD   R7,R7,R6       ; increment score
// add not causing an overflow and clearing the V bit
CV6:   ADD   R8,R8,R12      ; add 2 to biggest neg number
       NOP                
       NOP                  
       ADD   R10,R8,R9      ; add and hopefully clear V bit (or set not-V)
       BVC   CV7            ; branch if successful
       BRA   CV8
CV7:     ADD   R7,R7,R6       ; increment score
// subtract from the biggest neg num causing an overflow and setting the V bit
CV8:   LD    R8,WMM         ; load reg 8 with biggest negative number
       LDI   R9,#1          ; load reg 9 with one
       NOP                
       NOP                 
       SUB   R10,R8,R9      ; subtract and hopefully set V bit
       BVS   CV9            ; branch if successful
       BRA   CV10
CV9:     ADD   R7,R7,R6       ; increment score
// subtract not causing an overflow and clearing the V bit
CV10:  ADD   R8,R8,R12      ; add 2 to biggest neg number
       NOP                
       NOP                  
       SUB   R10,R8,R9      ; subtract and hopefully clear V bit (or set not-V)
       BVC   CV11           ; branch if successful
       BRA   CV12
CV11:    ADD   R7,R7,R6       ; increment score
CV12:    LDI   R4,#6          ; number of tests
         LDI   R0,#0x0080     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   CC0            ; if not skip setting the indicator bit
         OR    R1,R1,R0       ; set test passed flag  
//------------------------------------------------------------------------
// Condition code tests for the -C- bit
//
// add causing a carry and setting the C bit      
// add not causing a carry and clearing the C bit      
//
//   success flag - REG 1 - 00000040   
//------------------------------------------------------------------------
CC0:     SUB   R7,R7,R7 
// add causing a carry/overflow and setting the C bit      
       LD    R8,WM1         ; load all ones into reg 8 
       LDI   R9,#1          ; load one into reg 9
       NOP                 
       NOP                 
       ADD   R10,R8,R9      ; add and hopefully set C bit
       BCS   CC1            ; branch if successful
       BRA   CC2
CC1:     ADD   R7,R7,R6       ; increment score
// add not causing a carry/overflow and clearing the C bit      
CC2:   SUB   R8,R8,R12      ; subtract two
       NOP                
       NOP               
       ADD   R10,R8,R9      ; add and hopefully clear C bit (or set not-C)
       BCC   CC3            ; branch if successful
       BRA   CC4
CC3:     ADD   R7,R7,R6       ; increment score
CC4:     LDI   R4,#2          ; number of tests
         LDI   R0,#0x0040     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   CP0            ; if not skip setting the indicator bit
         OR    R1,R1,R0       ; set test passed flag  
//------------------------------------------------------------------------
// ALU - COMPARE - reg-reg 
//   We have already been using compare, but we have not necessarily tested
//   it as completely as we might have.  
//   We  should maybe verify that no register is changed by a compare, and
//   we should probably verify that a not-equal result is possible - which 
//   would not be the case if say the first register was just being 
//   compared with itself. 
// 
// compare two identical positive numbers in two different registers
// verify compare did not change source registers
// compare two identical negative numbers in two different registers
// verify compare did not change source registers
// compare two different positive numbers in two different registers
// compare a register to itself
//
//   success flag - REG 2 - 00004000   
//------------------------------------------------------------------------
CP0:     SUB   R7,R7,R7 
// compare two identical positive numbers in two different registers
       LDI   R9,#2          ; load (immed) reg 9 with 2
       NOP                
       NOP                
       CMP   R12,R9         ; compare and hopefully the two are equal
       BEQ   CP1            ; branch if successful - we assume this works
       BRA   CP2
CP1:     ADD   R7,R7,R6       ; increment score
// verify compare did not change source registers
CP2:   ADD   R10,R12,R9     ; add to set reg 10 - should be 4 if regs 12 and 9 are still 2
       NOP                 
       NOP               
       SUB   R10,R10,R14    ; subtract - should be zero if compare left regs 8 and 9 unchanged
       BEQ   CP3            ; branch if successful 
       BRA   CP4
CP3:     ADD   R7,R7,R6       ; increment score
// compare two identical negative numbers in two different registers
CP4:   LD    R8,WM1         ; load reg 8 with minus 1
       LD    R9,WM1         ; load reg 9 with minus 1
       NOP               
       NOP                
       CMP   R8,R9          ; compare and hopefully the two are equal
       BEQ   CP5            ; branch if successful 
       BRA   CP6
CP5:     ADD   R7,R7,R6       ; increment score
// verify compare did not change source registers
CP6:   ADD   R10,R8,R9      ; load reg 10 - should be minus 2 if regs 8 and 9 are still -1 
       NOP                
       NOP                 
       ADD   R10,R10,R12    ; add - should be zero if compare left regs 8 and 9 unchanged  
       BEQ   CP7            ; branch if successful 
       BRA   CP8
CP7:     ADD   R7,R7,R6       ; increment score
// compare two different positive numbers in two different registers
CP8:   CMP   R12,R14        ; compare and hopefully the values are unequal
       BNE   CP9            ; branch if successful      
       BRA   CP10
CP9:     ADD   R7,R7,R6       ; increment score
// compare a register to itself
CP10:  CMP   R12,R12        ; compare reg with itself - hopefully are equal
       BEQ   CP11           ; branch if successful      
       BRA   CP12
CP11:    ADD   R7,R7,R6       ; increment score
CP12:    LDI   R4,#6          ; number of tests
         LDI   R0,#0x4000     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   CP14           ; if not skip setting the indicator bit
         OR    R2,R2,R0       ; set test passed flag  
//------------------------------------------------------------------------
// ALU - COMPARE - reg-immed 
//
// compare a register with an identical positive immediate value
// compare a register with an identical negative immediate value
// compare a register with a different positive immediate value
//
//   success flag - REG 2 - 00002000   
//------------------------------------------------------------------------
CP14:    SUB   R7,R7,R7 
// compare a register with an identical positive immediate value
       CMP   R12,#2         ; hopefully compare with an immediate 2
       BEQ   CP15           ; branch if successful 
       BRA   CP16
CP15:    ADD   R7,R7,R6       ; increment score
// compare a register witn an identical negative immediate value
CP16:  LDI   R8,#-1         ; load reg 8 - with minus 1
       NOP                 
       NOP               
       CMP   R8,#-1         ; hopefully compare with an immediate minus 1
       BEQ   CP17           ; branch if successful 
       BRA   CP18
CP17:    ADD   R7,R7,R6       ; increment score
// compare a register with a different positive immediate value
CP18:  CMP   R12,#3         ; compare with 3
       BNE   CP19           ; branch if successful      
       BRA   CP20
CP19:    ADD   R7,R7,R6       ; increment score
CP20:    LDI   R4,#3          ; number of tests
         LDI   R0,#0x2000     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   AD0            ; if not skip setting the indicator bit
         OR    R2,R2,R0       ; set test passed flag  
//------------------------------------------------------------------------
// ALU - ADD - reg-reg
//
// add positive numbers
// add a positive and a negative number
// add negative numbers
// add using the same reg for both source operands
// add using the same reg for all operands
// 
//   success flag - REG 2 - 00001000   
//------------------------------------------------------------------------
AD0:     SUB   R7,R7,R7 
// add positive numbers
       LDI   R9,#2          ; load reg 9 with 2
       NOP                
       NOP                  
       ADD   R10,R12,R9     ; hopefully add positive numbers 
       NOP                 
       NOP                
       CMP   R10,#4         ; compare result with 4
       BEQ   AD1            ; branch if successful 
       BRA   AD2
AD1:     ADD   R7,R7,R6       ; increment score
// add a positive and a negative number
AD2:   LDI   R9,#-2         ; load reg 9 with minus 2
       NOP                
       NOP                 
       ADD   R10,R12,R9     ; hopefully add pos and neg number giving zero 
       NOP                 
       NOP                
       CMP   R10,#0         ; compare result with 0
       BEQ   AD3            ; branch if successful 
       BRA   AD4
AD3:     ADD   R7,R7,R6       ; increment score
// add negative numbers
AD4:   LDI   R8,#-2         ; load reg 8 with minus 2 
       NOP                
       NOP                  
       ADD   R10,R8,R9      ; hopefully add negative numbers 
       NOP                 
       NOP                
       CMP   R10,#-4        ; compare result with minus 4
       BEQ   AD5            ; branch if successful 
       BRA   AD6
AD5:     ADD   R7,R7,R6       ; increment score
// add using the same reg for both source operands
AD6:   ADD   R10,R12,R12    ; add with both source operands the same reg
       NOP
       NOP
       CMP   R10,#4         ; compare result with 4
       BEQ   AD7
       BRA   AD8
AD7:     ADD   R7,R7,R6       ; increment score
// add using the same reg for all operands
AD8:   LDI   R8,#2          ; load reg 8 with 2
       NOP
       NOP
       ADD   R8,R8,R8
       NOP
       NOP
       CMP   R8,#4          ; compare result with 4
       BEQ   AD9
       BRA   AD10  
AD9:     ADD   R7,R7,R6       ; increment score
AD10:    LDI   R4,#5          ; number of tests
         LDI   R0,#0x1000     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   AD11           ; if not skip setting the indicator bit
         OR    R2,R2,R0       ; set test passed flag  
//------------------------------------------------------------------------
// ALU - ADD - reg-immed
//   At this point it seems logical to assert that ALU operations with
//   immediate data values have been tested, so this is not necessary.
//   Logically that seems valid.  But Murphy again says to ignore this
//   at your peril.  Clearly it is not absolutely required that one 
//   successful use of an immediate value implies all will work.      
//
// add a positive immediate value
// add a negative immediate value
//
//   success flag - REG 2 - 00000800   
//------------------------------------------------------------------------
AD11:    SUB   R7,R7,R7 
// add a positive immediate value
       ADD   R10,R12,#2     ; hopefully add a positive immediate value  
       NOP                 
       NOP                
       CMP   R10,#4         ; compare result with 4
       BEQ   AD12           ; branch if successful 
       BRA   AD13
AD12:    ADD   R7,R7,R6      ; increment score
// add a negative immediate value
AD13:  ADD   R10,R13,#-2    ; hopefully add a negative immediate value 
       NOP                 
       NOP                
       CMP   R10,#1         ; compare result with 1
       BEQ   AD14           ; branch if successful 
       BRA   AD15
AD14:    ADD   R7,R7,R6       ; increment score
AD15:    LDI   R4,#2          ; number of tests
         LDI   R0,#0x0800     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   SU0            ; if not skip setting the indicator bit
         OR    R2,R2,R0       ; set test passed flag  
//------------------------------------------------------------------------
// ALU - SUBTRACT - reg-reg
//
// subtract positive numbers
// subtract a positive and a negative number
// subtract negative numbers
// subtract using the same reg for both source operands
// subtract using the same reg for all operands
//
//   success flag - REG 2 - 00000400   
//------------------------------------------------------------------------
SU0:     SUB   R7,R7,R7 
// subtract positive numbers
       SUB   R10,R14,R12    ; hopefully subtract positive numbers 
       NOP                 
       NOP                
       CMP   R10,#2         ; compare result with 2
       BEQ   SU1            ; branch if successful 
       BRA   SU2
SU1:     ADD   R7,R7,R6       ; increment score
// subtract a positive and a negative number
SU2:   LDI   R9,#-2         ; load reg 9 with minus 2
       NOP                
       NOP                 
       SUB   R10,R14,R9     ; hopefully subtract a pos and a neg number  
       NOP                 
       NOP                
       CMP   R10,#6         ; compare result with 6
       BEQ   SU3            ; branch if successful 
       BRA   SU4
SU3:     ADD   R7,R7,R6       ; increment score
// subtract negative numbers
SU4:   LDI   R8,#-4         ; load reg 8 with minus 4 
       NOP                
       NOP                  
       SUB   R10,R8,R9      ; hopefully subtract negative numbers 
       NOP                 
       NOP                
       CMP   R10,#-2        ; compare result with minus 2
       BEQ   SU5            ; branch if successful 
       BRA   SU6
SU5:     ADD   R7,R7,R6       ; increment score
// subtract using the same reg for both source operands
SU6:   SUB   R10,R14,R14
       BEQ   SU7
       BRA   SU8 
SU7:     ADD   R7,R7,R6       ; increment score
// subtract using the same reg for all operands
SU8:   SUB   R8,R8,R8
       BEQ   SU9
       BRA   SU10
SU9:     ADD   R7,R7,R6       ; increment score
SU10:    LDI   R4,#5          ; number of tests
         LDI   R0,#0x0400     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   SU11           ; if not skip setting the indicator bit
         OR    R2,R2,R0       ; set test passed flag  
//------------------------------------------------------------------------
// ALU - SUBTRACT - reg-immed
//
// subtract a positive immediate value
// subtract a negative immediate value
//
//   success flag - REG 2 - 00000200   
//------------------------------------------------------------------------
SU11:    SUB   R7,R7,R7 
// subtract a positive immediate value
       SUB   R10,R12,#1     ; hopefully subtract a pos immediate value  
       NOP                 
       NOP                
       CMP   R10,#1         ; compare result with 1
       BEQ   SU12           ; branch if successful 
       BRA   SU13
SU12:    ADD   R7,R7,R6       ; increment score
// subtract a negative immediate value
SU13:  SUB   R10,R12,#-2    ; hopefully subtract a neg immediate value 
       NOP                 
       NOP                
       CMP   R10,#4         ; compare result with 4
       BEQ   SU14           ; branch if successful 
       BRA   SU15
SU14:    ADD   R7,R7,R6       ; increment score
SU15:    LDI   R4,#2          ; number of tests
         LDI   R0,#0x0200     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   AN0            ; if not skip setting the indicator bit
         OR    R2,R2,R0       ; set test passed flag  
//------------------------------------------------------------------------
// At this point we are making a simplifying assumption.  The preceeding 
// tests have tested the ability to fetch and store the proper operands 
// for the ALU operations.  No longer will we test things like using the
// same register for both source operands.  
//------------------------------------------------------------------------
// ALU - AND - reg-reg 
//
// and resulting in zero
// and resulting in non-zero
// verify and does not set the condition code 
// 
//   success flag - REG 2 - 00000100   
//------------------------------------------------------------------------
AN0:     SUB   R7,R7,R7 
// and resulting in zero
       AND   R10,R14,R12    ; hopefully and resulting in zero 
       NOP                 
       NOP   
       CMP   R10,#0         ; compare results with zero             
       BEQ   AN1            ; branch if successful 
       BRA   AN2
AN1:     ADD   R7,R7,R6       ; increment score
// and resulting in non-zero
AN2:   AND   R10,R14,R16    ; hopefully and resulting in non-zero 
       NOP                 
       NOP   
       CMP   R10,#4         ; compare results with 4             
       BEQ   AN3            ; branch if successful 
       BRA   AN4
AN3:     ADD   R7,R7,R6       ; increment score
// verify and does not set the condition code 
AN4:   CMP   R14,#6         ; set a not-equal contition
       AND   R10,R12,R14    ; and - result is zero, but cond code should not be set
       NOP
       NOP 
       BNE   AN5            ; branch if successful - cond code not set
       BRA   AN6
AN5:     ADD   R7,R7,R6       ; increment score
AN6:     LDI   R4,#3          ; number of tests
         LDI   R0,#0x0100     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   AN7            ; if not skip setting the indicator bit
         OR    R2,R2,R0       ; set test passed flag  
//------------------------------------------------------------------------
// ALU - AND - reg-immed 
//
// and immediate using a positive immediate value
// and immediate using a negative immediate value
// 
//   success flag - REG 2 - 00000080   
//------------------------------------------------------------------------
AN7:     SUB   R7,R7,R7 
// and immediate using a positive immediate value
       AND   R10,R14,#2     ; hopefully and resulting in zero 
       NOP                 
       NOP   
       CMP   R10,#0         ; compare results with zero             
       BEQ   AN8            ; branch if successful 
       BRA   AN9
AN8:     ADD   R7,R7,R6       ; increment score
// and immediate using a negative immediate value
AN9:   LDI   R9,#-1         ; load reg 9 with minus 1
       NOP                
       NOP                  
       AND   R10,R9,#-1     ; hopefully and resulting in zero 
       NOP                 
       NOP   
       CMP   R10,#-1        ; compare results with minus 1             
       BEQ   AN10           ; branch if successful 
       BRA   AN11
AN10:    ADD   R7,R7,R6       ; increment score
AN11:    LDI   R4,#2          ; number of tests
         LDI   R0,#0x0080     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   OR0            ; if not skip setting the indicator bit
         OR    R2,R2,R0       ; set test passed flag  
//------------------------------------------------------------------------
// ALU - OR - reg-reg
//
// or with overlapping bits
// or with all bits exclusive to one operand
// verify or does not set the condition code 
// 
//   success flag - REG 2 - 00000040   
//------------------------------------------------------------------------
OR0:     SUB   R7,R7,R7 
// or with overlapping bits
       OR    R10,R14,R16    ; or with some bits common to both operands
       NOP
       NOP
       CMP   R10,R16        ; compare result with 6 
       BEQ   OR1            ; branch if successful
       BRA   OR2
OR1:     ADD   R7,R7,R6       ; increment score
// or with all bits exclusive to one operand
OR2:   OR    R10,R12,R14    ; or with bits exclusive
       NOP
       NOP
       CMP   R10,R16        ; compare result with 6
       BEQ   OR3            ; branch if successful
       BRA   OR4  
OR3:     ADD   R7,R7,R6       ; increment score
// verify or does not set the condition code
OR4:   CMP   R10,R10        ; compare - setting -equal- result 
       OR    R10,R12,R14    ; or giving a non-zero result
       NOP
       BEQ   OR5            ; -z- cond code should still be set
       BRA   OR6
OR5:     ADD   R7,R7,R6       ; increment score
OR6:     LDI   R4,#3          ; number of tests
         LDI   R0,#0x0040     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   OR7            ; if not skip setting the indicator bit
         OR    R2,R2,R0       ; set test passed flag  
//------------------------------------------------------------------------
// ALU - OR - reg-immed 
//
// or immediate using a positive immediate value
// or immediate using a negative immediate value
//
//   success flag - REG 2 - 00000020   
//------------------------------------------------------------------------
OR7:     SUB   R7,R7,R7
// or immediate using a positive immediate value
       OR    R10,R14,#2     ; or 4 and an immediate 2
       NOP
       NOP
       CMP   R10,R16        ; compare result with 6
       BEQ   OR8            ; branch if successful
       BRA   OR9    
OR8:     ADD   R7,R7,R6       ; increment score
// or immediate using a negative immediate value
OR9:   OR    R10,R12,#-4    ; or 2 and an immediate minus 4
       NOP
       NOP
       CMP   R10,#-2        ; compare results with minus 2
       BEQ   OR10           ; branch if successful
       BRA   OR11 
OR10:    ADD   R7,R7,R6       ; increment score
OR11:    LDI   R4,#2          ; number of tests
         LDI   R0,#0x0020     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   NT0            ; if not skip setting the indicator bit
         OR    R2,R2,R0       ; set test passed flag  
//------------------------------------------------------------------------
// ALU - NOT  
//
// not resulting in no bits left on
// not resulting in some bits left
// verify not does not change the condition code
//
//   success flag - REG 2 - 00000010   
//------------------------------------------------------------------------
NT0:     SUB   R7,R7,R7
// not resulting in no bits left on
       LDI   R8,#-1         ; load a minus 1 - FFFFFFFF
       NOP
       NOP
       NOT   R10,R8         ; not a minus 1 - should result in zero
       NOP
       NOP
       CMP   R10,#0         ; compare result with zero
       BEQ   NT1            ; branch if successful
       BRA   NT2     
NT1:     ADD   R7,R7,R6       ; increment score
// not resulting in some bits left
NT2:   NOT   R10,R12        ; not a plus 2 - should result in minus 3
       NOP
       NOP
       CMP   R10,#-3        ; compare result with minus 3
       BEQ   NT3            ; branch if successful
       BRA   NT4
NT3:     ADD   R7,R7,R6       ; increment score
// verify not does not change the condition code
NT4:   CMP   R10,R10        ; compare - setting -equal- result 
       NOT   R10,R12        ; not resulting in a non-zero result
       BEQ   NT5            ; branch if cond code still unchanged
       BRA   NT6
NT5:     ADD   R7,R7,R6       ; increment score
NT6:     LDI   R4,#3          ; number of tests
         LDI   R0,#0x0010     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   CX0            ; if not skip setting the indicator bit
         OR    R2,R2,R0       ; set test passed flag  
//------------------------------------------------------------------------
// BGE and BLT Condition code tests 
//
// test BGE and BLT with N^V 
// test BGE and BLT with ^N^V   
// test BGE and BLT with ^NV   
// test BGE and BLT with NV   
//  
//   success flag - REG 3 - 00004000   
//------------------------------------------------------------------------
CX0:     SUB   R7,R7,R7
// test BGE and BLT with N^V 
       LDI   R8,#0          ; clear reg 8
       LD    R9,WM1         ; load reg 9 with minus 1
       NOP
       NOP  
       ADD   R9,R9,R8       ; add zero - but this will set cond code N and ^V  
       BGE   CX2            ; should -not- branch if successful
       BLT   CX1            ; branch if successful
       BRA   CX2 
CX1:     ADD   R7,R7,R6       ; increment score
// test BGE and BLT with ^N^V   
CX2:   ADD   R9,R8,R8       ; add giving zero - set cond code ^N and ^V
       BLT   CX4            ; should -not- branch if successful
       BGE   CX3            ; branch if successful
       BRA   CX4
CX3:     ADD   R7,R7,R6       ; increment score
// test BGE and BLT with ^NV
CX4:   LD    R8,WMM         ; load max negative number
       NOP
       NOP
       ADD   R9,R8,R8       ; add two max neg numbers - giving zero - set cond code ^N and V
       BGE   CX6            ; should -not- branch if successful
       BLT   CX5            ; branch if successful
       BRA   CX6           
CX5:     ADD   R7,R7,R6       ; increment score
// test BGE and BLT with NV   
CX6:   LD    R8,WPM         ; load max positive number
       NOP
       NOP
       ADD   R9,R8,R8       ; add giving neg result - set cond code N and V
       BLT   CX8            ; should -not- branch if successful
       BGE   CX7            ; branch if successful
       BRA   CX8
CX7:     ADD   R7,R7,R6       ; increment score
CX8:     LDI   R4,#4          ; number of tests
         LDI   R0,#0x4000     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   CX10           ; if not skip setting the indicator bit
         OR    R3,R3,R0       ; set test passed flag  
//------------------------------------------------------------------------
// BGT and BLE Condition code tests 
//
//   (test BGT and BLE with ZN^V -but- Z and N are mutually exclusive) 
// test BGT and BLE with Z^N^V   
// test BGT and BLE with Z^NV   
//   (test BGT and BLE with ZNV  -but- Z and N are mutually exclusive)   
// test BGT and BLE with ^ZN^V 
// test BGT and BLE with ^Z^N^V   
// test BGT and BLE with ^Z^NV    
// test BGT and BLE with ^ZNV   
//  
//   success flag - REG 3 - 00002000   
//------------------------------------------------------------------------
CX10:    SUB   R7,R7,R7
// test BGT and BLE with Z^N^V   
       LDI   R8,#0          ; clear reg 8
       NOP
       NOP
       ADD   R9,R8,R8       ; add giving zero - set cond code Z, ^N and ^V
       BGT   CX12           ; should -not- branch if successful
       BLE   CX11           ; branch if successful
       BRA   CX12
CX11:    ADD   R7,R7,R6       ; increment score
// test BGT and BLE with Z^NV   
CX12:  LD    R8,WMM         ; load max negative number
       NOP
       NOP
       ADD   R9,R8,R8       ; add two max neg numbers - giving zero - set cond code Z, ^N and V
       BGT   CX14           ; should -not- branch if successful
       BLE   CX13           ; branch if successful
       BRA   CX14           
CX13:    ADD   R7,R7,R6       ; increment score
// test BGT and BLE with ^ZN^V 
CX14:  LDI   R8,#0          ; clear reg 8
       LD    R9,WM1         ; load reg 9 with minus 1
       NOP
       NOP  
       ADD   R9,R9,R8       ; add zero - but this will set cond code ^Z, N and ^V  
       BGT   CX16           ; should -not- branch if successful
       BLE   CX15           ; branch if successful
       BRA   CX16 
CX15:    ADD   R7,R7,R6       ; increment score
// test BGT and BLE with ^Z^N^V   
CX16:  LDI   R8,#1          ; load reg 8 with 1
       NOP
       NOP  
       ADD   R9,R8,R8       ; add giving 2 - set cond code ^Z, ^N and ^V
       BLE   CX18           ; should -not- branch if successful
       BGT   CX17           ; branch if successful
       BRA   CX18
CX17:    ADD   R7,R7,R6       ; increment score
// test BGT and BLE with ^Z^NV    
CX18:  LDI   R8,#-2         ; load reg 8 with minus 2
       LD    R9,WMM         ; load reg 9 with max neg number 
       NOP
       NOP  
       ADD   R9,R8,R8       ; add giving 2 - set cond code ^Z, ^N and V
       BGT   CX20           ; should -not- branch if successful
       BLE   CX19           ; branch if successful
       BRA   CX20 
CX19:    ADD   R7,R7,R6       ; increment score
// test BGT and BLE with ^ZNV   
CX20:  LDI   R8,#2          ; load reg 8 with 2
       LD    R9,WPM         ; load reg 9 with max pos number 
       NOP
       NOP  
       ADD   R9,R8,R8       ; add giving 2 - set cond code ^Z, N and V
       BLE   CX22           ; should -not- branch if successful
       BGT   CX21           ; branch if successful
       BRA   CX22
CX21:    ADD   R7,R7,R6       ; increment score
CX22:    LDI   R4,#6          ; number of tests
         LDI   R0,#0x2000     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   PT0            ; if not skip setting the indicator bit
         OR    R3,R3,R0       ; set test passed flag  
//------------------------------------------------------------------------
// ALU pass-thru tests
//   Some operations pass data thru the ALU, and may even use the ALU
//   for some operation, yet the condition code is -not- supposed to
//   be altered by these operations. 
//
// load immediate - verify cond code unchanged
// load - verify cond code unchanged
// do logical op - verify cond code unchanged
//  
//   success flag - REG 3 - 00001000   
//------------------------------------------------------------------------
PT0:     SUB   R7,R7,R7
// load immediate - verify cond code unchanged
       SUB   R8,R8,R8       ; set reg 8 to zero - and set -Z- cond code
       NOP
       NOP
       LDI   R8,#1          ; load reg 8 - should leave cond code unchanged
       NOP
       NOP
       BEQ   PT1            ; branch if successful
       BRA   PT2
PT1:     ADD   R7,R7,R6       ; increment score
// load - verify cond code unchanged
PT2:   SUB   R8,R8,#2       ; set reg 8 to minus 1 - and set -N- cond code
       NOP
       NOP
       LD    R8,WPM         ; load max pos number - should leave cc unchanged
       NOP
       NOP
       BMI   PT3            ; branch if successful
       BRA   PT4 
PT3:     ADD   R7,R7,R6       ; increment score
// do logical op - verify cond code unchanged
PT4:   SUB   R8,R8,R8       ; set reg 8 to zero - and set -Z- cond code
       LDI   R9,#1          ; load reg 9 with 1
       NOP
       NOP
       OR    R8,R8,R9       ; or - set reg 8 to 1 - leave cond code unchanged
       BEQ   PT5            ; branch if successful
       BRA   PT6 
PT5:     ADD   R7,R7,R6       ; increment score
PT6:     LDI   R4,#3          ; number of tests
         LDI   R0,#0x1000     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   LX0            ; if not skip setting the indicator bit
         OR    R3,R3,R0       ; set test passed flag  
//------------------------------------------------------------------------
// Load Indexed
//   The last of these tests is an attempt to verify the use of the 17-bit
//   immediate address.  If the offset value is something like
//   0 1xxx xxxx xxxx xxxx then using this as a 16-bit value would result
//   in a negative value.  However, if this is treated as a 17-bit value
//   then it is a positive offset. 
//   WARNING - if this offset is treated as a 16-bit number - which means
//   it is going to be -negative- then we will address memory at some
//   negative address.  It might be difficult to predice what might 
//   happen if this is attempted.    
//
// load using an offset of zero
// load using a positive offset
// load using a negative offset
//  
//   success flag - REG 3 - 00000800  
//------------------------------------------------------------------------
LX0:     SUB   R7,R7,R7
// load using an offset of zero
       LDI   R8,#0x0604     ; load address of a pos 2 in memory
       NOP
       NOP
       LDX   R9,R8          ; load 2 from address 0604
       NOP
       NOP
       CMP   R9,#2          ; check for the expected value of 2
       BEQ   LX1            ; branch if successful
       BRA   LX2
LX1:     ADD   R7,R7,R6       ; increment score
// load using a positive offset
LX2:   LDX   R9,R8,#4       ; load with a positive offset value
       NOP
       NOP
       CMP   R9,#4          ; check for the expected value of 4
       BEQ   LX3            ; branch if successful
       BRA   LX4
LX3:     ADD   R7,R7,R6       ; increment score
// load using a negative offset
LX4:   LDX   R9,R8,#-4      ; load with a negative offset value
       NOP
       NOP
       CMP   R9,#1          ; check for the expected value of 1
       BEQ   LX5            ; branch if successful
       BRA   LX6
LX5:     ADD   R7,R7,R6       ; increment score
LX6:     LDI   R4,#3          ; number of tests
         LDI   R0,#0x0800     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   SX0            ; if not skip setting the indicator bit
         OR    R3,R3,R0       ; set test passed flag  
         ADD   R20,R20,R6     ; increment special indicator
//------------------------------------------------------------------------
// Store Indexed
//
// store using an offset of zero
// store using a positive offset
// store using a negative offset
//  
//   success flag - REG 3 - 00000400  
//------------------------------------------------------------------------
SX0:     SUB   R7,R7,R7
// store using an offset of zero
       LDI   R8,#0x0644     ; load address of a word in memory
       LDI   R9,#2          ; load a 2 into reg 9
       NOP
       NOP
       STX   R8,R9          ; store 2 in address 0644
       LD    R10,WX2
       NOP
       NOP
       CMP   R10,#2         ; check for the expected value of 2
       BEQ   SX1            ; branch if successful
       BRA   SX2
SX1:     ADD   R7,R7,R6       ; increment score
// store using a positive offset
SX2:   STX   R8,#4,R9       ; store 2 in address 0644 plus 4
       LD    R10,WX3
       NOP
       NOP
       CMP   R10,#2         ; check for the expected value of 2
       BEQ   SX3            ; branch if successful
       BRA   SX4
SX3:     ADD   R7,R7,R6       ; increment score
// store using a negative offset
SX4:   STX   R8,#-4,R9      ; store 2 in address 0644 minus 4
       LD    R10,WX1
       NOP
       NOP
       CMP   R10,#2         ; check for the expected value of 2
       BEQ   SX5            ; branch if successful
       BRA   SX6
SX5:     ADD   R7,R7,R6       ; increment score
SX6:     LDI   R4,#3          ; number of tests
         LDI   R0,#0x0400     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   BC0            ; if not skip setting the indicator bit
         OR    R3,R3,R0       ; set test passed flag  
//------------------------------------------------------------------------
// Branch - next instruction
//   it is not easy to prove this works.  We can assert that it looks
//   very much like this worked ok.  If the branch to other positive
//   offsets is working ok, then we can probably deduce that we have
//   a pretty decent test for branch to next.  (We risk some data 
//   hazards, but since the code should not be reached anyway....)   
//
// branch to the very next instruction 
//
//   success flag - REG 3 - 00000200   
//------------------------------------------------------------------------
BC0:     SUB   R7,R7,R7
// branch to the very next instruction 
       LDI   R10,#0         ; clear a counter
       LDI   R11,#0    
       BRA   BC1            ; branch to a branch
       ADD   R10,R10,#10    ; increment counter - should not get here
       ADD   R10,R10,#20    ; increment counter - should not get here
       ADD   R10,R10,#40    ; increment counter - should not get here
BC1:   ADD   R10,R10,#1     ; increment counter to 1 - should branch to here
       BRA   BC2            ; branch to the very next instruction
BC2:   ADD   R11,R11,#2     ; increment counter to 2 - should branch to here
       BRA   BC3            ; branch onward 
       ADD   R10,R10,#10    ; increment counter - should not get here
       ADD   R10,R10,#20    ; increment counter - should not get here     
       ADD   R10,R10,#40    ; increment counter - should not get here
BC3:   CMP   R10,#1         ; check that we got to instruction BC1
       BNE   BC4            ; branch if there was a problem
       CMP   R11,#2         ; check that we got to instruction BC2
       BNE   BC4            ; branch if there was a problem    
         ADD   R7,R7,R6       ; increment score
BC4:     LDI   R4,#1          ; number of tests
         LDI   R0,#0x0200     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   BC10           ; if not skip setting the indicator bit
         OR    R3,R3,R0       ; set test passed flag  
//------------------------------------------------------------------------
// Branch - negative offset  
//
// branch with a negative offset
//
//   success flag - REG 3 - 00000100   
//------------------------------------------------------------------------
BC10:    SUB   R7,R7,R7
// branch with a negative offset
       LDI   R9,#2          ; initialize loop indicator 
       LDI   R10,#0         ; clear an indicator register
       LDI   R11,#0         ; clear an indicator register
       BRA   BC12           ; branch ahead - skip some instructions
       ADD   R10,R10,R12    ; add 2 to indicator - should not get here
BC11:  ADD   R11,R11,R12    ; add 2 to indicator
       BRA   BC14           ; go check results
BC12:  SUB   R9,R9,#1       ; count times we got here (should be just one)
       BEQ   BC14           ; break out if we detect a loop here         
       BRA   BC11           ; branch with negative offset
BC14:  CMP   R9,#1          ; check for one time thru the code
       BNE   BC15           ; branch if a problem
       CMP   R10,#0         ; check that we did not go back too far
       BNE   BC15           ; branch if a problem
       CMP   R11,#2         ; check that we branched back far enough
       BNE   BC15           ; branch if a problem
         ADD   R7,R7,R6       ; increment score
BC15:    LDI   R4,#1          ; number of tests
         LDI   R0,#0x0100     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   JP0            ; if not skip setting the indicator bit
         OR    R3,R3,R0       ; set test passed flag         
//------------------------------------------------------------------------
// Jump Indirect  
//
// jump with a zero offset
// jump with a positive offset
// jump with a negative offset
//
//   success flag - REG 3 - 00000080   
//------------------------------------------------------------------------
JP0:     SUB   R7,R7,R7 
// jump with a zero offset
       LDI   R10,#0         ; clear an indicator register
       LDI   R9,#0x0700     ; load target instruction address - 0x0700
       JMP   R9             ; jump to target - 0x0700
       ADD   R10,R10,#16    ; we should never get here
JP1:   NOP
       NOP
       CMP   R10,#1         ; check that we reached our target 
       BEQ   JP2            ; branch if successful
       BRA   JP3
JP2:     ADD   R7,R7,R6       ; increment score
// jump with a positive offset
JP3:   LDI   R10,#0         ; clear an indicator register
       LDI   R9,#0x0710     ; load target area address - 0710
       JMP   R9,#0x0010     ; jump to target instruction - 0x0720
       ADD   R10,R10,#16    ; we should never get here
JP4:   NOP
       NOP
       CMP   R10,#2         ; check that we reached our target 
       BEQ   JP5            ; branch if successful
       BRA   JP6
JP5:     ADD   R7,R7,R6       ; increment score
// jump with a negative offset
JP6:   LDI   R10,#0         ; clear an indicator register
       LDI   R9,#0x0740     ; load target area addr plus some extra - 0x0740   
       JMP   R9,#-16        ; jump to target instruction - 0x0730
       ADD   R10,R10,#16    ; we should never get here
JP7:   NOP
       NOP
       CMP   R10,#4         ; check that we reached our target 
       BEQ   JP8            ; branch if successful
       BRA   JP9
JP8:     ADD   R7,R7,R6       ; increment score
JP9:     LDI   R4,#3          ; number of tests
         LDI   R0,#0x0080     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   JL0            ; if not skip setting the indicator bit
         OR    R3,R3,R0       ; set test passed flag  
         ADD   R20,R20,R6     ; increment special indicator
//------------------------------------------------------------------------
// Jump And Link
//
// verify jump does not alter reg 0 as a -link- register
// verify that the link register is set properly
//  
//   success flag - REG 3 - 00000040   
//------------------------------------------------------------------------
JL0:     SUB   R7,R7,R7 
// verify jump does not alter reg 0 as a -link- register
//   ok, you can argue this is a plain -jump- test, but it also involves -link-
//   and it did not seem helpful to fail the jump tests if this failed 
       LDI   R0,#0          ; clear an indicator register
       LDI   R10,#0         ; clear an indicator register
       LDI   R9,#0x0780     ; load target instruction address - 0x0780
       JMP   R9             ; jump to target - 0x0780
       ADD   R10,R10,#16    ; we should never get here
JL1:   NOP
       NOP
       CMP   R0,#0          ; verify reg 0 is unchanged 
       BEQ   JL2            ; branch if successful
       BRA   JL3
JL2:     ADD   R7,R7,R6       ; increment score
// verify that the link register is set properly
JL3:   NOP
       BRA   JL4            ; go to known address
JL5:   NOP                  ; this is the return point
       CMP   R8,#0x07A4     ; was the link address set correctly
       BEQ   JL6
       BRA   JL7
JL6:     ADD   R7,R7,R6       ; increment score
JL7:     LDI   R4,#2          ; number of tests
         LDI   R0,#0x0040     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   DH0            ; if not skip setting the indicator bit
         OR    R3,R3,R0       ; set test passed flag  
//------------------------------------------------------------------------
// Now we need to address -data- -hazards-.  This is certainly a test
// done because we explicitly know one internal design feature of the
// hardware under test.   Until now the testing has carefully avoided
// altering a register and then using it again -too-soon-.  Now we 
// will intentionally do exactly that.  This testing will be broken up
// into several pieces just so that the test reporting is not reduced
// to a case of all-or-nothing.
//------------------------------------------------------------------------
//------------------------------------------------------------------------
// hazard recently altered registers 
//
// use a reg as source operand 2 the second instruction after the reg is set
// use a reg as source operand 1 the second instruction after the reg is set
//     
//   success flag - REG 3 - 00000020   
//------------------------------------------------------------------------
DH0:     SUB   R7,R7,R7 
// use a reg as source operand 2 the second instruction after the reg is set
       LDI   R8,#1          ; load reg with a known value
       NOP
       NOP
       LDI   R9,#10         ; load reg with a known value
       NOP
       ADD   R10,R8,R9      ; use value loaded 2 instructions ago
       NOP
       NOP
       CMP   R10,#11        ; was result of add as expected
       BEQ   DH1            ; branch if successful
       BRA   DH2  
DH1:     ADD   R7,R7,R6       ; increment score
// use a reg as source operand 1 the second instruction after the reg is set
DH2:   LDI   R9,#20         ; load reg with a known value
       NOP
       ADD   R10,R9,R8      ; use value loaded 2 instructions ago
       NOP
       NOP
       CMP   R10,#21        ; was result of add as expected
       BEQ   DH3            ; branch if successful
       BRA   DH4  
DH3:     ADD   R7,R7,R6       ; increment score
DH4:     LDI   R4,#2          ; number of tests
         LDI   R0,#0x0020     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   DH5            ; if not skip setting the indicator bit
         OR    R3,R3,R0       ; set test passed flag
//------------------------------------------------------------------------
// hazard recently altered registers 
//
// use a reg as source operand 2 immediately after the reg is set
// use a reg as source operand 1 immediately after the reg is set
//     
//   success flag - REG 3 - 00000010   
//------------------------------------------------------------------------
DH5:     SUB   R7,R7,R7 
// use a reg as source operand 2 immediately after the reg is set
       LDI   R9,#10         ; load reg with a known value
       ADD   R10,R8,R9      ; use value loaded 2 instructions ago
       NOP
       NOP
       CMP   R10,#11        ; was result of add as expected
       BEQ   DH6            ; branch if successful
       BRA   DH7  
DH6:     ADD   R7,R7,R6       ; increment score
// use a reg as source operand 1 immediately after the reg is set
DH7:   LDI   R9,#20         ; load reg with a known value
       ADD   R10,R9,R8      ; use value loaded 2 instructions ago
       NOP
       NOP
       CMP   R10,#21        ; was result of add as expected
       BEQ   DH8            ; branch if successful
       BRA   DH9  
DH8:     ADD   R7,R7,R6       ; increment score
DH9:     LDI   R4,#2          ; number of tests
         LDI   R0,#0x0010     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   DH10           ; if not skip setting the indicator bit
         OR    R3,R3,R0       ; set test passed flag
//------------------------------------------------------------------------
// hazard recently altered registers 
//
// both operands of an instruction use the same recently altered source reg
// alter a reg with consecutive instructions and then use the reg as a
//   source operand
// alter a reg with consecutive instructions and then use the reg as 
//   both source operands
// two operands of an instruction use different, but both recently altered
//   regs as source operands  
//     
//   success flag - REG 3 - 00000008   
//------------------------------------------------------------------------
DH10:    SUB   R7,R7,R7 
// both operands of an instruction use the same recently altered source reg
       LDI   R9,#15         ; load reg with a known value
       ADD   R10,R9,R9      ; use value loaded 2 instructions ago
       NOP
       NOP
       CMP   R10,#30        ; was result of add as expected
       BEQ   DH11            ; branch if successful
       BRA   DH12  
DH11:    ADD   R7,R7,R6       ; increment score
// alter a reg with consecutive instructions and then use the reg as a
//   source operand
DH12:  LDI   R9,#25         ; load reg with a known value
       LDI   R9,#35         ; and load the reg again
       ADD   R10,R9,R8      ; use the correct value just loaded 
       NOP
       NOP
       CMP   R10,#36        ; was result of add as expected
       BEQ   DH13           ; branch if successful
       BRA   DH14  
DH13:    ADD   R7,R7,R6       ; increment score
// alter a reg with consecutive instructions and then use the reg as 
//   both source operands
DH14:  LDI   R9,#7          ; load reg with a known value
       LDI   R9,#15         ; and load the reg again
       ADD   R10,R9,R9      ; use the correct value just loaded 
       NOP
       NOP
       CMP   R10,#30        ; was result of add as expected
       BEQ   DH15           ; branch if successful
       BRA   DH16  
DH15:    ADD   R7,R7,R6       ; increment score
// two operands of an instruction use different, but both recently altered
//   regs as source operands  
DH16:  LDI   R8,#21         ; load reg with a known value
       LDI   R9,#31         ; and load the reg again
       ADD   R10,R8,R9      ; use the correct value just loaded 
       NOP
       NOP
       CMP   R10,#52        ; was result of add as expected
       BEQ   DH17           ; branch if successful
       BRA   DH18  
DH17:    ADD   R7,R7,R6       ; increment score
DH18:    LDI   R4,#4          ; number of tests
         LDI   R0,#0x0008     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   DH20           ; if not skip setting the indicator bit
         OR    R3,R3,R0       ; set test passed flag
//------------------------------------------------------------------------
// hazard recently loaded registers 
//
// use a reg as a source operand the second instruction after the reg is loaded
// use a reg as a source operand immediately after the reg is loaded
// load a reg with consecutive instructions and then use the reg as a
//   source operand
// both operands of an instruction use the same recently loaded source reg
// two operands of an instruction use different, but both recently loaded
//   regs as source operands  
//     
//   success flag - REG 3 - 00000004   
//------------------------------------------------------------------------
DH20:    SUB   R7,R7,R7 
// use a reg as a source operand the second instruction after the reg is set
       LDI   R8,#1          ; load reg with a known value
       NOP
       NOP
       LD    R9,WP2         ; load reg with a known value
       NOP
       ADD   R10,R8,R9      ; use value loaded 2 instructions ago
       NOP
       NOP
       CMP   R10,#3         ; was result of add as expected
       BEQ   DH21           ; branch if successful
       BRA   DH22  
DH21:    ADD   R7,R7,R6       ; increment score
// use a reg as a source operand immediately after the reg is loaded
DH22:  LD    R9,WP4         ; load reg with a known value
       ADD   R10,R9,R8      ; use value just loaded 
       NOP
       NOP
       CMP   R10,#5         ; was result of add as expected
       BEQ   DH23           ; branch if successful
       BRA   DH24  
DH23:    ADD   R7,R7,R6       ; increment score
// load a reg with consecutive instructions and then use the reg as a
//   source operand
DH24:  LD    R9,WP1         ; load reg with a known value
       LD    R9,WP2         ; load reg with a known value
       ADD   R10,R8,R9      ; use value just loaded 
       NOP
       NOP
       CMP   R10,#3         ; was result of add as expected
       BEQ   DH25           ; branch if successful
       BRA   DH26  
DH25:    ADD   R7,R7,R6       ; increment score
// both operands of an instruction use the same recently loaded source reg
DH26:  LD    R9,WP1         ; load reg with a known value
       LD    R9,WP4         ; load reg with a known value
       ADD   R10,R9,R9      ; use value just loaded 
       NOP
       NOP
       CMP   R10,#8         ; was result of add as expected
       BEQ   DH27           ; branch if successful
       BRA   DH28  
DH27:    ADD   R7,R7,R6       ; increment score
// two operands of an instruction use different, but both recently loaded
//   regs as source operands  
DH28:  LD    R9,WP1         ; load reg with a known value
       LD    R8,WP2         ; load reg with a known value
       ADD   R10,R8,R9      ; use value just loaded 
       NOP
       NOP
       CMP   R10,#3         ; was result of add as expected
       BEQ   DH29           ; branch if successful
       BRA   DH30  
DH29:    ADD   R7,R7,R6       ; increment score
DH30:    LDI   R4,#5          ; number of tests
         LDI   R0,#0x0004     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   XXX            ; if not skip setting the indicator bit
         OR    R3,R3,R0       ; set test passed flag
//------------------------------------------------------------------------
// really risky tests
//   If things do not go really well, these tests have the potential to 
//   reference negative memory addresses, or even try to branch to 
//   negative memory addresses.  Therefore, these tests will -not- be 
//   attempted unless.....
//    - all previous load/store - indexed tests were successful
//    - all previous jump/jump-link tests were successful
//    - -most- all other tests were successful  
//
// ldx using a pos offset which has a non-zero next-most-significant bit
// jump when the register contains a negative value
//     
//   success flag - REG 3 - 00000002   
//------------------------------------------------------------------------
RR0:     SUB   R7,R7,R7
         CMP   R20,#2         ; were all -indexed- and -jump tests successful
         BNE   XXX            ; if not - skip these tests
         LDI   R8,#100
         NOP
         NOP
         SUB   R8,R5,R8       ; number of successful tests more than 100  
         BMI   XXX            ; branch if less than 100 tests successful         
// ldx using a pos offset which has a non-zero next-most-significant bit
//   this could be dangerous if the immediate value is interpreted as a 16-bit
//   value.  If this happens we have a -negative- offset and we will end 
//   up with a negative address
       LDI   R8,#0x0604     ; load address of a pos 2 in memory
       LD    R10,W17P       ; load 17-bit positive value (00FFFC)
       NOP
       NOP
       SUB   R8,R8,R10      ; subtract from address 0604 - giving neg addr
       NOP
       NOP
       LDX   R9,R8,#0x00FFFC ; load from 0604 ((0604-FFFC)+FFFC) 
       NOP
       NOP
       CMP   R9,#2          ; check for the expected value of 2
       BEQ   RR1            ; branch if successful
       BRA   XXX
RR1:     ADD   R7,R7,R6       ; increment score
// jump when the register contains a negative value
//   this could be dangerous if say the register is being used and the 
//   offset value ignored.  So..... we will only attempt this test if
//   all the previous jump tests were successful
       LDI   R10,#0         ; clear an indicator register
       LDI   R9,#-16        ; load jump target address of -16 or 0xFF..F0
       JMP   R9,#0x0760     ; jump to target instruction -0x0010 + 0x0760 (0x0750) 
       ADD   R10,R10,#16    ; we should never get here
JP10:  NOP
       NOP
       CMP   R10,#8         ; check that we reached our target 
       BEQ   RR3            ; branch if successful
       BRA   RR4
RR3:     ADD   R7,R7,R6       ; increment score
RR4:     LDI   R4,#2          ; number of tests
         LDI   R0,#0x0002     ; load successful completion bit flag
         ADD   R5,R5,R7       ; increment total score
         CMP   R7,R4          ; did all tests pass
         BNE   XXX            ; if not skip setting the indicator bit
         OR    R3,R3,R0       ; set test passed flag  
//------------------------------------------------------------------------
// It is hard to believe but it seems that we are done
//------------------------------------------------------------------------
XXX:   HLT                  ; wow - finished
//------------------------------------------------------------------------
//
// Check regs 1, 2, and 3 for status about which groups of tests passed and failed
// Check reg 5 for a count of the number of tests passed
//  
//------------------------------------------------------------------------