How to detect 8061 vs 8065 from binary
-
wwhite
- Posts: 413
- Joined: 2021 Feb 16, 15:53
- Location: Victoria, BC, Canada
- Vehicle Information: 1994 Flarside, XLT, 351w E4OD
SD48b, Quarter Horse, Burn2
How to detect 8061 vs 8065 from binary
I am curious how the disassemblers determine 8061 code vs 8065?
I'm hoping for a very concrete way of detecting.
Binary size is easy, but some 8065 have single bank rom of 64k/56k.
Is it pattern matching, or something specific in the disassemble?
I'm hoping for a very concrete way of detecting.
Binary size is easy, but some 8065 have single bank rom of 64k/56k.
Is it pattern matching, or something specific in the disassemble?
-
decipha
- Posts: 6471
- Joined: 2021 Feb 15, 12:23
- Location: Metairie, LA
- Vehicle Information: Work Truck
'25 F-150 5L
Re: How to detect 8061 vs 8065 from binary
yeah, on the homepage click on write ups and disassembly, you can tell by the first few bytes of that bank if its a multi bank file and which bank it is.
-
jsa
- Posts: 445
- Joined: 2021 Feb 16, 15:46
- Location: Australia
- Vehicle Information: 95 Escort RS Cosworth
2.0 YBP
CARD / QUIK / COSY / ANTI
GHAJ0
SMD-190 / SMD-490 EEC-IV
Binary Editor
ForDiag
Re: How to detect 8061 vs 8065 from binary
I can't speak to the disassembler specifics.
Some examples of differences;
Some examples of differences;
Code: Select all
8061 8065
8 Interrupt Vectors 40 Interrupt Vectors
NPTRS at 82020 NPTRS at 82060
NCALS at 82021 NCALS at 82061
Calibration pointers 82022 to 82031 Calibration pointers 82062 to 82071
16 Bit Clock 24 Bit Clock
Stack R10 Stack R20
-
wwhite
- Posts: 413
- Joined: 2021 Feb 16, 15:53
- Location: Victoria, BC, Canada
- Vehicle Information: 1994 Flarside, XLT, 351w E4OD
SD48b, Quarter Horse, Burn2
Re: How to detect 8061 vs 8065 from binary
Yeah, so, I've been working on a pure software emulator, wanting to determine 8061 vs 8065 from the binary.
But, I don't think it is realistically possible, it can be done like what @decipha and @jsa mentioned above, and thank you both for that info.
If your emulating something with a GUI, you let the user choose the hardware to run on. That makes it easy, you either select 8061 or 8065. I might have to also allow user to select the number of banks.
Think I will just let the user select the hardware, as there are too many bins that are different. Can then test bins on different hardware as well.
But, I don't think it is realistically possible, it can be done like what @decipha and @jsa mentioned above, and thank you both for that info.
If your emulating something with a GUI, you let the user choose the hardware to run on. That makes it easy, you either select 8061 or 8065. I might have to also allow user to select the number of banks.
Think I will just let the user select the hardware, as there are too many bins that are different. Can then test bins on different hardware as well.
-
jsa
- Posts: 445
- Joined: 2021 Feb 16, 15:46
- Location: Australia
- Vehicle Information: 95 Escort RS Cosworth
2.0 YBP
CARD / QUIK / COSY / ANTI
GHAJ0
SMD-190 / SMD-490 EEC-IV
Binary Editor
ForDiag
Re: How to detect 8061 vs 8065 from binary
Yeah, always seems to be another brumby bin thay fouls up automatic methods.
User choice is easy, if the user does not know, the info can be retrieved from SAD output files.
User choice is easy, if the user does not know, the info can be retrieved from SAD output files.
-
tvrfan
- Posts: 130
- Joined: 2023 Oct 22, 22:13
- Location: New Zealand
- Vehicle Information: Several Kit cars, Ford (Europe), EEC-IV, TVR Vixen, Tasmin (a.k.a Wedge),
Engine - Cologne 2.8 V6 (Europe) catch code 'AA'.
EEC_Disassembler https://github.com/tvrfan/EEC-IV-disassembler
Re: How to detect 8061 vs 8065 from binary
Just spotted this - so - how SAD decides 8061/8065, and how banks are detected from a binary file.
The hardware requirement (as in manuals) says that every bank MUST have interrupt vectors set up. 8061 has these from 2010-201f, and 8065 has these from 2010 - 205e (in each bank). These are 16 bit word pointers, and must be valid pointers to code (i.e. 2010-0xffff or 2060-0xffff) . The FIRST thing that an interrupt handler has to do is to save the CPU state, which is a PUSHP instruction. So each word pointer MUST point to a PUSHP. That's the logic. So if you do this in a loop, you can check if there are 10 or 40 valid vectors. Done.
(why PUSHP ? - can explain separately...)
In real life however, the vector pointer can point to another jump, or a DI or NOP (as a time waster/safety). So it's a little bit more complicated. Some multibanks have the actual handler code only in one bank, so their interrupt vectors actually point to a ROMBNK, JUMP. When you follow this jump, you will then get to the PUSHP (or DI, NOP followed by PUSHP). This trick also allows SAD to decide which bank is which by analyzing the bank number in the ROMBANK.
An 'ignore interrupt handler also, will just do a RET or RETEI, so that's in the possible opcodes list too.
Also only ONE bank has a real jump at 0xB2000 (B = bank no). Why? well if CPU starts code at 0x82000, then it MUST jump over the interrupt vectors. So that's a way to get bank 8 identified. Other banks are typically loopstop jumps.
No, it doesn't always work but it's damn good overall. The vectors even appear in the data bank (bank 1). The only exception I've found so far is FM20M06 which BREAKS FORD'S OWN HARDWARE RULES. It doesn't have interrupt vectors set in its data bank (1), but then it has no code at all in bank 1, which many binaries do.
The code which does this is available in SAD in github.
EDIT - Added some details and fixed an ambiguous part.
The hardware requirement (as in manuals) says that every bank MUST have interrupt vectors set up. 8061 has these from 2010-201f, and 8065 has these from 2010 - 205e (in each bank). These are 16 bit word pointers, and must be valid pointers to code (i.e. 2010-0xffff or 2060-0xffff) . The FIRST thing that an interrupt handler has to do is to save the CPU state, which is a PUSHP instruction. So each word pointer MUST point to a PUSHP. That's the logic. So if you do this in a loop, you can check if there are 10 or 40 valid vectors. Done.
(why PUSHP ? - can explain separately...)
In real life however, the vector pointer can point to another jump, or a DI or NOP (as a time waster/safety). So it's a little bit more complicated. Some multibanks have the actual handler code only in one bank, so their interrupt vectors actually point to a ROMBNK, JUMP. When you follow this jump, you will then get to the PUSHP (or DI, NOP followed by PUSHP). This trick also allows SAD to decide which bank is which by analyzing the bank number in the ROMBANK.
An 'ignore interrupt handler also, will just do a RET or RETEI, so that's in the possible opcodes list too.
Also only ONE bank has a real jump at 0xB2000 (B = bank no). Why? well if CPU starts code at 0x82000, then it MUST jump over the interrupt vectors. So that's a way to get bank 8 identified. Other banks are typically loopstop jumps.
No, it doesn't always work but it's damn good overall. The vectors even appear in the data bank (bank 1). The only exception I've found so far is FM20M06 which BREAKS FORD'S OWN HARDWARE RULES. It doesn't have interrupt vectors set in its data bank (1), but then it has no code at all in bank 1, which many binaries do.
The code which does this is available in SAD in github.
EDIT - Added some details and fixed an ambiguous part.
-
tvrfan
- Posts: 130
- Joined: 2023 Oct 22, 22:13
- Location: New Zealand
- Vehicle Information: Several Kit cars, Ford (Europe), EEC-IV, TVR Vixen, Tasmin (a.k.a Wedge),
Engine - Cologne 2.8 V6 (Europe) catch code 'AA'.
EEC_Disassembler https://github.com/tvrfan/EEC-IV-disassembler
Re: How to detect 8061 vs 8065 from binary
So building on previous.
check file size. Scan the binary in small steps, for a jump followed by the interrupt vectors. (i.e. a temporary mapped 0x2000 for jump, and vectors at 0x2010 onwards). When you find a match, that's a bank start. Repeat until end of file. Not all bins have full banks, so have to scan every 0x1000 or so and can't assume a bank is always 64k.
Then depending upon how many banks found.....
This is in 'find_banks' routine in Core.cpp part of SAD.
check file size. Scan the binary in small steps, for a jump followed by the interrupt vectors. (i.e. a temporary mapped 0x2000 for jump, and vectors at 0x2010 onwards). When you find a match, that's a bank start. Repeat until end of file. Not all bins have full banks, so have to scan every 0x1000 or so and can't assume a bank is always 64k.
Then depending upon how many banks found.....
This is in 'find_banks' routine in Core.cpp part of SAD.
-
tvrfan
- Posts: 130
- Joined: 2023 Oct 22, 22:13
- Location: New Zealand
- Vehicle Information: Several Kit cars, Ford (Europe), EEC-IV, TVR Vixen, Tasmin (a.k.a Wedge),
Engine - Cologne 2.8 V6 (Europe) catch code 'AA'.
EEC_Disassembler https://github.com/tvrfan/EEC-IV-disassembler
Re: How to detect 8061 vs 8065 from binary
Decipha - have you got a better method than the SAD one ?? I'm interested as you say "first few bytes" Sure, when you look at it by eye, the bank START and 61/65 is obvious, but bank number too ?? I'm interested if you've found a reliable shortcut !!
-
decipha
- Posts: 6471
- Joined: 2021 Feb 15, 12:23
- Location: Metairie, LA
- Vehicle Information: Work Truck
'25 F-150 5L
Re: How to detect 8061 vs 8065 from binary
yeah its at the beginning of my disassembly write up for how to identify the bank order
hasnt failed me yet
hasnt failed me yet
-
tvrfan
- Posts: 130
- Joined: 2023 Oct 22, 22:13
- Location: New Zealand
- Vehicle Information: Several Kit cars, Ford (Europe), EEC-IV, TVR Vixen, Tasmin (a.k.a Wedge),
Engine - Cologne 2.8 V6 (Europe) catch code 'AA'.
EEC_Disassembler https://github.com/tvrfan/EEC-IV-disassembler
Re: How to detect 8061 vs 8065 from binary
WOW. How can it be THAT simple !! I did a stack of messing around in code and mapping to do everything from first principles, as per what I posted above, and then track the rombank prefix jumps to get a matrix of which bank is which, and you managed to do it by checking a few bytes.... kudos and respect.
My only feedback is FM20M06 doesn't work with this method either, for same reason - no interrupt vectors in bank 1. But it seems to be a real oddball bin.
Seriously, I am truly surprised that most multibanks have EXACTLY the same interrupt vector and NOP,DI combinations across their bank starts, and your pattern match method also says that interrupt handlers are always in bank 0 ? OK. To me this means all the multibanks must have been originally built with a kind of 'base template' approach ? I guess that makes sense with a compile build, but I never spotted it ...
[....DAMN....and other swear words]