This is where the BIN Hackers and definition junkies discuss the inner workings of the EEC code and hardware. General tuning questions do not go here. Only technical/hardware-specific/code questions and discussions belong here.

Section C of the eec-iv pocket reference guide gives the operation of the instruction and the object code format, not the assembly language format. I prefer to see and use assembly code in the style of the Intel macro assemblers for their 8xxx processors (obviously disassembly listings give specific mnemonics for instructions rather than the generic mnemonics you can utilise to cover several instructions when using an assembler ).

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

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

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

quick update - I'm having a total nightmare with getting the signed and unsigned subr names right....one of those things that looks quite simple, but
across the various binaries it shows up the holes in my logic. The original setup didn't always work either.

I might go back to a 'data scan' method (looking for sign bit changes...).

I have fixed a few things, added back the command to specify 'special lookup' subroutines, reworked CARRY (again),
fixed a couple of other bugs I found when testing.

There's probably still more bugs to find, but I ran this on all my collection of bins.
Apart from known issues (like subroutine arguments) I think I fixed what was reported so far.
Autonames sort of work....

I've been wondering if should type up a 'SAD for non IT people' guide, with some basics on how binary/hex numbers work, some basics of CPU core, and assembler code basics and then explaining what the 1D and 2D lookups do, interrupts and so on...

Would this help anyone here ??

(No I'm NOT going to call it an "Idiot's Guide" somehow I always thought that was demeaning "Total Newbie" would be better....)

Last edited by tvrfan on Mon Apr 09, 2018 4:57 pm, edited 1 time in total.

I know a primer like that couldn't hurt. As I mentioned in my PM to you (and others), I'll need something like this to concoct up simple machine code to do data-marshalling between the EEC and MBus. Today, I bought the hardware I'll need to get an EEC's J3 MBus pins connected to a Beaglebone.

Edit:
I split the posts related to the EEC Primer document out into it's own thread. Here's the link:EEC Primer Doc

... Yes, I like that. How about adding bits affected by ands and ors'.

Unless I am misunderstanding, if you add a symbol name for a single bit SYM 1234 "flagx" : T 5 (would be bit 5)
then ANDs and ORs which are immediates (i.e. fixed values) should already be converted to 'flagx = 0;' or 'flagx = 1;'

Unless I am misunderstanding, if you add a symbol name for a single bit SYM 1234 "flagx" : T 5 (would be bit 5)
then ANDs and ORs which are immediates (i.e. fixed values) should already be converted to 'flagx = 0;' or 'flagx = 1;'

You might just have me nailed there, it is something I have not done yet.
How would that work out with scratch registers?

I can honestly say I completely missed INC and DEC as possibly being used with carry ... DUH ! Stupid error.

Flag/bit names - again another slight catch 22 here - and an idea...

For scratch registers (typically R30 - R40 seem to be used a lot), sometimes it's several flags at once,
and sometimes its a genuine number mask (like for example A/D reads are only 10 bits). So where the AND and OR is done
with an immediate value, SAD looks for any bit names.
I was wondering whether to have a TYPE of variable as 'FLAGS' to define this behaviour, but it still wouldn't work for scratch/temp registers.

BUT also have in the background the idea that you can declare data types and they would be tracked/transferable.....
- i.e Types
Plain Word, Byte, Flags (word,byte) Nothing. perhaps signed/unsigned ?

IOtime (word/byte. long?) autoconvert to millisecs, but would require clock speed, unless I can spot a way to get it from code. (Timers subroutine?)
ADvalue (word), auto convert to volts 0-5
RPM (word) auto convert (divide by 4) all are x4 as far as I can see. seems to be a standard
Temp ? trickier, as Euro tend to use C and US ones use F (well, A9L does, don't know if later ones went metric)

After that so far I see other variables don't have a common calibration, but perhaps could declare them .
or perhaps allow the idea of a divisor/multiplier factor on all SYM (only on tables/funcs to 3.05) which get used in print phase ?

The the idea that when you do R34 = R36, or R34 = [1234] the TYPE (or divisor) of the variable gets transferred to R34 as well as its value.

But then I can't decide if it's too complex....what if two different types get added ?

Anyway I need to sort out in-line subroutine arguments first.... But ideas welcome, if I can do it (relatively) easily.

here's a section of AA code to show flag names, HSI sample has no named flags

Fixed the 'add and Carry' comment for JC/JNC not including the CY flag
Removed incorrect debug info in subroutine listings (which caused the Prenc and comma problem)
Added comment for JC/JNC after INC or DEC opcodes.

So uh, I did a thing.... Testing it here in a second
The image is blurry AF, stupid Linux. Anyways, tvrfan your code is so good it's portable to Android.

Well, from what techie stuff I read, Android is supposed to have a Linux kernel/core !
I am trying to keep the code 'clean' C/C++, so a certified compiler should make it runnable on any environment which has the standard 'C' libraries.
Code does expect at least a 32 bit compiler and environment.
As per Github, I use exactly the same code for Win32 and Linux 64.

Good to know though ..... see the advert .....!!! SAD NOW RUNS ON MOBILE DEVICES !!!

In CARD SAD misses code from 0x4510 to 0x459E.
The dog chasing its tail seems to be R34 = 4510 and push(R34)

Happens in A9L as well.

This is down to the way SAD chops up the code into 'blocks' and then links them with a tree structure.
It sees no link between the load and the push/ret.
When I put code in to handle this, it also produces lots of invalid address hits, which often messes up the disassembly.
I haven't solved it yet...