**************************************************************
* THUNK FUNCTION *
**************************************************************
thunk undefined Reset()
Thunked-Function: FUN_00000020
undefined r0:1 <RETURN>
Reset XREF[1]: Entry Point(*)
00000000 06 00 00 ea b FUN_00000020
**************************************************************
* FUNCTION *
**************************************************************
undefined UndefinedInstruction()
undefined r0:1 <RETURN>
UndefinedInstruction XREF[1]: Entry Point(*)
00000004 65 47 4f 4e cdpmi p7,0x4,cr4,cr15,cr5,0x3
**************************************************************
* FUNCTION *
**************************************************************
undefined SupervisorCall()
undefined r0:1 <RETURN>
SupervisorCall XREF[1]: Entry Point(*)
00000008 2e 42 54 30 subccs r4,r4,lr, lsr #0x4
**************************************************************
* FUNCTION *
**************************************************************
undefined PrefetchAbort()
undefined r0:1 <RETURN>
PrefetchAbort XREF[1]: Entry Point(*)
0000000c c5 45 42 68 stmdavs r2,{r0 r2 r6 r7 r8 r10 lr}^
**************************************************************
* FUNCTION *
**************************************************************
undefined DataAbort()
undefined r0:1 <RETURN>
DataAbort XREF[1]: Entry Point(*)
00000010 00 26 00 00 andeq r2,r0,r0, lsl #0xc
**************************************************************
* FUNCTION *
**************************************************************
undefined NotUsed()
undefined r0:1 <RETURN>
NotUsed XREF[1]: Entry Point(*)
00000014 53 50 4c 02 subeq r5,r12,#0x53
**************************************************************
* FUNCTION *
**************************************************************
undefined IRQ()
undefined r0:1 <RETURN>
IRQ XREF[1]: Entry Point(*)
00000018 00 00 00 00 andeq r0,r0,r0
**************************************************************
* FUNCTION *
**************************************************************
undefined FIQ()
undefined r0:1 <RETURN>
FIQ XREF[1]: Entry Point(*)
0000001c 00 00 00 00 andeq r0,r0,r0
**************************************************************
* FUNCTION *
**************************************************************
undefined FUN_00000020()
undefined r0:1 <RETURN>
FUN_00000020 XREF[1]: Reset:00000000(T),
Reset:00000000(j)
00000020 00 00 0f e1 mrs r0,cpsr
00000024 1f 00 c0 e3 bic r0,r0,#0x1f
00000028 db 00 80 e3 orr r0,r0,#0xdb
0000002c 00 f0 29 e1 msr cpsr_cf,r0
00000030 78 d0 9f e5 ldr sp,[DAT_000000b0] = 00006C00h
00000034 00 00 0f e1 mrs r0,cpsr
They used several handling styles in their code.
The top bar uses a bitmap for the menu "button", a print text (CH1, CH2, T) and fill rectangle for the channel and trigger "buttons" and bigger bitmaps for the actual menus, instead of building them with code. Certainly faster, but why the mix. Using bitmaps for everything would have been the fastest. A full bitmap for the CTRL "button" instead of filling a rounded rectangle, drawing a rounded rectangle outline and copy in the text bitmap would have been faster.
But this puzzle is also nearing the end. Able to name more and more of the functions and get an understanding of how it works.
I'm also curious as to what people are doing with the data from the repository.
I'm also curious as to what people are doing with the data from the repository.
Sounds like you've got to expand your reversing capabilities!
Very fine work. Can I get a signed print?
void monitor_battery(void)
{
int iVar1;
undefined *puVar2;
byte bVar3;
uint uVar4;
byte *pbVar5;
int iVar6;
int iVar7;
byte bVar8;
bool bVar9;
iVar1 = DAT_8000a6a8; //Base of settings data
bVar8 = 0xff;
if (0xd < *(byte *)(DAT_8000a6a8 + 10)) //Time base setting If 13 is smaller then, so 14 and up (1mS/div and down)
{
iVar7 = 0x1e; //1mS/div --- 10nS/div, factor is 30
goto LAB_8000a5bc;
}
if (*(byte *)(DAT_8000a6a8 + 10) < 0xc) //Less then 0x0C
{
if (*(byte *)(DAT_8000a6a8 + 10) < 9) //Less then 9
{
if (6 < *(byte *)(DAT_8000a6a8 + 10)) //If 6 is smaller then, so 7 and 8.
{
iVar7 = 100; //200mS/div, 100mS/div, factor is 100
goto LAB_8000a5bc;
}
if (3 < *(byte *)(DAT_8000a6a8 + 10)) //If 3 is smaller then, so 4, 5 and 6
{
iVar7 = 0x32; //2S/div, 1S/div, 500mS/div, factor is 64
goto LAB_8000a5bc;
}
if (1 < *(byte *)(DAT_8000a6a8 + 10)) //If 1 is smaller then, so 2 and 3
goto LAB_8000a5b0; //10S/div, 5S/div, factor is 10
}
iVar7 = 3; //0, 1, 9, 10, 11
//50S/div, 20S/div, 50mS/div, 20mS/div, 10mS/div, factor is 3
}
else
{
LAB_8000a5b0: //12, 13
iVar7 = 10; //5mS/div, 2mS/div factor is 10
}
LAB_8000a5bc:
uVar4 = check_port_pin(DAT_8000a6ac,0xc); //Battery charge detect
puVar2 = PTR_DAT_8000a6b0; //0x80192ed4 some global variable, some accumulator??
if (uVar4 == 0) //If pin is low the battery is being charged
{
if (*(char *)(iVar1 + 0x39) == '\0') //BatteryCharging variable
{
*PTR_DAT_8000a6b0 = 0; //If previous state was not charging this variable is set 0
}
*(undefined *)(iVar1 + 0x39) = 1; //Indicate charging
}
else
{
*(undefined *)(iVar1 + 0x39) = 0; //Indicate not charging
}
bVar3 = read_keyadc_data(); //Battery level reading. result 0 - 0x3F
//0x80361378 Some base pointer
//Some fractional addition to the adc value
// result from scan byte from 0x8036137A (screen brightness) 0x068DB8BB
uVar4 = (uint)bVar3 + (uint)((ulonglong)(uint)((int)(short)(ushort)*(byte *)(DAT_8000a6b4 + 2) * (int)(short)((ushort)bVar3 * 10)) * (ulonglong)DAT_8000a6b8 >> 0x28); //High result byte logical shifted right an extra 8
//Check if on charge
if (*(char *)(iVar1 + 0x39) != '\0')
{
uVar4 = uVar4 - 7; //Take of 7 as compensation
}
//Check if result is less then 25
if (uVar4 < 0x19)
{
//If so set it to the minimum
uVar4 = 0x19;
}
//Divide ((the result minus the minimum) multiplied by 20) by 21
pbVar5 = (byte *)divide((uVar4 - 0x19) * 0x14, 0x15);
//Get data from global variable which is reset when charging starts
//Is an array index
bVar3 = *puVar2;
//0x802F1906 some array where the result is stored
DAT_8000a6bc[bVar3] = (byte)pbVar5;
//As long as the index is lower than the factor obtained from timebase setting
if ((int)(uint)bVar3 < iVar7 + -1)
{
//Increment the index and store it back
*puVar2 = bVar3 + 1;
return; //and quit
}
//When several samples are stored it comes here
//true since none of the timebase compare paths lead to iVar being set zero
bVar9 = iVar7 != 0;
if (bVar9)
{
pbVar5 = DAT_8000a6bc; //Point to the data
}
*puVar2 = 0; //Reset the index
//As long as there is data to process
while (bVar9)
{
bVar3 = *pbVar5; //Get the first byte
pbVar5 = pbVar5 + 1; //Point to the next one
if (bVar3 < bVar8) //Determine the lowest value
{
bVar8 = bVar3; //Keep the lowest value of the samples
}
iVar7 = iVar7 + -1; //One count done
bVar9 = iVar7 != 0; //Check on done
}
//Store result in BatteryChargeLevel
*(byte *)(iVar1 + 0x38) = bVar8;
display_battery_status();
}
Hi folks,
Just found a review of the Fnirsi-1013D with a clear verdict:
Hands off the Fnirsi 1013D
Martin
LAB_8001dc04:
do
{
tp_i2c_read_status();
uVar11 = (uint)*(ushort *)(puVar4 + 2);
if (uVar11 - 0xa2 < 0xb6) //Check the xrange
{
uVar15 = (uint)*(ushort *)(puVar4 + 4); //Get the y pos
bVar27 = 0x2d < uVar15;
bVar26 = uVar15 == 0x2e;
if (0x2e < uVar15)
{
bVar27 = uVar15 <= uVar12;
bVar26 = uVar12 == uVar15;
}
if (bVar27 && !bVar26)
{
uVar16 = uVar11 - 0xdc;
if (((uVar16 < 0x3b) && (0x30 < uVar15)) && (uVar15 < 0x6a))
{
if (*puVar4 != '\0') //Do we have touch
{
*pcVar5 = '\x01'; //This is for channel 1 enable
display_channel1_menu();
FUN_80002790();
tp_i2c_read_status();
cVar1 = *puVar4;
while (cVar1 != '\0')
{
tp_i2c_read_status();
cVar1 = *puVar4;
}
}
}
else
{
uVar18 = uVar11 - 0x11a;
if (((uVar18 < 0x3a) && (0x31 < uVar15)) && (uVar15 < 0x6b))
{
if (*puVar4 != '\0')
{
*pcVar5 = '\0'; //This is for channel 1 disable
display_channel1_menu();
FUN_80002790();
pcVar5[3] = '\0';
FUN_8000689c();
tp_i2c_read_status();
cVar1 = *puVar4;
while (cVar1 != '\0') {
tp_i2c_read_status();
cVar1 = *puVar4;
}
}
}
else {
if (((uVar16 < 0x3b) && (0x6f < uVar15)) && (uVar15 < 0xa9)) {
if (*puVar4 != '\0') {
pcVar5[4] = '\x01';
display_channel1_menu();
tp_i2c_read_status();
cVar1 = *puVar4;
while (cVar1 != '\0') {
tp_i2c_read_status();
cVar1 = *puVar4;
}
}
}
else {
if (((uVar18 < 0x3a) && (0x6f < uVar15)) && (uVar15 < 0xa9)) {
if (*puVar4 != '\0') {
pcVar5[4] = '\0';
display_channel1_menu();
tp_i2c_read_status();
cVar1 = *puVar4;
while (cVar1 != '\0') {
tp_i2c_read_status();
cVar1 = *puVar4;
}
}
}
else {
if (((uVar16 < 0x3b) && (0xad < uVar15)) && (uVar15 < 0xe7)) {
if (*puVar4 != '\0') {
pcVar5[1] = '\0';
FUN_800068d4();
display_channel1_menu();
tp_i2c_read_status();
cVar1 = *puVar4;
while (cVar1 != '\0') {
tp_i2c_read_status();
cVar1 = *puVar4;
}
}
}
else {
if (((uVar18 < 0x3a) && (0xad < uVar15)) && (uVar15 < 0xe7)) {
if (*puVar4 != '\0') {
pcVar5[1] = '\x01';
FUN_800068d4();
display_channel1_menu();
tp_i2c_read_status();
cVar1 = *puVar4;
while (cVar1 != '\0') {
tp_i2c_read_status();
cVar1 = *puVar4;
}
}
}
else {
if (((uVar11 - 0xe6 < 0x22) && (0xeb < uVar15)) && (uVar15 < 0x125)) {
if (*puVar4 != '\0') {
pcVar5[2] = '\0';
display_channel1_menu();
tp_i2c_read_status();
cVar1 = *puVar4;
while (cVar1 != '\0') {
tp_i2c_read_status();
cVar1 = *puVar4;
}
}
}
else {
if (((uVar11 - 0x108 < 0x20) && (0xeb < uVar15)) && (uVar15 < 0x125)) {
if (*puVar4 != '\0') {
pcVar5[2] = '\x01';
display_channel1_menu();
tp_i2c_read_status();
cVar1 = *puVar4;
while (cVar1 != '\0') {
tp_i2c_read_status();
cVar1 = *puVar4;
}
}
}
else {
if (((uVar11 - 0x129 < 0x20) && (0xeb < uVar15)) &&
((uVar15 < 0x125 && (*puVar4 != '\0')))) {
pcVar5[2] = '\x02';
display_channel1_menu();
tp_i2c_read_status();
cVar1 = *puVar4;
while (cVar1 != '\0') {
tp_i2c_read_status();
cVar1 = *puVar4;
}
}
}
}
}
}
}
}
}
}
goto LAB_8001dc04;
}
}
} while (*puVar4 == '\0');
FUN_8000a6c0(); //Copy saved screen rect back to the screen
tp_i2c_read_status();
cVar1 = *puVar4;
while (cVar1 != '\0') {
tp_i2c_read_status();
cVar1 = *puVar4;
}
//Stay in the menu as long as there is no touch outside the menu
while(1)
{
//Scan the touch panel for touch
tp_i2c_read_status();
//Check if there is touch
if(havetouch)
{
//Check if touch within the menu field
if((xtouch >= 161) && (xtouch <= 344) && (ytouch >= 46) && (ytouch <= 298))
{
//Check on channel enable or disable
if((ytouch >= 62) && (ytouch <= 84))
{
//Check on enable
if((xtouch >= 239) && (xtouch <= 271))
{
//Enable the channel
scopesettings.channel1.enable = 1;
//Display this
display_channel1_enable_select();
display_channel1_settings(0);
}
//Check on disable
else if((xtouch >= 291) && (xtouch <= 323))
{
//Disable the channel
scopesettings.channel1.enable = 0;
//Display this
display_channel1_enable_select();
display_channel1_settings(0);
}
}
//Check on fft enable or disable
else if((ytouch >= 124) && (ytouch <= 146))
{
//Check on enable
if((xtouch >= 239) && (xtouch <= 271))
{
//Enable the channel
scopesettings.channel1.fftenable = 1;
//Display this
display_channel1_fft_show();
}
//Check on disable
else if((xtouch >= 291) && (xtouch <= 323))
{
//Disable the channel
scopesettings.channel1.fftenable = 0;
//Display this
display_channel1_fft_show();
}
}
//Check on coupling DC or AD
else if((ytouch >= 188) && (ytouch <= 210))
{
//Check on enable
if((xtouch >= 239) && (xtouch <= 271))
{
//Enable the channel
scopesettings.channel1.coupling = 0;
//Display this
display_channel1_coupling_select();
display_channel1_settings(0);
}
//Check on disable
else if((xtouch >= 291) && (xtouch <= 323))
{
//Disable the channel
scopesettings.channel1.coupling = 1;
//Display this
display_channel1_coupling_select();
display_channel1_settings(0);
}
}
//Check on probe magnification setting
else if((ytouch >= 245) && (ytouch <= 283))
{
//Check on 1x
if((xtouch >= 239) && (xtouch <= 259))
{
//Enable the channel
scopesettings.channel1.magnification = 0;
//Display this
display_channel1_probe_magnification_select();
display_channel1_settings(0);
}
//Check on 10x
else if((xtouch >= 270) && (xtouch <= 293))
{
//Disable the channel
scopesettings.channel1.magnification = 1;
//Display this
display_channel1_probe_magnification_select();
display_channel1_settings(0);
}
//Check on 100x
else if((xtouch >= 299) && (xtouch <= 329))
{
//Disable the channel
scopesettings.channel1.magnification = 2;
//Display this
display_channel1_probe_magnification_select();
display_channel1_settings(0);
}
}
//Wait until touch is released before checking on a new position
while(havetouch)
{
//Scan the touch panel for touch
tp_i2c_read_status();
}
}
else
{
//Touch outside the menu so quit
return;
}
}
}