//
// 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
//
//------------------------------------------------------------------------