"MT1369 RESETDISC UPGRADE"Essa string pode ser concontrada em todo firmware MT13x9. Confirmado com:
- Proview DVP-858
- Philips DVP5100
- Philips DVP5960
- Philips DVP5965
- Philips DVP5140
- Philips DVP5980
- Philips DVP3040
- Philips PET725
- LG DK194G
- LG série 8xxx
- LG série 9xxx
- Pioneer 575
- JTEC MTK7000
Tanto que vou passar a usá-la no mtkModToolbox para reconhecer se um firmware é válido.
Ao contrário do que parece, é a junção das strings:
MT1369 RESET
DISC UPGRADE
Minha investigação sobre o propósito dessas strings foi interessante. Existe uma rotina no Bloco 0 que verifica se uma dessas strings está na memória, a apaga e toma uma ação dependendo de qual das duas foi encontrada.
Eu suponho que "MT1369 RESET" seja a condição normal, que acontece toda vez que o aparelho é ligado e que "DISC UPGRADE", logicamente, só aconteça num upgrade. É possível que o firmware use isso para determinar, ao ligar, se vai ser preciso fazer alguma inicialização extra. Talvez carregar novos valores default na EEPROM. Se for este o caso, talvez até exista uma diferença funcional entre instalar um firmware por cabo e por CD.
Rotinas do Proview DVP-858 20.07B0:E568 Esta rotina retorna "2" se encontrar "DISC UPGRADE" na memória
B0:E568 "1" se encontrar "MT1369 RESET" e "0" se não encontrar nada.
B0:E568
B0:E568 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
B0:E568
B0:E568
B0:E568 B0_E568: ; CODE XREF: B0_E26Bp
B0:E568 E4 clr A ; Verifica se "MT1369 RESET" está na memória
B0:E569 F5 35 mov RAM_35, A ; RAM_35 conta as interações pelo loop
B0:E56B
B0:E56B B0_E56B: ; CODE XREF: B0_E568+1Ej
B0:E56B E5 35 mov A, RAM_35
B0:E56D 24 97 add A, #0x97 ; 'ù'
B0:E56F FF mov R7, A ; Primeira passagem: R7=97
B0:E570 E4 clr A
B0:E571 33 rlc A ; Neste ponto A sempre tem "1"
B0:E572 FE mov R6, A
B0:E573 12 F3 20 lcall BankSw_1_B0_F320 ; Lê a XRAM, 0xC bytes desde F997, com retorno em R7
B0:E576 E5 35 mov A, RAM_35
B0:E578 90 18 5B mov DPTR, #B0_185B
B0:E57B 93 movc A, @A+DPTR
B0:E57C 6F xrl A, R7
B0:E57D 70 09 jnz B0_E588 ; Salta se não corresponde
B0:E57F 05 35 inc RAM_35
B0:E581 E5 35 mov A, RAM_35
B0:E583 C3 clr C
B0:E584 94 0C subb A, #0xC ; "RESET MT13x9" tem 0xC caracteres
B0:E586 40 E3 jc B0_E56B
B0:E588
B0:E588 B0_E588: ; CODE XREF: B0_E568+15j
B0:E588 E5 35 mov A, RAM_35
B0:E58A B4 0C 08 cjne A, #0xC, Disc_Upgrade? ; Verifica se o loop chegou a ser completado
B0:E58A ; (todos os caracteres encontrados). Se negativo salta para a próxima.
B0:E58A ; Se positivo, encerra.
B0:E58D C2 34 clr RAM_26.4 ; Determina o apagamento da string
B0:E58F 12 AE 60 lcall B0_AE60 ; Grava (ou apaga) "MT1369 RESET" de XRAM_F897 a XRAM_F8A2
B0:E592 7F 01 mov R7, #1 ; 1 = "MT1369 RESET"
B0:E594 22 ret
B0:E595 ; ---------------------------------------------------------------------------
B0:E595
B0:E595 Disc_Upgrade?: ; CODE XREF: B0_E568+22j
B0:E595 E4 clr A ; verifica se a string "DISC UPGRADE" está na memória
B0:E596 F5 35 mov RAM_35, A ; RAM_35 conta as interações pelo loop
B0:E598
B0:E598 B0_E598: ; CODE XREF: B0_E568+4Bj
B0:E598 E5 35 mov A, RAM_35
B0:E59A 24 97 add A, #0x97 ; 'ù'
B0:E59C FF mov R7, A ; Primeira passagem: R7=97
B0:E59D E4 clr A
B0:E59E 33 rlc A ; Neste ponto A sempre tem "1"
B0:E59F FE mov R6, A
B0:E5A0 12 F3 20 lcall BankSw_1_B0_F320 ; Lê a XRAM, 0xC bytes desde F997, com retorno em R7
B0:E5A3 E5 35 mov A, RAM_35
B0:E5A5 90 18 67 mov DPTR, #DISC_UPGRADE
B0:E5A8 93 movc A, @A+DPTR
B0:E5A9 6F xrl A, R7
B0:E5AA 70 09 jnz B0_E5B5 ; Salta se não corresponde
B0:E5AC 05 35 inc RAM_35
B0:E5AE E5 35 mov A, RAM_35
B0:E5B0 C3 clr C
B0:E5B1 94 0C subb A, #0xC ; "DISC UPGRADE" tem 0xC caracteres
B0:E5B3 40 E3 jc B0_E598
B0:E5B5
B0:E5B5 B0_E5B5: ; CODE XREF: B0_E568+42j
B0:E5B5 E5 35 mov A, RAM_35
B0:E5B7 B4 0C 08 cjne A, #0xC, B0_E5C2 ; Verifica se o loop chegou a ser completado (todos os caracteres encontrados)
B0:E5BA C2 34 clr RAM_26.4 ; Determina o apagamento da string
B0:E5BC 12 AE 60 lcall B0_AE60 ; Grava (ou apaga) "MT1369 RESET" de XRAM_F897 a XRAM_F8A2
B0:E5BF 7F 02 mov R7, #2 ; 2= "DISC UPGRADE" estava na memória
B0:E5C1 22 ret
B0:E5C2 ; ---------------------------------------------------------------------------
B0:E5C2
B0:E5C2 B0_E5C2: ; CODE XREF: B0_E568+4Fj
B0:E5C2 7F 00 mov R7, #0
B0:E5C4 22 ret
B0:E5C4 ; End of function B0_E568
Esta é uma das rotinas que escreve ou apaga:
B0:AE60 Se esta rotina for chamada com bit RAM_26.4 setado, a
B0:AE60 string será escrita. Se o bit estiver estiver resetado,
B0:AE60 os 0xC bytes serão zerados.
B0:AE60
B0:AE60 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
B0:AE60
B0:AE60 ; Grava (ou apaga) "MT1369 RESET" de XRAM_F897 a XRAM_F8A2
B0:AE60
B0:AE60 B0_AE60: ; CODE XREF: B0_8F1D+E2p
B0:AE60 ; B0_8F1D+189j ...
B0:AE60 20 34 03 jb RAM_26.4, B0_AE66 ; "1", escreve, "0", apaga.
B0:AE63 02 AF 02 ljmp B0_AF02 ; Zera a memória de XRAM_F897 a XRAM_F8A2
B0:AE66 ; ---------------------------------------------------------------------------
B0:AE66
B0:AE66 B0_AE66: ; CODE XREF: B0_AE60j
B0:AE66 90 18 5B mov DPTR, #B0_185B ; M
B0:AE69 E4 clr A
B0:AE6A 93 movc A, @A+DPTR
B0:AE6B FD mov R5, A
B0:AE6C 7F 97 mov R7, #0x97 ; 'ù'
B0:AE6E 7E 00 mov R6, #0
B0:AE70 12 F3 2C lcall BankSw_3_B0_F32C
B0:AE73 90 18 5C mov DPTR, #B0_185C ; T
B0:AE76 E4 clr A
B0:AE77 93 movc A, @A+DPTR
B0:AE78 FD mov R5, A
B0:AE79 7F 98 mov R7, #0x98 ; 'ÿ'
B0:AE7B 7E 00 mov R6, #0
B0:AE7D 12 F3 2C lcall BankSw_3_B0_F32C
B0:AE80 90 18 5D mov DPTR, #B0_185D ; 1
B0:AE83 E4 clr A
B0:AE84 93 movc A, @A+DPTR
B0:AE85 FD mov R5, A
B0:AE86 7F 99 mov R7, #0x99 ; 'Ö'
B0:AE88 7E 00 mov R6, #0
B0:AE8A 12 F3 2C lcall BankSw_3_B0_F32C
B0:AE8D 90 18 5E mov DPTR, #B0_185E ; 3
B0:AE90 E4 clr A
B0:AE91 93 movc A, @A+DPTR
B0:AE92 FD mov R5, A
B0:AE93 7F 9A mov R7, #0x9A ; 'Ü'
B0:AE95 7E 00 mov R6, #0
B0:AE97 12 F3 2C lcall BankSw_3_B0_F32C
B0:AE9A 90 18 5F mov DPTR, #B0_185F ; 6
B0:AE9D E4 clr A
B0:AE9E 93 movc A, @A+DPTR
B0:AE9F FD mov R5, A
B0:AEA0 7F 9B mov R7, #0x9B ; 'ø'
B0:AEA2 7E 00 mov R6, #0
B0:AEA4 12 F3 2C lcall BankSw_3_B0_F32C
B0:AEA7 90 18 60 mov DPTR, #B0_1860 ; 9
B0:AEAA E4 clr A
B0:AEAB 93 movc A, @A+DPTR
B0:AEAC FD mov R5, A
B0:AEAD 7F 9C mov R7, #0x9C ; '£'
B0:AEAF 7E 00 mov R6, #0
B0:AEB1 12 F3 2C lcall BankSw_3_B0_F32C
B0:AEB4 90 18 61 mov DPTR, #B0_1861 ; " "
B0:AEB7 E4 clr A
B0:AEB8 93 movc A, @A+DPTR
B0:AEB9 FD mov R5, A
B0:AEBA 7F 9D mov R7, #0x9D ; 'Ø'
B0:AEBC 7E 00 mov R6, #0
B0:AEBE 12 F3 2C lcall BankSw_3_B0_F32C
B0:AEC1 90 18 62 mov DPTR, #B0_1862 ; R
B0:AEC4 E4 clr A
B0:AEC5 93 movc A, @A+DPTR
B0:AEC6 FD mov R5, A
B0:AEC7 7F 9E mov R7, #0x9E ; '×'
B0:AEC9 7E 00 mov R6, #0
B0:AECB 12 F3 2C lcall BankSw_3_B0_F32C
B0:AECE 90 18 63 mov DPTR, #B0_1863 ; E
B0:AED1 E4 clr A
B0:AED2 93 movc A, @A+DPTR
B0:AED3 FD mov R5, A
B0:AED4 7F 9F mov R7, #0x9F ; 'ƒ'
B0:AED6 7E 00 mov R6, #0
B0:AED8 12 F3 2C lcall BankSw_3_B0_F32C
B0:AEDB 90 18 64 mov DPTR, #B0_1864 ; S
B0:AEDE E4 clr A
B0:AEDF 93 movc A, @A+DPTR
B0:AEE0 FD mov R5, A
B0:AEE1 7F A0 mov R7, #0xA0 ; 'á'
B0:AEE3 7E 00 mov R6, #0
B0:AEE5 12 F3 2C lcall BankSw_3_B0_F32C
B0:AEE8 90 18 65 mov DPTR, #B0_1865 ; E
B0:AEEB E4 clr A
B0:AEEC 93 movc A, @A+DPTR
B0:AEED FD mov R5, A
B0:AEEE 7F A1 mov R7, #0xA1 ; 'í'
B0:AEF0 7E 00 mov R6, #0
B0:AEF2 12 F3 2C lcall BankSw_3_B0_F32C
B0:AEF5 90 18 66 mov DPTR, #B0_1866 ; T
B0:AEF8 E4 clr A
B0:AEF9 93 movc A, @A+DPTR
B0:AEFA FD mov R5, A
B0:AEFB 7F A2 mov R7, #0xA2 ; 'ó'
B0:AEFD 7E 00 mov R6, #0
B0:AEFF 02 F3 2C ljmp BankSw_3_B0_F32C ; Neste ponto os registradores tem a string "MT1369 RESET"
B0:AEFF ; Atente para o fato de que aqui a instrução é "ljmp" e não "lcall"
B0:AEFF ; Por isso o RET não é necessário (já existe um na rotina)
B0:AF02 ; ---------------------------------------------------------------------------
B0:AF02
B0:AF02 B0_AF02: ; CODE XREF: B0_AE60+3j
B0:AF02 E4 clr A ; Zera a memória de XRAM_F897 a XRAM_F8A2
B0:AF03 FD mov R5, A
B0:AF04 7F 97 mov R7, #0x97 ; 'ù'
B0:AF06 FE mov R6, A
B0:AF07 12 F3 2C lcall BankSw_3_B0_F32C
B0:AF0A E4 clr A
B0:AF0B FD mov R5, A
B0:AF0C 7F 98 mov R7, #0x98 ; 'ÿ'
B0:AF0E FE mov R6, A
B0:AF0F 12 F3 2C lcall BankSw_3_B0_F32C
B0:AF12 E4 clr A
B0:AF13 FD mov R5, A
B0:AF14 7F 99 mov R7, #0x99 ; 'Ö'
B0:AF16 FE mov R6, A
B0:AF17 12 F3 2C lcall BankSw_3_B0_F32C
B0:AF1A E4 clr A
B0:AF1B FD mov R5, A
B0:AF1C 7F 9A mov R7, #0x9A ; 'Ü'
B0:AF1E FE mov R6, A
B0:AF1F 12 F3 2C lcall BankSw_3_B0_F32C
B0:AF22 E4 clr A
B0:AF23 FD mov R5, A
B0:AF24 7F 9B mov R7, #0x9B ; 'ø'
B0:AF26 FE mov R6, A
B0:AF27 12 F3 2C lcall BankSw_3_B0_F32C
B0:AF2A E4 clr A
B0:AF2B FD mov R5, A
B0:AF2C 7F 9C mov R7, #0x9C ; '£'
B0:AF2E FE mov R6, A
B0:AF2F 12 F3 2C lcall BankSw_3_B0_F32C
B0:AF32 E4 clr A
B0:AF33 FD mov R5, A
B0:AF34 7F 9D mov R7, #0x9D ; 'Ø'
B0:AF36 FE mov R6, A
B0:AF37 12 F3 2C lcall BankSw_3_B0_F32C
B0:AF3A E4 clr A
B0:AF3B FD mov R5, A
B0:AF3C 7F 9E mov R7, #0x9E ; '×'
B0:AF3E FE mov R6, A
B0:AF3F 12 F3 2C lcall BankSw_3_B0_F32C
B0:AF42 E4 clr A
B0:AF43 FD mov R5, A
B0:AF44 7F 9F mov R7, #0x9F ; 'ƒ'
B0:AF46 FE mov R6, A
B0:AF47 12 F3 2C lcall BankSw_3_B0_F32C
B0:AF4A E4 clr A
B0:AF4B FD mov R5, A
B0:AF4C 7F A0 mov R7, #0xA0 ; 'á'
B0:AF4E FE mov R6, A
B0:AF4F 12 F3 2C lcall BankSw_3_B0_F32C
B0:AF52 E4 clr A
B0:AF53 FD mov R5, A
B0:AF54 7F A1 mov R7, #0xA1 ; 'í'
B0:AF56 FE mov R6, A
B0:AF57 12 F3 2C lcall BankSw_3_B0_F32C
B0:AF5A E4 clr A
B0:AF5B FD mov R5, A
B0:AF5C 7F A2 mov R7, #0xA2 ; 'ó'
B0:AF5E FE mov R6, A
B0:AF5F 12 F3 2C lcall BankSw_3_B0_F32C
B0:AF62 22 ret
B0:AF62 ; End of function B0_AE60
E esta outra rotina decide qual das rotinas escrever. Ela faz isso de um modo bem mais elegante.
B0:EAAA ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
B0:EAAA
B0:EAAA
B0:EAAA B0_EAAA: ; CODE XREF: B0_B617+B0p
B0:EAAA ; B0_B617+DDp ...
B0:EAAA EF mov A, R7
B0:EAAB 24 FE add A, #0xFE ; '¦'
B0:EAAD 60 22 jz B0_EAD1 ; Grava "DISC UPGRADE" em XRAM_F997
B0:EAAF 04 inc A
B0:EAB0 70 3E jnz B0_EAF0 ; Apaga os registradores de XRAM_F897 a XRAM_F8A2
B0:EAB2 E4 clr A ; Grava "MT1369 RESET" em XRAM_F997
B0:EAB3 F5 40 mov RAM_40, A
B0:EAB5
B0:EAB5 B0_EAB5: ; CODE XREF: B0_EAAA+24j
B0:EAB5 E5 40 mov A, RAM_40
B0:EAB7 24 97 add A, #0x97 ; 'ù'
B0:EAB9 FF mov R7, A
B0:EABA E4 clr A
B0:EABB 33 rlc A
B0:EABC FE mov R6, A
B0:EABD E5 40 mov A, RAM_40
B0:EABF 90 18 5B mov DPTR, #B0_185B
B0:EAC2 93 movc A, @A+DPTR
B0:EAC3 FD mov R5, A
B0:EAC4 12 F3 2C lcall BankSw_3_B0_F32C
B0:EAC7 05 40 inc RAM_40
B0:EAC9 E5 40 mov A, RAM_40
B0:EACB C3 clr C
B0:EACC 94 0C subb A, #0xC
B0:EACE 40 E5 jc B0_EAB5
B0:EAD0 22 ret
B0:EAD1 ; ---------------------------------------------------------------------------
B0:EAD1
B0:EAD1 B0_EAD1: ; CODE XREF: B0_EAAA+3j
B0:EAD1 E4 clr A ; Grava "DISC UPGRADE" em XRAM_F997
B0:EAD2 F5 40 mov RAM_40, A
B0:EAD4
B0:EAD4 B0_EAD4: ; CODE XREF: B0_EAAA+43j
B0:EAD4 E5 40 mov A, RAM_40
B0:EAD6 24 97 add A, #0x97 ; 'ù'
B0:EAD8 FF mov R7, A
B0:EAD9 E4 clr A
B0:EADA 33 rlc A
B0:EADB FE mov R6, A
B0:EADC E5 40 mov A, RAM_40
B0:EADE 90 18 67 mov DPTR, #DISC_UPGRADE
B0:EAE1 93 movc A, @A+DPTR
B0:EAE2 FD mov R5, A
B0:EAE3 12 F3 2C lcall BankSw_3_B0_F32C
B0:EAE6 05 40 inc RAM_40
B0:EAE8 E5 40 mov A, RAM_40
B0:EAEA C3 clr C
B0:EAEB 94 0C subb A, #0xC
B0:EAED 40 E5 jc B0_EAD4
B0:EAEF 22 ret
B0:EAF0 ; ---------------------------------------------------------------------------
B0:EAF0
B0:EAF0 B0_EAF0: ; CODE XREF: B0_EAAA+6j
B0:EAF0 C2 34 clr RAM_26.4 ; Apaga os registradores de XRAM_F897 a XRAM_F8A2
B0:EAF2 12 AE 60 lcall B0_AE60 ; Grava (ou apaga) "MT1369 RESET" de XRAM_F897 a XRAM_F8A2
B0:EAF5 22 ret
B0:EAF5 ; End of function B0_EAAA
Para compreender essas rotinas só está me faltando entender qual o valor de "A" na linha destacada em vermelho acima. Só pode ser ou "0" ou "1". Se for "1" bagunça a lógica de endereçamento, porque uma rotina vai estar escrevendo a partir de XRAM_F897 enquanto a outra vai estar escrevendo a partir de XRAM_F997. Se for "0" o endereçamento "bate", mas a presença da instrução "rlc A" deixa de ter qualquer propósito.
Nota: para compreender as rotinas é preciso olhar o código no IDA e seguir algumas "lcall" para ver o que é feito nelas. Só olhar as listagens acima não basta.