Reverse engineering details in the U1253A / U1253B / U1273A / U1273AX firmware
» Binary format «
This part only applies for U1253B, U1273A and U1273AX updaters, the binary extracted from the U1253A is already reversed.
The updater only checks the file size, there isn't any kind of checksum, so we can modify it freely.
The .AG file is byte-reversed and nibble-swapped.
This first bytes:
A0 13 00 00 03 7F 06 7F
Are the actually the last bytes of the firmware:
F7 60 F7 30 00 00 31 0A
A tool was writen to perform this task: (Attached, including the sources).
Usage is as follows:
tool.exe [input] [output] [xor]
This tool is compatible with the .AG firmware file of Agilent/Keysight U1253B, U1273A(X) and maybe others.
It reverses the byte order and swaps the nibbles, optionally applying a XOR value.
The output will be the original firmware bytes, ready for modifying or disassembling.
Once modified, run the tool again to convert it back to the original format, it'll be ready for flashing.
XOR option is optional and only for research purposes, not required to reverse the original .AG firmware file.
XOR value must written in hex representation, like 0x9A.
Examples: tool.exe input.bin output.bin
tool.exe input.bin output.bin 0x9A
» Updater format «
This part only applies for U1253B, U1273A and U1273AX updaters.
It's not required to get your hands dirty with the updater, just for documenting purposes.
The updater reverses the bytes and nibbles back to normal when sending the firmware to the DMM, but also XORs the data with 0x9A.
Each packet seems to be 1024 firmware bytes + 2 bytes checksum.
First 32 bytes captured data from the updater communication:
3A 89 9A 9A 99 E5 9C E5 93 E5 96 E5 95 E5 88 E5
8F E5 82 E5 53 91 3F 91 81 E5 84 E5 BB E5 BE E5
Last 32 bytes of original .ag file:
F7 42 F7 12 F7 E1 F7 B1 B0 5A B0 9C F7 81 F7 51
F7 21 F7 F0 F7 C0 F7 90 F7 60 F7 30 00 00 31 0A
Reverse bytes and perform nibble swap:
A0 13 00 00 03 7F 06 7F 09 7F 0C 7F 0F 7F 12 7F
15 7F 18 7F C9 0B A5 0B 1B 7F 1E 7F 21 7F 24 7F
XOR everything with 0x9A, matching updater data: (This detail was essential to later decode the U1253A firmware!)
3A 89 9A 9A 99 E5 9C E5 93 E5 96 E5 95 E5 88 E5
8F E5 82 E5 53 91 3F 91 81 E5 84 E5 BB E5 BE E5
No further investigation was performed about the bootloader protocol or packet checksums, as this was not required for the firmware modification.
» Firmware sections «
- Bootloader: 0x0000-0x2FFF.
- App: 0x3000-0x7FFFF, 0x8000-0xBFFF(*).
(*) Flash is banked, so depending on the bank register, 0x8000-0xBFFF is mapped to 6 different flash areas:
- Bank 0: 0x08000-0x0BFFF
- Bank 1: 0x0C000-0x0FFFF
- Bank 2: 0x10000-0x13FFF
- Bank 3: 0x14000-0x17FFF
- Bank 4: 0x18000-0x1BFFF
- Bank 5: 0x1C000-0x1FFFF
No disassembler supporting 78K0 architecture and banked flash was found.
Thus, most of the work was performed analyzing the common area (0x0000-0x7FFF) and bank 0 (0x8000-0xBFFF).
» Display replacement «
- The difference is not the command set, but the display fabrication.
- The panel might be wired "backwards", showing a mirrored picture.
- The SSD1306/SSD1309 controller supports 132x64 resolution, but:
- Depending on the manufacturer, the first pixel column in 128x64 diplays is connected to controller column 0 or 2.
- The original displays uses X-offset=2, while the ones found in aliexpress seem to use X-offset=0.
- This is what causes the weird vertical line when replacing the screen, and the image being slighly shifted.
- Thus, firmware modification is needed to overcome all of this.
» Modification «
The original .ag file must be reversed with the tool to work with k0dasm (Only for .AG firmwares, doesn't apply for U1253A).
tool.exe U1273AX_V303.AG fw.bin
Once decoded, it can be partially disassembled after slightly modifying K0dasm (Attached).
k0dasm fw.bin > disassembled.txt
Useful links:
-
78K0 instruction manual.
- Very useful assembler example in k0dasm repo:
testprog.asm.
With all this, the essential routines were identified:
call pattern:
send_data: sub_0a5d 9a 5d 0a
send_cmd: sub_0a68 9a 68 0a
oled_init: sub_0994 9a 94 09
oled_draw: sub_0ac2 9a c2 0a (Also calling sub_0b20)
oled_pos: sub_0b20 9a 20 0b
The mcu only updates the APP section, so program under 0x3000 cannot be modified.
Thus, new functions were made and placed in empty areas, replacing any calls to the functions in the bootloader with the new ones.
- Display init: sub_7f60, allowing custom X/Y flip (Credits:
abyrvalg).
sub_7f60:
clr1 pm1.0 ;7f60 71 0b 21 <<<--- Same as original function
clr1 pm1.1 ;7f63 71 1b 21
mov pu12,#0x00 ;7f66 13 3c 00
clr1 p1.0 ;7f69 0b 01
clr1 p1.1 ;7f6b 1b 01
mov pm5,#0x00 ;7f6d 13 25 00
mov pu5,#0x00 ;7f70 13 35 00
mov p5,#0x00 ;7f73 11 05 00
mov PM14,#0x02 ;7f76 13 2e 02
mov pu14,#0x02 ;7f79 13 3e 02
set1 P14.3 ;7f7c 3a 0e
set1 P14.4 ;7f7e 4a 0e
set1 P14.5 ;7f80 5a 0e
set1 P14.2 ;7f82 2a 0e
movw ax,#0x0064 ;7f84 10 64 00
call !sub_0946 ;7f87 9a 46 09
set1 P13.0 ;7f8a 0a 0d
clr1 P13.0 ;7f8c 0b 0d
movw ax,#0x000a ;7f8e 10 0a 00
call !sub_0946 ;7f91 9a 46 09
set1 P13.0 ;7f94 0a 0d
movw ax,#0x00ae ;7f96 10 ae 00
call !sub_0a68 ;7f99 9a 68 0a
movw ax,#0x00ad ;7f9c 10 ad 00
call !sub_0a68 ;7f9f 9a 68 0a
movw ax,#0x008a ;7fa2 10 8a 00
call !sub_0a68 ;7fa5 9a 68 0a
movw ax,#0x00a8 ;7fa8 10 a8 00
call !sub_0a68 ;7fab 9a 68 0a
movw ax,#0x003f ;7fae 10 3f 00
call !sub_0a68 ;7fb1 9a 68 0a
movw ax,#0x00d3 ;7fb4 10 d3 00
call !sub_0a68 ;7fb7 9a 68 0a
movw ax,#0x0000 ;7fba 10 00 00
call !sub_0a68 ;7fbd 9a 68 0a
movw ax,#0x0040 ;7fc0 10 40 00
call !sub_0a68 ;7fc3 9a 68 0a
movw ax,#0x00a1 ;7fc6 10 a1 00 <<<--- Segment remap cmd (Y-mirror)
call !sub_0a68 ;7fc9 9a 68 0a
movw ax,#0x00c0 ;7fcc 10 c0 00 <<<--- Scan direction cmd (X-mirror)
call !sub_0a68 ;7fcf 9a 68 0a
movw ax,#0x00a6 ;7fd2 10 a6 00
call !sub_0a68 ;7fd5 9a 68 0a
br !lab_0a0c ;7fd8 9b 0c 0a <<<--- Continue in original function
- Drawing: sub_7ec0 (Calling sub_7e80).
sub_7ec0:
push hl ;7ec0 b7 <<<--- Same as original function
push ax ;7ec1 b1
push ax ;7ec2 b1
movw ax,sp ;7ec3 89 1c
movw hl,ax ;7ec5 d6
mov a,[hl+0x0a] ;7ec6 ae 0a
inc a ;7ec8 41
mov [hl+0x0a],a ;7ec9 be 0a
mov x,#0x00 ;7ecb a0 00
xch a,x ;7ecd 30
push ax ;7ece b1
mov a,[hl+0x08] ;7ecf ae 08
mov x,#0x00 ;7ed1 a0 00
xch a,x ;7ed3 30
call !sub_7e80 ;7ed4 9a 80 7e <<<--- Call new oled position function
br !lab_0ad9 ;7ed7 9b d9 0a <<<--- Continue in original function
- Set position: sub_7e80, subtracting a value from the column value to fix the X-offset.
sub_7e80:
push hl ;7e80 b7 <<<--- Same as original function
push ax ;7e81 b1
movw ax,sp ;7e82 89 1c
movw hl,ax ;7e84 d6
mov a,[hl] ;7e85 87
xch a,x ;7e86 30
mov a,[hl+0x06] ;7e87 ae 06
movw hl,ax ;7e89 d6
mov a,#0xb0 ;7e8a a1 b0 <<<--- Row cmd
or a,l ;7e8c 61 6e
mov x,#0x00 ;7e8e a0 00
xch a,x ;7e90 30
call !sub_0a68 ;7e91 9a 68 0a <<<--- Send cmd
mov a,h ;7e94 67 <<<--- Move column value to reg A
cmp a,!mem_7e9e ;7e95 48 9e 7e <<<--- Compare with subtract value at 0x7e9e
bnc lab_7e9d ;7e98 9d 03 <<<--- If carry set, load A with subtract value so it becomes 0 when subtracting
mov a,!mem_7e9e ;7e9a 8e 9e 7e
lab_7e9d:
sub a,#0x02 ;7e9d 1d 02 <<<--- Subtract 2 to column value
mov h,a ;7e9f 77 <<<--- Update H reg for later use in lower column cmd
and a,#0x0f ;7ea0 5d 0f <<<--- Isolate lower column data
mov x,#0x00 ;7ea2 a0 00
xch a,x ;7ea4 30
call !sub_0a68 ;7ea5 9a 68 0a <<<--- Send cmd
mov a,h ;7ea8 67 <<<--- Move column value to reg A
ror a,1 ;7ea9 24 <<<--- Rotate 4 bits to the left to get higher column bits
ror a,1 ;7eaa 24
ror a,1 ;7eab 24
ror a,1 ;7eac 24
and a,#0x0f ;7ead 5d 0f <<<--- Isolate higher column data
or a,#0x10 ;7eaf 6d 10 <<<--- High column cnmd
mov x,#0x00 ;7eb1 a0 00
xch a,x ;7eb3 30
call !sub_0a68 ;7eb4 9a 68 0a <<<--- Send cmd
pop ax ;7eb7 b0
pop hl ;7eb8 b6
ret ;7eb9 af <<<--- Done, return
New functions: call pattern:
oled_init: sub_7f60 9a 60 7f
oled_draw: sub_7ec0 9a c0 7e (Also calling sub_7e80)
oled_pos: sub_7e80 9a 80 7e
Hex bytes:B7 B1 89 1C D6 87 30 AE 06 D6 A1 B0 61 6E A0 00 30 9A 68 0A 67 48 9E 7E 9D 03 8E 9E 7E 1D 02 77 5D 0F A0 00 30 9A 68 0A 67 24 24 24 24 5D 0F 6D 10 A0 00 30 9A 68 0A B0 B6 AF 00 00 00 00 00 00 B7 B1 B1 89 1C D6 AE 0A 41 BE 0A A0 00 30 B1 AE 08 A0 00 30 9A 80 7E 9B D9 0A
71 0B 21 71 1B 21 13 3C 00 0B 01 1B 01 13 25 00 13 35 00 11 05 00 13 2E 02 13 3E 02 3A 0E 4A 0E 5A 0E 2A 0E 10 64 00 9A 46 09 0A 0D 0B 0D 10 0A 00 9A 46 09 0A 0D 10 AE 00 9A 68 0A 10 AD 00 9A 68 0A 10 8A 00 9A 68 0A 10 A8 00 9A 68 0A 10 3F 00 9A 68 0A 10 D3 00 9A 68 0A 10 00 00 9A 68 0A 10 40 00 9A 68 0A 10 A1 00 9A 68 0A 10 C0 00 9A 68 0A 10 A6 00 9A 68 0A 9B 0C 0A
Because the entire firmware can't be disassembled, a manual pattern search and replace was performed:
- "9A 94 09" (call !sub_0994) -> "9A 60 7F" (call !sub_7f60)
- "9A 20 0B" (call !sub_0b20) -> "9A 80 7E" (call !sub_7e80)
- "9A C2 0A" (call !sub_0ac2) -> "9A C0 7E" (call !sub_7ec0)
Now, the user can easily patch the .AG file (Updater format, not reversed) using any hex editor like HxD to fix any difference in the screen:
Address Value Function
0x18032 0x0C / 0x8C X-mirror off / on
0x18038 0x0A / 0x1A Y-mirror off / on
0x18161 0x00-0xFF X-offset subtract value, nibble-swapped, so 0x00 / 0x10 / 0x20 for 0/-1/-2 pixel offset (Subtracted to the default 2 offset)
Remember this is hex, use a
decimal to hexadecimal converter.
For example, set 10 pixel X-offset: The number to put there is not 10 -> swap -> 0x01! 10=0x0A in hex, after swapping=0xA0.
The original firmware uses X-offset of 2, so applying a subtract value higher than 2 won't make any effect (Tested for underflow).
If for whatever reason, instead subtracting you want to increase the column address, patch as following:
0x18162 Replace [D1 E7 E9 E8 30 D9 E7 E9 84] with [D0 00 00 00 00 00 00 00 00].
Address Value Function
0x18167 0x00-0xFF X-offset add value, nibble-swapped, so 0x00 / 0x10 / 0x20 for 0/+1/+2 pixel offset (Added to the default 2 offset)
After modification, tool must be run again on the modified file to became ready to be flashed with the updater:
tool.exe fw_modded.AG U1273AX_V303.bin
Additionally, the boot logos were located and can be easily modified now.
This procedure is identical in v3.03 and v4.02 firmwares.
Offsets of the images in the .AG file (Updater format, not reversed):
- U1237AX logo: 0x8000-0x83FF
- KEYSIGHT screen: 0x8400-0x87FF
Make a 128x64px image in Paint or whatever, save as monochrome BMP.
Use this converter:
https://javl.github.io/image2cpp/ - Load the bmp.
- Tick "Flip image vertically".
- Draw mode: vertical - 1 bit per pixel.
- If the image color appears inverted, tick "Invert image colors".
- Click generate code.
- Download as binary.
- Only for firmwares in .AG format: Fix the nibble and byte ordering: "tool.exe downloaded.bin fixed.bin"
- Open both the .ag firmware and fixed picture in HxD.
- In the image data, Right click over the data, click select All, Copy.
- Go to the FW data, Control+G, write this offset (hex):
- U1237AX logo: 8000
- KEYSIGHT screen: 8400
- Right click on that byte, "Paste writing". If you get a warning like "This operation will change the file size", you're doing it wrong.
- Save the file.
To load the modded firmware into the DMM, rename the modded file to "U1273AX_V303.AG", place it in the updater folder and run the updater.
I quickly analyzed v4.02 to find out it's very much the same thing, the addresses of the display functions and the boot pictures are the same.
But it seems be already doing the same as this mod, so no action required at all! Just replace the display with the one from the aliexpress!
cmp a,h ;0b2c 61 4f <<<--- Check if column is 0
bnc lab_0b31 ;0b2e 9d 01 <<<--- If not, decrease h
dec h ;0b30 57 <<<--- Otherwise skip
lab_0b31:
mov a,#0x00 ;0b31 a1 00
cmp a,h ;0b33 61 4f <<<--- (Again) Check if column is 0
bnc lab_0b38 ;0b35 9d 01 <<<--- If not, decrease h
dec h ;0b37 57 <<<--- Otherwise skip
movw ax,#0x00a1 ;09fa 10 a1 00 <<<--- Segment remap cmd (Y-mirror)
call !sub_0a68 ;09fd 9a 68 0a
movw ax,#0x00c0 ;0a00 10 c0 00 <<<--- Scan direction cmd (X-mirror)
call !sub_0a68 ;0a03 9a 68 0a
Specific for U1253B:This write-up was made for the U1253B v3.04 firmware.
Original: call pattern:
send_data: sub_05c6 9a c6 05
send_cmd: sub_05d1 9a d1 05
oled_init: sub_04f5 9a f5 04
oled_draw: sub_062c 9a 2c 06 (Also calling sub_068a)
oled_pos: sub_068a 9a 8a 06
New functions: call pattern:
oled_init: sub_7f60 9a 60 7f
oled_pos: sub_7f70 9a 70 7f
oled_draw: sub_7faa 9a aa 7f (Also calling sub_7f70)
- Display init: sub_7f60:sub_7f60:
call !sub_04f5 ;7f60 9a f5 04 <<<--- Call original function
movw ax,#0x00a1 ;7f63 10 a1 00 <<<--- Segment remap cmd (Y-mirror)
call !sub_05d1 ;7f66 9a d1 05 <<<--- Send cmd
movw ax,#0x00c0 ;7f69 10 c0 00 <<<--- Scan direction cmd (X-mirror)
call !sub_05d1 ;7f6c 9a d1 05 <<<--- Send cmd
ret ;7f6f af <<<--- Return
- Set position: sub_7f70:sub_7f70:
push hl ;7f70 b7 <<<--- Same as original function
push ax ;7f71 b1
movw ax,sp ;7f72 89 1c
movw hl,ax ;7f74 d6
mov a,[hl] ;7f75 87
xch a,x ;7f76 30
mov a,[hl+0x06] ;7f77 ae 06
movw hl,ax ;7f79 d6
mov a,#0xb0 ;7f7a a1 b0 <<<--- Row cmd
or a,l ;7f7c 61 6e
mov x,#0x00 ;7f7e a0 00
xch a,x ;7f80 30
call !sub_05d1 ;7f81 9a d1 05 <<<--- Send cmd
mov a,h ;7f84 67 <<<--- Move column value to reg A
cmp a,!mem_7f8e ;7f85 48 8e 7f <<<--- Compare with subtract value at 0x7f8e
bnc lab_7f8d ;7f88 9d 03 <<<--- If carry set,
mov a,!mem_7f8e ;7f8a 8e 8e 7f <<<--- Load A with subtract value at 0x7f8e so it becomes 0 when subtracting
lab_7f8d:
sub a,#0x02 ;7f8d 1d 02 <<<--- Subtract 2 to column value
mov h,a ;7f8f 77 <<<--- Update H reg for later use in lower column cmd
and a,#0x0f ;7f90 5d 0f <<<--- Isolate lower column data
mov x,#0x00 ;7f92 a0 00
xch a,x ;7f94 30
call !sub_05d1 ;7f95 9a d1 05 <<<--- Send cmd
mov a,h ;7f98 67 <<<--- Move column value to reg A
ror a,1 ;7f99 24 <<<--- Rotate 4 bits to the left to get higher column bits
ror a,1 ;7f9a 24
ror a,1 ;7f9b 24
ror a,1 ;7f9c 24
and a,#0x0f ;7f9d 5d 0f <<<--- Isolate higher column data
or a,#0x10 ;7f9f 6d 10 <<<--- High column cmd
mov x,#0x00 ;7fa1 a0 00
xch a,x ;7fa3 30
call !sub_05d1 ;7fa4 9a d1 05 <<<--- Send cmd
pop ax ;7fa7 b0
pop hl ;7fa8 b6
ret ;7fa9 af <<<--- Done, return
- Drawing: sub_7faa:sub_7faa:
push hl ;7faa b7 <<<--- Same as original function
push ax ;7fab b1
push ax ;7fac b1
movw ax,sp ;7fad 89 1c
movw hl,ax ;7faf d6
mov a,[hl+0x0a] ;7fb0 ae 0a
inc a ;7fb2 41
mov [hl+0x0a],a ;7fb3 be 0a
mov x,#0x00 ;7fb5 a0 00
xch a,x ;7fb7 30
push ax ;7fb8 b1
mov a,[hl+0x08] ;7fb9 ae 08
mov x,#0x00 ;7fbb a0 00
xch a,x ;7fbd 30
call !sub_7f70 ;7fbe 9a 70 7f <<<--- Call new oled position function
br !lab_0643 ;7fc1 9b 43 06 <<<--- Continue in original function
Hex bytes:9A F5 04 10 A1 00 9A D1 05 10 C0 00 9A D1 05 AF B7 B1 89 1C D6 87 30 AE 06 D6 A1 B0 61 6E A0 00 30 9A D1 05 67 48 8E 7F 9D 03 8E 8E 7F 1D 02 77 5D 0F A0 00 30 9A D1 05 67 24 24 24 24 5D 0F 6D 10 A0 00 30 9A D1 05 B0 B6 AF B7 B1 B1 89 1C D6 AE 0A 41 BE 0A A0 00 30 B1 AE 08 A0 00 30 9A 70 7F 9B 43 06
Because the entire firmware can't be disassembled, a manual pattern search and replace was performed:
- INIT: "9A F5 04" (call !sub_04f5) -> "9A 60 7F" (call !sub_7f60)
- POSITION: "9A 8A 06" (call !sub_068a) -> "9A 70 7F" (call !sub_7f70)
- DRAW: "9A 2C 06" (call !sub_062c) -> "9A AA 7F" (call !sub_7faa)
Patching offsets: ( .AG file in updater format, not reversed)
Address Value Function
0x18095 0x0C / 0x8C X-mirror off / on
0x1809B 0x0A / 0x1A Y-mirror off / on
0x18071 0x00-0xFF X-offset subtract value, nibble-swapped, so 0x00 / 0x10 / 0x20 for 0/-1/-2 pixel offset (Subtracted to the default 2 offset)
If for whatever reason, instead subtracting you want to increase the column address, patch as following:
0x18072 Replace [D1 F7 E8 E8 30 D9 F7 E8 84] with [D0 00 00 00 00 00 00 00 00].
Address Value Function
0x18071 0x00-0xFF X-offset add value, nibble-swapped, so 0x00 / 0x10 / 0x20 for 0/+1/+2 pixel offset (Added to the default 2 offset)
The boot logos are placed in the same area as U1273A(X), same procedure applies.
Specific for U1253A:This write-up was made for the U1253A v1.20 firmware.
The firmware is contained inside the updater .exe, it uses a completely different format, so a new tool was needed.
There's a RTF text file embedded in the executable containing Intel Hex format, it's clearly encoded.
:10 0000 A5 9F2CC0C03C4039403640334030402D40 45
:10 0010 A8 573D5A3D5545B144593D5C3D633D663D 0C
:10 0020 80 3D65306537652A6529652C6523652665 BC
:10 0030 98 0D4D704D774D7A4D794D7C4D634D664D 94
Checksum follows Intel Hex standard: Sum all bytes in (100000A59F2CC0C03C4039403640334030402D401 = 0xBB) and make 2-complement: 0x45.
These bytes will likely match this (From U1273A):
A0 13 FF FF 03 7F 06 7F 09 7F 0C 7F 0F 7F 12 7F
15 7F 18 7F 2D 07 09 07 1B 7F 1E 7F 21 7F 24 7F
27 7F 2A 7F 2D 7F 30 7F 33 7F 36 7F 39 7F 3C 7F
3F 7F 42 7F 45 7F 48 7F 4B 7F 4E 7F 51 7F 54 7F
It's XOR'red with [0x9A + 3rd field field]
:10 0000 A5 [ 9F2CC0C03C4039403640334030402D40 ] ^ [0x9A+0xA5] = [ A0 13 00 00 03 7F 06 7F 09 7F 0C 7F 0F 7F 12 7F ]
:10 0010 A8 [ 573D5A3D5545B144593D5C3D633D663D ] ^ [0x9A+0xA8] = [ 15 7F 18 7F C9 0B A5 0B 1B 7F 1E 7F 21 7F 24 7F ]
:10 0020 80 [ 3D65306537652A6529652C6523652665 ] ^ [0x9A+0x80] = [ 27 7F 2A 7F 2D 7F 30 7F 33 7F 36 7F 39 7F 3C 7F ]
:10 0030 98 [ 0D4D704D774D7A4D794D7C4D634D664D ] ^ [0x9A+0x98] = [ 3F 7F 42 7F 45 7F 48 7F 4B 7F 4E 7F 51 7F 54 7F ]
A tool was writen to extract/insert the firmware from/to the updater executable: (Attached, including the sources)
tool_U1253A.exe [ -e | -i ] [ input_file ] [ output_file ]
This tool extracts/inserts the firmware from/to the Agilent U1253A updater executable
Only tested with "Agilent U1253A Firmware Update V120.exe"!
-e: Extract the firmware from the updater executable into a file.
The output will be the original firmware bytes, ready for modifying or disassembling.
-i: Insert the firmware file into an existing updater executable.
Example: tool -e updater.exe firmware.bin (firmware.bin is created)
Example: tool -i firmware.bin updater.exe (firmware.bin is inserted into update.exe)
The routines were the same, and placed in the same addresses as the U1253B.
Modification was identical to the one in U1253B, however the extracted bin file is not reversed, and the .exe can't be directly patched, so the modifications are different:
Patching offsets: (Over the file extracted using the tool)
Address Value Function
0x7F6A 0xC0 / 0xC8 X-mirror off / on
0x7F64 0xA0 / 0xA1 Y-mirror off / on
0x7F8E 0x00-0xFF X-offset subtract value, 0x00 / 0x01 / 0x02 for 0/-1/-2 pixel offset (Subtracted to the default 2 offset)
If for whatever reason, instead subtracting you want to increase the column address, patch as following:
0x7F85 Replace [48 8E 7F 9D 03 8E 8E 7F 1D] with [00 00 00 00 00 00 00 00 0D].
Address Value Function
0x7F8E 0x00-0xFF X-offset add value, 0x00 / 0x01 / 0x02 for 0/+1/+2 pixel offset (Added to the default 2 offset)
Offsets of the images in the extracted file after using the tool:
- U1253A logo: Not there?
- Agilent screen: 0x1758A-0x17989
- Agilent screen: 0x1798B-0x17D8A (Same image, slightly shifted to the left).
Make a 128x64px image in Paint or whatever, save as monochrome BMP.
Use this converter:
https://javl.github.io/image2cpp/ - Load the bmp.
- Tick "Flip image vertically".
- Draw mode: vertical - 1 bit per pixel.
- If the image color appears inverted, tick "Invert image colors".
- Click generate code.
- Download as binary.
- Open both the extracted firmware and .bin picture in HxD.
- In the image data, Right click over the data, click select All, Copy.
- Go to the FW data, Control+G, write this offset (hex):
- Agilent screen: 1758A
- 2nd Agilent screen: 1798B
- Right click on that byte, "Paste writing". If you get a warning like "This operation will change the file size", you're doing it wrong.
- Save the file.