a bit more poking about today...
It looks like we have the device validation code sequence:
Code:
sub_12E8E0+11A ; ---------------------------------------------------------------------------
sub_12E8E0+11A
sub_12E8E0+11A loc_12E9FA: ; CODE XREF: sub_12E8E0+106↑j
sub_12E8E0+11A sub.w e5, e5 ; Subtract binary
sub_12E8E0+11C
sub_12E8E0+11C loc_12E9FC: ; CODE XREF: sub_12E8E0+E2↑j
sub_12E8E0+11C ; sub_12E8E0+112↑j
sub_12E8E0+11C mov.w e5, e5 ; Move data
sub_12E8E0+11E bne loc_12E9C4:8 ; Branch if not equal
sub_12E8E0+120 mov.b r5l, r0l ; Move data
sub_12E8E0+122 extu.w r0 ; Extend as unsigned
sub_12E8E0+124 extu.l er0 ; Extend as unsigned
sub_12E8E0+126 mov.b @(1:16,er6), r1l ; Move data
sub_12E8E0+12A and.b #0x80, r1l ; Logical AND
sub_12E8E0+12C mov.b @er6, r2l ; Move data
sub_12E8E0+12E and.b #0x7F, r2l ; Logical AND
sub_12E8E0+130 or.b r2l, r1l ; Logical OR
sub_12E8E0+132 mov.b r1l, @(0x41E864:32,er0) ; Move data
sub_12E8E0+13A mov.l #8, er0 ; Move data
sub_12E8E0+140 push.l er0 ; Push data on stack
sub_12E8E0+144 mov.l #aIomega, er1 ; Move data
sub_12E8E0+14A mov.l er6, er0 ; Move data
sub_12E8E0+14C adds #4, er0 ; Add with sign extension
sub_12E8E0+14E adds #4, er0 ; Add with sign extension
sub_12E8E0+150 jsr unk_400228:24 ; Jump to subroutine
sub_12E8E0+154 adds #4, sp ; Add with sign extension
sub_12E8E0+156 mov.b r0l, r0l ; Move data
sub_12E8E0+158 bne loc_12EA5C:8 ; Branch if not equal
sub_12E8E0+15A mov.l #8, er0 ; Move data
sub_12E8E0+160 push.l er0 ; Push data on stack
sub_12E8E0+164 mov.l #aIomega_0, er1 ; Move data
sub_12E8E0+16A mov.l er6, er0 ; Move data
sub_12E8E0+16C adds #4, er0 ; Add with sign extension
sub_12E8E0+16E adds #4, er0 ; Add with sign extension
sub_12E8E0+170 jsr unk_400228:24 ; Jump to subroutine
sub_12E8E0+174 adds #4, sp ; Add with sign extension
sub_12E8E0+176 mov.b r0l, r0l ; Move data
sub_12E8E0+178 beq loc_12EBB4:16 ; Branch if equal
sub_12E8E0+17C
sub_12E8E0+17C loc_12EA5C: ; CODE XREF: sub_12E8E0+158↑j
sub_12E8E0+17C mov.l #3, er0 ; Move data
sub_12E8E0+182 push.l er0 ; Push data on stack
sub_12E8E0+186 mov.l #aZip, er1 ; Move data
sub_12E8E0+18C mov.l er6, er0 ; Move data
sub_12E8E0+18E add.l #0x10, er0 ; Add binary
sub_12E8E0+194 jsr unk_400228:24 ; Jump to subroutine
sub_12E8E0+198 adds #4, sp ; Add with sign extension
sub_12E8E0+19A cmp.b #1, r0l ; Compare
sub_12E8E0+19C bne loc_12EAA4:8 ; Branch if not equal
sub_12E8E0+19E mov.b r5l, r0l ; Move data
sub_12E8E0+1A0 extu.w r0 ; Extend as unsigned
sub_12E8E0+1A2 extu.l er0 ; Extend as unsigned
sub_12E8E0+1A4 mov.b #1, r1l ; Move data
sub_12E8E0+1A6 mov.b r1l, @(0x41E8AC:32,er0) ; Move data
sub_12E8E0+1AE mov.b r5l, r0l ; Move data
sub_12E8E0+1B0 bsr sub_12F40E:16 ; Branch to subroutine
sub_12E8E0+1B4 mov.b r5l, r0l ; Move data
sub_12E8E0+1B6 bsr sub_12F482:16 ; Branch to subroutine
sub_12E8E0+1BA mov.b r5l, r0l ; Move data
sub_12E8E0+1BC bsr sub_12F6B0:16 ; Branch to subroutine
sub_12E8E0+1C0 jmp loc_12EBB4:24 ; Jump
sub_12E8E0+1C4 ; ---------------------------------------------------------------------------
sub_12E8E0+1C4
Lets break this down (i'd welcome someone to check my homework):
1. Initial Status Setup:
Code:
mov.b r5l, r0l ; Get device ID/index
extu.w r0 ; Zero-extend to word
extu.l er0 ; Zero-extend to long
```
2. Status Bits Manipulation:
Code:
mov.b @(1:16,er6), r1l ; Get byte from er6+1
and.b #0x80, r1l ; Keep only bit 7
mov.b @er6, r2l ; Get byte from er6
and.b #0x7F, r2l ; Keep bits 0-6
or.b r2l, r1l ; Combine the bits
mov.b r1l, @(0x41E864:32,er0) ; Store to status array at 0x41E864+device_id
3. First IOMEGA Check (Case sensitive):
Code:
mov.l #8, er0 ; Length = 8
push.l er0 ; Push length
mov.l #aIomega, er1 ; "IOMEGA " string
mov.l er6, er0 ; Buffer pointer
adds #8, er0 ; Buffer+8
jsr unk_400228 ; Compare strings
4. Second IOMEGA Check (Case insensitive):
Code:
mov.l #8, er0 ; Length = 8
push.l er0
mov.l #aIomega_0, er1 ; "iomega " string
mov.l er6, er0 ; Same buffer
adds #8, er0 ; Buffer+8
jsr unk_400228 ; Compare strings
5. ZIP Check:
Code:
mov.l #3, er0 ; Length = 3
push.l er0
mov.l #aZip, er1 ; "ZIP" string
mov.l er6, er0 ; Buffer pointer
add.l #0x10, er0 ; Buffer+16
jsr unk_400228 ; Compare strings
6. If ZIP is Found:
Code:
cmp.b #1, r0l ; Check result
bne loc_12EAA4 ; Skip if not ZIP
mov.b r5l, r0l ; Get device ID
mov.b #1, r1l ; Set flag = 1
mov.b r1l, @(0x41E8AC:32,er0) ; Store flag to array at 0x41E8AC+device_id
This code appears to be validating a device by:
1. Looking for "IOMEGA " (with both case variations)
2. Looking for "ZIP" at offset 0x10
3. Maintaining device status in arrays at 0x41E864 and 0x41E8AC (note the dreaded 0x40xxxx address space)
I'm working through more of the logic, particularly:
1. What happens at loc_12EAA4 (failure path)
2. The code at sub_12F40E, sub_12F482, and sub_12F6B0
3. What happens after a successful validation
Merry Christmas!