Someone recently asked me to comment on this subject as a software developer
OK here goes. It helps to look at the source-code posted by
mdccode5150 as even though its for ME17 the Project Configuration hasn't really changed all that much from ME7.x days. The reason why you don't get a match is related to "code generation" and the fact they change compilers and C167 GNU CC based compilers got better at code optimization as they get newer. Its also conditionally compiled for different projects...
First lets look at the macro's used (C language) to define bits..
#define b_MASK (uint8)0xFFu
#define SETBIT_B(basis,bitpos) ((basis) |= ((uint8)1 << (bitpos)), TRUE)
#define CLRBIT_B(basis,bitpos) ((basis) &= b_MASK - ((uint8)1 << (bitpos)), FALSE)
#define GETBIT_B(basis,bitpos) (((basis) & ((uint8)1 << (bitpos))) != 0)
#define PUTBIT_B(basis,bitpos,val) ((val) ? SETBIT_B(basis,bitpos) : CLRBIT_B(basis,bitpos))
And here's a custom macro specific to a given bit (auto generated by some scripts)
#define SET_B_autget ((bits |= (uint8)1u << 0))
#define CLR_B_autget ((bits &= (uint8)(((uint8) b_MASK) - ((uint8)1u << 0))))
#define GET_B_autget ((bits & ((uint8)1u << 0)) != (uint8)0u)
#define PUT_B_autget(val) ((val) ? SET_B_autget : CLR_B_autget)
Here's some snippet. Lets look at CWKONFZ1 on ME7.3 projects.
Note: Different projects defined bits settings to mean different things!!
/******************************************************************/
/** CWKONFZ1 Config. Vehicle */
/******************************************************************/
PUT_B_autget ( GETBIT_B(KW_CWKONFZ1,0) );
PUT_B_mt ( GETBIT_B(KW_CWKONFZ1,1) );
PUT_B_cvt ( GETBIT_B(KW_CWKONFZ1,2) );
PUT_B_f1getr ( GETBIT_B(KW_CWKONFZ1,3) );
//PUT_B_xxx ( GETBIT_B(KW_CWKONFZ1,4) );
//PUT_B_xxx ( GETBIT_B(KW_CWKONFZ1,5) );
PUT_B_asrfz ( GETBIT_B(KW_CWKONFZ1,6) );
PUT_B_4wd ( GETBIT_B(KW_CWKONFZ1,7) );
So these macro's are generating code... All they are doing is retrieving given bits from a CW byte and setting a given bit in another memory location. Its those other memory locations which are checked at runtime to see if the bits are set or not set by individual functions. These Control words simply set bits. Nothing more.
When you run this through one of the earlier compilers (as used on ME7.3) it spits out pretty crappy un-optimized code which looks something like this...
get_cw_sy_flags+0: F3 F8 1F 00 movb rl4, CWKONFZ1 ; CWKONFZ1 : Codewort fnr Konfiguration Fahrzeug [PROKON]
get_cw_sy_flags+4 69 81 andb rl4, #1 ; #0x01 = .bit 0
get_cw_sy_flags+6 3A 88 88 36 bmovn USR0, Z
get_cw_sy_flags+A 4A 88 00 63 bmov PROKON_FD00.3, USR0 ; b_autget
get_cw_sy_flags+E F3 F8 1F 00 movb rl4, CWKONFZ1 ; CWKONFZ1 : Codewort fnr Konfiguration Fahrzeug [PROKON]
get_cw_sy_flags+12 69 82 andb rl4, #2 ; #0x02 = .bit 1
get_cw_sy_flags+14 3A 88 88 36 bmovn USR0, Z
get_cw_sy_flags+18 4A 88 01 66 bmov PROKON_FD02.6, USR0 ; b_mt
get_cw_sy_flags+1C F3 F8 1F 00 movb rl4, CWKONFZ1 ; CWKONFZ1 : Codewort fnr Konfiguration Fahrzeug [PROKON]
get_cw_sy_flags+20 69 84 andb rl4, #4 ; #0x04 = .bit 2
get_cw_sy_flags+22 3A 88 88 36 bmovn USR0, Z
get_cw_sy_flags+26 4A 88 00 64 bmov PROKON_FD00.4, USR0 ; b_cvt
get_cw_sy_flags+2A F3 F8 1F 00 movb rl4, CWKONFZ1 ; --
get_cw_sy_flags+2E 67 F8 08 00 andb rl4, #8 ; #0x08 = .bit 3
get_cw_sy_flags+32 3A 88 88 36 bmovn USR0, Z
get_cw_sy_flags+36 4A 88 00 68 bmov PROKON_FD00.8, USR0 ; B_f1getr: Condition F1-gearbox (electronic clutch)
get_cw_sy_flags+3A F3 F8 1F 00 movb rl4, CWKONFZ1 ; CWKONFZ1 : Codewort fnr Konfiguration Fahrzeug [PROKON]
get_cw_sy_flags+3E 67 F8 40 00 andb rl4, #40h ; '@' ; #0x40 = .bit 6
get_cw_sy_flags+42 3A 88 88 36 bmovn USR0, Z
get_cw_sy_flags+46 4A 88 00 62 bmov PROKON_FD00.2, USR0 ; b_asrfz
get_cw_sy_flags+4A F3 F8 1F 00 movb rl4, CWKONFZ1 ; CWKONFZ1 : Codewort fnr Konfiguration Fahrzeug [PROKON]
get_cw_sy_flags+4E 67 F8 80 00 andb rl4, #80h ; 'Ç' ; #0x80 = .bit 7
get_cw_sy_flags+52 3A 88 88 36 bmovn USR0, Z
get_cw_sy_flags+56 4A 88 00 60 bmov PROKON_FD00.0, USR0 ; b_4wd [ ** NOT REFERENCED ANYWHERE ** ]
Lets look at just one of these generated code's for a moment...
get_cw_sy_flags+4A F3 F8 1F 00 movb rl4, CWKONFZ1 ; CWKONFZ1 : Codewort fur Konfiguration Fahrzeug [PROKON]
get_cw_sy_flags+4E 67 F8 80 00 andb rl4, #80h ; 'Ç' ; #0x80 = .bit 7
get_cw_sy_flags+52 3A 88 88 36 bmovn USR0, Z
get_cw_sy_flags+56 4A 88 00 60 bmov PROKON_FD00.0, USR0 ; b_4wd
Lets remove 'code generator specifics' to make the signature a little bit more 'generic'...
get_cw_sy_flags+4A F3 F? ?? ?? movb r??, ?????? ; CWKONFZ1 : Codewort fur Konfiguration Fahrzeug [PROKON]
get_cw_sy_flags+4E 67 F? 80 00 andb r??, #80h ; '#0x80 = .bit 7
get_cw_sy_flags+52 3A ?? ?? ?? bmovn ?????, ??
get_cw_sy_flags+56 4A ?? ?? ?? bmov ?????.??, ????; b_4wd
Here we've removed the 'registers' F? ... and then the physical referenced address, e.g F3F8 1F00 becomes F3F?
?
This is because F3 is the opcode for 'moveb' F8 is references 'rl4' and finally 1F00 is (byte swapped to 001F is referencing map region +1F). so 0x810000+0x1F which is 0x81001F or file offset 0x1001F in this specific case...
67 is the opcode for 'andb' again 'register' F8 is referencing 'rl4' and then 80 00 becomes (byte swapped) 00 80 or 0x0080 which is the 7th bit...
So the mask to detect this exact field is "F3 F? ?? ?? 67 F? 80 00 3A ?? ?? ?? 4A ?? 00 ??"
And here's code generation on a different GCC compiled with large memory model.
D7 40 06 02 extp #206h, #1
F3 F2 C5 01 movb rl1, CWKONFZ1
8A F1 02 00 jb r1.0, _bit_clear
6F 88 _bit_set: bset USR0
0D 01 jmpr cc_UC, _cont
6E 88 _bit_clear: bclr USR0
3A 88 00 60 _cont: bmovn PROKON_Flags_FD00.0, USR0
You can see logically it does exactly the same as the original macros. The difference here is the extp #1 so it explicitly calls out that this is at segment 0x206. If you understand these opcodes (see C167 instruction manual) you'll see that means its at address 0x206*0x4000 (each segment is 0x4000 in size). So that equates to an address offset of 0x818000 + 0x01CF, so in this particular case its referencing 0x81801CF, or file offset 0x181CF.
However this is NOT really the best way to detect these fields using crude 'static signature detection' because you'd literally have to detect all the different compiler variants used as the code is pretty different every time... why? Its because its FAR far better to find the byte and bit offset which actually USES these bit-fields and search for the bits referenced backwards from that... So in this case find all references to code using FD00.0.... Search for the signature which uses of one of them and extract the bit and byte offset used there and that will de-reference the memory set by the project bit setups. In this way its possible to fully automate detection of all prokon bits in a rom you've never even seen before..
Same technique works on MED9 (PowerPC) and ME17 (tricore) just with difference instructions. Any questions just ask..