I'll add my 2c worth in case it helps any
for SAD disassembler, I do often 'swop' the conditional logic over to produce a 'C' like setup with brackets
CMP R32, R34;
JNE 12345; if (R34 = R32) {
.... }
which 'reverses' the jump (i.e. only enters brackets if jump is NOT taken)
So this can add confusion - when I'm debugging I typically go back to the actual opcode to check...
I was unhappy with carry as it didn't look right, but left it to fix other stuff.
Format - I copied the 8096 format, which Ford also use in their handbook.
For an easy rule of thumb for reading , I treat the operands as BACKWARDS, like this - - -
AD3W, R32, R34, R36 is R36 = R34 + R32
AD3W, op1, op2, op3 is op3 = op2 + op1
This is also useful to remember that only the FIRST operand in the opcode (= last one in pseudo source) can be indexed or indirect or immediate - R32 position in the above example. I think this is always right, but may be an exception in there (I think of STW as an LDW with ops swopped).
In the same way, the WRITE operand (the one that gets written to) is always the same as the number of operands, or none, except for STW and STB.
You do have to be careful with CMP and SUB, which according to Ford handbook and 8096 is op3 or op2 = op2 - op1. This means that op1 > op2 will CLEAR carry, because it's using the BORROW setup. So therefore
Code: Select all
SUB R32, R34 R34 = R34 - R32;
JLT 12345 if (R32 > R34) goto 12345; or.... if (R34 < 0) goto 12345;
JNC 12345 if (unsigned) (R32 > R34) goto 12345; as JNC doesn't check the NEG flag, but JLT does..
That's my understanding , and I admit I didn't check operand order in the carry question !
Shift-wise, I can see JC/JNC being useful for a LEFT shift, as it signifies an overflow in the shift, but I can't honestly see any use for a JC/JNC after a right shift, because it doesn't really mean anything useful. If however, 8061 didn't have a JB/JNB (like the 8096 !) then it can be used to do the equivalent bit check logic.
And yes, I agree with Bob in that the actual arithmetic engine itself doesn't care about 2 or 3 operands, it still does same operation, just changes where result gets stored. And also same for CMP which is a SUB with no result store.
Sticky ? I can see why this is provided, but not seen it used in EEC stuff - that makes sense to me, as the whole point is to reduce complex calcs and replace with approximated lookup functions/tables instead ... so sticky bit is redundant.
And lastly a programmers note about nested if-thens etc, which I haven't got to work in SAD (yet)
if (conditiona) {
if (conditionb) {
<code> } }
is of course if (conditiona AND conditionb) but its reverse is if (! conditiona OR ! conditionb) where ! means NOT, as in C code
and if (condition) { } else { } actually looks like this in code (addresses are just an example )
3000 CMP A, B
3002 JNE 3018
3004 ... # if {...}
3016 JMP 3040
3018 ... # else {...}
3040....
where goto is last operand of the 'if' block, so it jumps over the 'else' , and the original if jumps to the 'else'
But when they get mixed up with loops and others gets a bit tricky to sort out.....
Please correct me if you find an error in here ! Thanks.