Bom, acho que ficou um pouco grande. Ryan, se estiver ruim pode deletar.
Acho que a melhor maneira de entender o que foi feito é ir seguindo as explicações e visualizar, no IDA, as diferenças entre o firmware original e o modificado. Mas vamos às modificações.
Eu já tinha feito a rotina de cálculo do tempo restante inteira, com todas as considerações possíveis (minuto zera, roda para 59 e decrementa hora, segundo zera, roda para 59 e decrementa minuto e, se este estiver zerado, roda para 59 e decrementa hora, desde que a hora não seja 0...). Para os cálculos, transformava BCD em binário e depois em BCD de novo. Estava tudo funcionando, e então descobri que não precisava nada disso. O código ARM já tem tudo pronto. Além dos endereços 0260, 0261 e 0262 com o tempo total progressivo, 0270, 0271 e 0272 com o tempo total do capítulo e 0274, 0275 e 0276 com o tempo total do filme, descobri que para VCD o firmware usava os endereços 0268, 0269 e 026A para mostrar o tempo. E esse tempo é por capítulo!
Analisando os endereços a partir de 0270, vemos que estão em sequênca de 3, pula 1 e nova sequência de 3. Então, se tinha 0260, 0261 e 0262, poderia ser o caso de saltar o 0263, e alguma coisa haveria na sequência 0264, 0265 e 0266. E havia! E, para completar a lista de endereços, 026C, 026D e 026E! Dái, obtive a seguinte tabela para usar com ARM_GetChar:
R6 R7 Valor retornado em R7 (em BCD)
02 60 Horas, tempo total progressivo
02 61 Minutos, tempo total progressivo
02 62 Segundos, tempo total progressivo
02 64 Horas, tempo total restante
02 65 Minutos, tempo total restante
02 66 Segundos, tempo total restante
02 68 Horas, tempo progressivo do capítulo
02 69 Minutos, tempo progressivo do capítulo
02 6A Segundos, tempo progressivo do capítulo
02 6C Horas, tempo restante do capítulo
02 6D Minutos, tempo restante do capítulo
02 6E Segundos, tempo restante do capítulo
02 70 Horas, tempo do capítulo
02 71 Minutos, tempo do capítulo
02 72 Segundos, tempo do capítulo
02 73 Horas, tempo total
02 74 Minutos, tempo total
02 75 Segundos, tempo totalPara arquivos DivX, tempo de capítulo e tempo total são iguais.
Ao identificar a rotina que mostra o tempo na tela, vi que existiam 4 iguais. Uma para DivX (banco 3), outra para DVD (banco 1), outra para VCD/SVCD (banco 1) e a última eu não consegui descobrir para que tipo de filme seria (a deixei intocada). Para mp3 e CDs eu sei que não é, pois para esse tipo de conteúdo a forma de mostrar o tempo é diferente (a tela fica permanentemente no file browser, mostrando o tempo). Temos, então, algumas rotinas de sincronização do tempo, que chamam a respectiva "mostra tempo", sendo que uma delas sempre fica na rotina principal, chamada ao se apertar a tecla display. Além disso, cada rotina "mostra tempo" chama uma rotina que mostra a string "time" no final da página, no campo específico, quando o menu tempo está selecionado (função GO TO). Também, para cada tipo de conteúdo, temos uma rotina que mostra as setas < > nos menus da tecla display que possuem opções navegáveis à esquerda e à direita. E, por último, temos a rotina de roteamento do controle remoto que executa rotinas para algumas teclas pressionadas, levando em consideração o menu selecionado. Assim, foram feitas basicamente 4 alterações para cada tipo de conteúdo (DivX, DVD e VCD/SVCD):
1. Desvios nas rotinas de atualização/sincronia de tempo para uma rotina própria que possa condicionar os endereços de sincronia de tempo à opção escolhida pelo usuário.
2. Remoção do filtro que verifica se o menu tempo está selecionado e não imprime os símbolos < >.
3. Desvio na rotina que imprime a string "time" para uma rotina própria que possa condicionar a string exibida à opção escolhida pelo usuário.
4. Remoção de filtro e inclusão de desvio nas rotinas executadas após pressionar esquerda/direita quando o menu tempo está selecionado, para alterar as opções de exibição de tempo.
Vejamos as modificações para DivX:
A rotina mostra tempo começa em:
; mostra tempo DivX
B3:9F60
B3:9F60 B3_9F60: ; CODE XREF: B3_3827+22B_p
B3:9F60 ; B3:8A71_p ...
B3:9F60 90 FB E0 mov DPTR, #XRAM_FBE0
B3:9F63 EE mov A, R6
B3:9F64 F0 movx @DPTR, A
B3:9F65 A3 inc DPTR
B3:9F66 EF mov A, R7
B3:9F67 F0 movx @DPTR, A
B3:9F68 A3 inc DPTR
B3:9F69 EC mov A, R4
....
Ela possui uma flag (RAM_2E.2) que identifica se a posição tempo está selecionada ou não. Se estiver, o texto passa a ser de cor preta e fundo amarelo.
B3_A003: ; CODE XREF: B3_9F60+9B_j
B3:A003 30 72 1A jnb RAM_2E.2, B3_A020 ;flag
B3:A006 7F 01 mov R7, #1
B3:A008 12 56 38 lcall B3_5638
B3:A00B 90 FC 03 mov DPTR, #XRAM_FC03
B3:A00E 74 05 mov A, #5
B3:A010 F0 movx @DPTR, A
B3:A011 A3 inc DPTR
B3:A012 74 0F mov A, #0xF
B3:A014 F0 movx @DPTR, A
B3:A015 7B 05 mov R3, #5
B3:A017 7D 05 mov R5, #5
B3:A019 7F 02 mov R7, #2
B3:A01B 12 05 E9 lcall B3_BS_128_B5_B84C
B3:A01E 80 13 sjmp B3_A033
B3:A020 ; ---------------------------------------------------------------------------
B3:A020
B3:A020 B3_A020: ; CODE XREF: B3_9F60:B3_A003_j
B3:A020 90 FC 03 mov DPTR, #XRAM_FC03
B3:A023 74 01 mov A, #1
B3:A025 F0 movx @DPTR, A
B3:A026 A3 inc DPTR
B3:A027 74 0E mov A, #0xE
B3:A029 F0 movx @DPTR, A
B3:A02A 7B 01 mov R3, #1
B3:A02C 7D 01 mov R5, #1
B3:A02E 7F 02 mov R7, #2
B3:A030 12 05 E9 lcall B3_BS_128_B5_B84C
B3:A033
Os endereços de memória que guardam horas, minutos e segundos são #FDC1, #FDC2 e #FDC3, respectivamente.
São quatro rotinas que atualizam o tempo DivX e chamam a mostra tempo DivX:
Uma começa em B3_3827 e é a principal. É responsável por desenhar o menu quando apertamos a tecla display. O trecho que atualiza o tempo é o seguinte:
B3:38A5 7F 60 mov R7, #0x60 ; '`' ; atualiza tempo. tecla display pressionada
B3:38A7 7E 02 mov R6, #2
B3:38A9 12 03 A3 lcall B3_BS_31_B4_F1E6
B3:38AC 90 FD C1 mov DPTR, #XRAM_FDC1
B3:38AF EF mov A, R7
B3:38B0 F0 movx @DPTR, A
B3:38B1 7F 61 mov R7, #0x61 ; 'a'
B3:38B3 7E 02 mov R6, #2
B3:38B5 12 03 A3 lcall B3_BS_31_B4_F1E6
B3:38B8 90 FD C2 mov DPTR, #XRAM_FDC2
B3:38BB EF mov A, R7
B3:38BC F0 movx @DPTR, A
B3:38BD 7F 62 mov R7, #0x62 ; 'b'
B3:38BF 7E 02 mov R6, #2
B3:38C1 12 03 A3 lcall B3_BS_31_B4_F1E6
B3:38C4 90 FD C3 mov DPTR, #XRAM_FDC3
B3:38C7 EF mov A, R7
B3:38C8 F0 movx @DPTR, A
As outras começam em B3_5F36, B3_9E0B e B3_BA70 e possuem o mesmo trecho acima (uma atualiza o tempo enquanto os menus da tecla display são exibidos, outra quando saímos da função GO TO e outra acho que para quando navegamos pelos menus). Então, fiz uma interceptação em cada uma delas para a minha própria rotina que atualiza o tempo conforme a escolha do usuário (conforme o conteúdo do endereço #74 da EEPROM, escolhido por mim). No caso de DivX, para cada valor em #74 (0, 1 ou 2) ele vai atualizar os endereços de memória #FCC1, #FCC2 e #FCC3 com ARM_GetChar diferente (0260, 0261 e 0262 ou 0264, 0265 e 0266 ou 0274, 0275 e 0276). Só tive que tomar cuidado com a primeira rotina, na chamada principal da tecla display. Como não há opção no menu de preferência de tempo, inicialmente, quando se atualiza o firmware e o player resseta pela primeira vez, o valor no endereço #74 pode ser qualquer coisa. Então, a interceptação naquela rotina é um pouco diferente. Eu primeiro analiso se o valor é diferente de 0, 1 ou 2. Se for, atribuo 0 ao endereço #74. A melhor forma de ver como eu fiz isso é analisando o firmware com o IDA e analisar as modificações.
Mas como fazer a preferência do usuário ser gravada no endereço #74, da forma que o
zeurt sugeriu? Aí tive que modificar mais três rotinas e criar mais duas. A primeira rotina alterada foi a que exibe os símbolos < > (as setas de navegação esquerda e direita para sinalizar ao usuário que aquele menu possui opções selecionáveis à esquerda e à direita).
O começo dessa rotina é o seguinte e a parte a se modificar está comentada. Aquele trecho analisa qual a posição está selecionada. Se for a 1 (a segunda posição, começando em 0), é o menor tempo. Ao retirar o filtro, a posição 1 também passa a exibir as setas < e >.
B3_B6A2: ; CODE XREF: B3_32B3+3F_p
B3:B6A2 ; B3_5F36+E6_p ...
B3:B6A2 90 FB F2 mov DPTR, #XRAM_FBF2
B3:B6A5 EF mov A, R7
B3:B6A6 F0 movx @DPTR, A
B3:B6A7 90 FC 87 mov DPTR, #XRAM_FC87
B3:B6AA E0 movx A, @DPTR
B3:B6AB B4 17 03 cjne A, #0x17, B3_B6B1
B3:B6AE D3 setb C
B3:B6AF 80 01 sjmp B3_B6B2
B3:B6B1 ; ---------------------------------------------------------------------------
B3:B6B1
B3:B6B1 B3_B6B1: ; CODE XREF: B3_B6A2+9_j
B3:B6B1 C3 clr C
B3:B6B2
B3:B6B2 B3_B6B2: ; CODE XREF: B3_B6A2+D_j
B3:B6B2 40 03 jc B3_B6B7
B3:B6B4 02 B7 96 ljmp B3_B796
B3:B6B7 ; ---------------------------------------------------------------------------
B3:B6B7
B3:B6B7 B3_B6B7: ; CODE XREF: B3_B6A2:B3_B6B2_j
B3:B6B7 90 FB F2 mov DPTR, #XRAM_FBF2
B3:B6BA E0 movx A, @DPTR
B3:B6BB 64 01 xrl A, #1 ; evita simbolos < > no menu tempo
B3:B6BD 70 03 jnz B3_B6C2
B3:B6BF 02 B7 96 ljmp B3_B796
.....
Agora a parte mais interessante: a rotina de roteamento das teclas do controle remoto quando se aperta a tecla display. O seu começo é o seguinte:
B3:891B ; Roteamento teclas do controle remoto
B3:891B
B3:891B BankSw_249_B3_891B: ; DATA XREF: B0:B0_BS_249_B3_891B_o
B3:891B ; B1:B1_BS_249_B3_891B_o ...
B3:891B
B3:891B ; FUNCTION CHUNK AT B3:888A SIZE 00000008 BYTES
B3:891B ; FUNCTION CHUNK AT B3:8AD6 SIZE 00000003 BYTES
B3:891B
B3:891B D2 70 setb RAM_2E.0
B3:891D 90 FB 00 mov DPTR, #XRAM_FB00
B3:8920 E0 movx A, @DPTR
B3:8921 12 22 9A lcall B3_?C?CCASE
B3:8921 ; End of function BankSw_249_B3_891B
B3:8921
B3:8921 ; ---------------------------------------------------------------------------
B3:8924 8A 7B .word B3_8A7B
B3:8926 00 .byte 0
B3:8927 8A 7B .word B3_8A7B
B3:8929 01 .byte 1
B3:892A 8A 7B .word B3_8A7B
B3:892C 02 .byte 2
B3:892D 8A 7B .word B3_8A7B
B3:892F 03 .byte 3
B3:8930 8A 7B .word B3_8A7B
B3:8932 04 .byte 4
B3:8933 8A 7B .word B3_8A7B
B3:8935 05 .byte 5
B3:8936 8A 7B .word B3_8A7B
B3:8938 06 .byte 6
B3:8939 8A 7B .word B3_8A7B
B3:893B 07 .byte 7
B3:893C 8A 7B .word B3_8A7B
B3:893E 08 .byte 8
B3:893F 8A 7B .word B3_8A7B
B3:8941 09 .byte 9
B3:8942 8A 26 .word B3_8A26
B3:8944 0D .byte 0xD
B3:8945 8A 36 .word B3_8A36 ; Navega esquerda, menus tecla display
B3:8947 0E .byte 0xE
B3:8948 8A 3E .word B3_8A3E ; Navega direita, menus tecla display
B3:894A 0F .byte 0xF
B3:894B 8A 2E .word B3_8A2
....
Como explicado pelo pessoal do mt13x9 group, esta é um Char Case (?C?CCASE). Esta rotina, especificamente, verifica o valor de #FB00 (endereço que guarda a tecla pressionada no remoto) e chama rotinas de acordo com a tabela abaixo da chamada a ?C?CCASE. A tabela segue o padrão pule para a rotina "word XXYY" se o valor abaixo, "byte ZZ", estiver no endereço #FB00. Então, para os valores de 00 a 09, por exemplo, que são os códigos das teclas numéricas, ela chama a rotina B3_8A7B, que é a rotina reponsável por capturar os números digitados no remoto e repassar à rotina correspondente ao menu selecionado (função GO TO, se estivermos no menu tempo, função que chama o filme pelo número se estivermos na menu de filmes, função que chama as legendas pelo número etc).
Estamos preocupados com as teclas esquerda/direita. Como os valores #0E e #0F (eu testei com o MTKTool, enviando dados ao endereço #FB00) correspondem aos códigos das teclas esquerda e direita, seguimos as rotinas B3_8A36 e B3_8A3E e suas chamadas. A rotina B3_8A3E (seta direita), por exemplo, chama a rotina B3_6766, a qual, por sua vez, executa rotinas diferentes, conforme o menu selecionado. Ela possui um trecho que ignora (não faz nada) se a seleção estiver no menu tempo (posição 1). Temos que ter um cuidado, pois há um artifício hexadecimal aqui. Inicialmente ao valor da posição, é somado o valor #FE. Isso quer dizer que se a posição inicial for 2, passa a ser 0 (em 8 bits, 254 + 2 = 256 = 0 + carry), se for 1, passar a ser #FF, etc. Seguindo as contas após a soma e os decrementos, podemos achar o trecho em que se ignora a posição 1 (menu tempo):
B3:6766 ; Navega direita, menus tecla display
B3:6766
B3:6766 B3_6766: ; CODE XREF: B3:B3_8A3E_p
B3:6766 90 FD BD mov DPTR, #XRAM_FDBD
B3:6769 E0 movx A, @DPTR
B3:676A FF mov R7, A
B3:676B 74 01 mov A, #1
B3:676D 7E 00 mov R6, #0
B3:676F C8 xch A, R0
B3:6770 EF mov A, R7
B3:6771 C8 xch A, R0
B3:6772 08 inc R0
B3:6773 80 05 sjmp B3_677A
B3:6775 ; ---------------------------------------------------------------------------
B3:6775
B3:6775 B3_6775: ; CODE XREF: B3_6766:B3_677A_j
B3:6775 C3 clr C
B3:6776 33 rlc A
B3:6777 CE xch A, R6
B3:6778 33 rlc A
B3:6779 CE xch A, R6
B3:677A
B3:677A B3_677A: ; CODE XREF: B3_6766+D_j
B3:677A D8 F9 djnz R0, B3_6775
B3:677C FF mov R7, A
B3:677D 90 FD C4 mov DPTR, #XRAM_FDC4
B3:6780 E0 movx A, @DPTR
B3:6781 FD mov R5, A
B3:6782 E4 clr A
B3:6783 EF mov A, R7
B3:6784 5D anl A, R5
B3:6785 70 0E jnz B3_6795
B3:6787 7D 04 mov R5, #4
B3:6789 7F 02 mov R7, #2
B3:678B 12 CA 78 lcall BankSw_147_B3_CA78
B3:678E 7F 0A mov R7, #0xA
B3:6790 12 05 FB lcall B3_BS_131_B2_FDBD
B3:6793 D3 setb C
B3:6794 22 ret
B3:6795 ; ---------------------------------------------------------------------------
B3:6795
B3:6795 B3_6795: ; CODE XREF: B3_6766+1F_j
B3:6795 90 FD BD mov DPTR, #XRAM_FDBD
B3:6798 E0 movx A, @DPTR
B3:6799 24 FE add A, #0xFE ; '¦'
B3:679B 70 03 jnz B3_67A0
B3:679D 02 68 48 ljmp B3_6848
B3:67A0 ; ---------------------------------------------------------------------------
B3:67A0
B3:67A0 B3_67A0: ; CODE XREF: B3_6766+35_j
B3:67A0 14 dec A
B3:67A1 70 03 jnz B3_67A6
B3:67A3 02 68 B0 ljmp B3_68B0
B3:67A6 ; ---------------------------------------------------------------------------
B3:67A6
B3:67A6 B3_67A6: ; CODE XREF: B3_6766+3B_j
B3:67A6 24 03 add A, #3
B3:67A8 60 03 jz B3_67AD ; nao zero, menu tempo tecla display
B3:67AA 02 69 78 ljmp B3_6978
Então, alterei o endereço B3:67AA para que chame uma rotina que criei no final do bloco, a qual pega o valor do endereço #74 da EEPROM e o incrementa (é a tecla direita, certo?). Como são 3 opções para DivX (tempo, tempo restante e tempo total), se o valor chegar a 3, deve ser rodado para 0. Além disso, ela chama a rotina mostra tempo novamente para atualizar a string de exibição do tipo de tempo, modificação que veremos mais à frente. Para a tecla esquerda, a modificação é similar, pois as rotinas são praticamente iguais. Uma coisa importante: ao fazer as primeiras tentativas de modificações nessas rotinas, elas funcionaram, mas mesmo que eu continuasse mudando as opções, o menu sumia depois de um tempo (como se nenhuma tecla havia sido pressionada). Bom, seguindo a execução das rotinas para os outros menus, vi que havia sempre uma execução: carregar o registrador R7 com o valor #0A ou #03 e chamar a rotina B3_05FB (isso é para dar mais 10 ou 3 segundos de tempo de exibição do menu da tecla display). Assim, atribuí um valor de 3 a R7 e chamei B3_05FB no final das novas rotinas esquerda e direita, o que faz com que o menu continue sendo exibido enquanto estivermos navegando nas opções de tempo, por pelo menos 3 segundos após a última alteração.
A string "time" é a de número #0119 (podemos verificar com o MTK Lang Editor). E a rotina que mostra as strings com a descrição dos menus da tecla display para DivX começa em B3_5638 e o trecho responsável pela string "time", quando o menu tempo estiver selecionado, é o seguinte:
B3:56E0 B3_56E0: ; CODE XREF: B3_5638+90_j
B3:56E0 90 FB F3 mov DPTR, #XRAM_FBF3 ; string tempo?
B3:56E3 74 01 mov A, #1
B3:56E5 F0 movx @DPTR, A
B3:56E6 A3 inc DPTR
B3:56E7 74 19 mov A, #0x19
B3:56E9 F0 movx @DPTR, A
B3:56EA 80 16 sjmp B3_5702
Vemos que em #FBF3 é colocado o valor #01 e em #FBF4 o valor #19. Bom, como eu usei as strings #01A6 e #01E9 para tempo restante e tempo total, respectivamente (ainda criei as strings 01F2, 01F3 e 01F4 para os tempos de capítulo, mas isso não se aplica a DivX), eu fiz um salto nesse trecho, após armazenar o valor #1 em #FBF3, para uma rotina que novamente irá verificar o conteúdo do endereço #74 da EEPROM e decidir qual dos valores, #19, #A6 ou #E9, armazena em #FBF4. Assim, toda vez que selecionarmos o menu tempo, a string correta será exibida. Além disso, como dito anteriormente, quando o usuário navegar para a direita ou para a esquerda, as rotinas que atualizam o valor do endereço #74 EEPROM também chamam a "mostra tempo", fazendo a string se atualizar imediatamente.
Tempo de DVD:Para o caso do tempo de DVD, as mudanças praticamente são as mesmas. A posição do menu tempo agora é a 2 (terceiro menu). Uma das dificuldades foi que os scripts feitos para o IDA não identificaram essas rotinas corretamente. Alguns trechos ficaram truncados, como se fossem bytes perdidos, sem opção de visão gráfica. Mas as instruções estão lá. Basta termos mais cuidado. Em alguns casos, o IDA considerou que as instruções eram outras, cortando os opcodes no meio. Mas nesses poucos casos não houve modificações.
A rotina "mostra tempo" está em B1_A9B8. A maior diferença está nos endereços de memória usados agora para armazenar o tempo: #FDD0, #FDD1 e #FDD2 para horas, minutos e segundos, respectivamente. A flag de memória para indicar se o menu tempo está selecionado também é outro (RAM_2E.4). Os trechos das rotinas que atualizam o tempo são: B1_314D (não consegui identificar de forma rápida o início da rotina, devido ao problema no reconhecimento dos scripts, citado anteriormente, mas não perdi tempo com isso, pois não foi necessário), B1_4FB1 (que pertence à rotina principal do menu da tecla display, iniciada em B1_4F54), B1_7E00 (da rotina iniciada em B1_7DF4) e B1_9FAD (pertencente à rotina BankSw_381_B1_9F86). Aqui, a modificação é como antes: desvio para uma rotina que verifica a posição #74 da EEPROM e atualiza o tempo com os respectivos ARM_GetChar (mas agora são 6 opções, pois também há as opções de tempo por capítulo). E, na rotina principal, a verificação inicial do endereço #74 é para valores não maiores que 5.
Nota 1: Temos uma situação interessante. Se o usuário escolher como opção o tempo restante, será gravado o valor 1 na EEPROM, e esse ficará mantido para todo o tipo de filme que ele assistir depois, até que o usuário resolva mudar. Mas se ele preferir um tempo de capítulo, por exemplo, o tempo progressivo do capítulo (valor 3), quando ele for assistir um DivX, a rotina principal do menu display do DivX irá fazer aquela verificação inicial (se o valor é maior que 2) e retornará o valor para 0 (já que para DivX não há opção de tempo por capítulo) e o tempo ficará sendo o tempo normal (até que o usuário mude). Uma solução para isso seria usar endereços de EEPROM diferentes, mas também teríamos o problema de ter criado duas preferências diferentes, o que poderia confundir o usuário. Bom, isso é para pensar. A rotina de roteamento das teclas, seguida por sua tabela de rotinas para cada tecla, é a BankSw_199_B1_2880. Seguindo a tabela, vemos que a rotina para a tecla esquerda começa em B1_2B80 e a da tecla direita começa em B1_2DDE. A rotina que põe os símbolos < e > nos menus começa em B1_8061 e o trecho que exibe a string "time" está em B1_70FA, sendo que o início exato da rotina está numa faixa não corretamente identificada pelos scripts (como citado anteriormente). Lembrando que agora são 6 strings.
Nota 2: Outra coisa importante: como no caso do DivX, foi necessário adicionar um valor (escolhi 3 segundos de novo) a R7 e chamar #05FB no final das novas rotinas esquerda e direita. Mas, além disso, o sinal de proibido era exibido no canto da tela, como se as teclas não estivessem funcionando (apesar de estarem). Isso acontecia devido a outra execução (que não está presente nas rotinas correspondentes de DivX), que é atribuir o valor #1 a R7 e chamar a rotina B1_733D. Então, ao final das rotinas, também tive que realizar essa operação.Outra peculiaridade dos menus da tecla display para DVD está nos casos em que é impossível selecionar a função GO TO em alguns títulos de alguns filmes. Mudar isso é opcional, mas achei ruim o fato de o usuário selecionar um tipo de tempo no filme e, se entrar nos extras de alguns DVDs, ficar impossibilitado de alterar o tipo de tempo até que volte ao filme ou bote outro. Bom, as travas de navegação ao menu tempo estavam, como esperado, nas rotinas das teclas de navegação (direita, esquerda, cima e baixo). Elas foram tiradas nos seguintes trechos (lembrando que o menu tempo para DVDs está na posição 2):
Navegação tecla esquerda (inicio em B1_2B80):
B1:2B9E 5D anl A, R5
B1:2B9F 70 0F jnz B1_2BB0 ; se zero, titulo nao aceita tecla
B1:2BA1 7D 04 mov R5, #4
B1:2BA3 7F 02 mov R7, #2
B1:2BA5 12 06 5B lcall B1_BS_147_B3_CA78
B1:2BA8 7F 0A mov R7, #0xA
B1:2BAA 12 05 FB lcall B1_BS_131_B2_FDBD
B1:2BAD 02 33 E0 ljmp B1_33E0
Navegação tecla direita (início em B1_2DDE). Obs: há um erro dos que eu citei na identificação desta rotina pelo IDA. A quebra não existe e temos, na verdade, um LCALL para 065B:
B1:2DFB EF mov A, R7
B1:2DFC 5D anl A, R5
B1:2DFD 70 0F jnz B1_2E0E ; se zero, titulo nao aceita tecla
B1:2DFF 7D 04 mov R5, #4
B1:2E01 7F 02 mov R7, #2
B1:2E01 ; ---------------------------------------------------------------------------
B1:2E03 12 .byte 0x12
B1:2E04 06 .byte 6
B1:2E05
B1:2E05 ; =============== S U B R O U T I N E =======================================
B1:2E05
B1:2E05
B1:2E05 B1_2E05: ; CODE XREF: B1_2832_p
B1:2E05 5B anl A, R3
Navegação tecla cima (início em B1_2914):
B1:2A19 90 FB D4 mov DPTR, #XRAM_FBD4
B1:2A1C E0 movx A, @DPTR
B1:2A1D 64 02 xrl A, #2 ; proibe funcao go to em alguns titulos nao principais do DVD
B1:2A1F 70 03 jnz B1_2A24
B1:2A21 02 29 72 ljmp B1_2972
B1:2A24 ; -----------------------------
Navegação tecla baixo (início em B1_2A39)
B1:2B60 90 FB D4 mov DPTR, #XRAM_FBD4
B1:2B63 E0 movx A, @DPTR
B1:2B64 64 02 xrl A, #2 ; proibe funcao go to em alguns titulos nao principais do DVD
B1:2B66 70 03 jnz B1_2B6B
B1:2B68 02 2A 97 ljmp B1_2A97
E ainda havia uma "trava" na rotina principal de exibição do menu display, em que a modificação não se limitou apenas em retirar o filtro, como nas anteriores. Foi necessário saltar para uma rotina própria para tratar o caso melhor (se o menu tempo fosse o último a ser selecionado, ao apertar a tecla display novamente, ele estaria selecionado, mas o tempo congelado era mostrado, em vez dos traços da função GO TO):
B1:53AC 90 FD CC mov DPTR, #XRAM_FDCC
B1:53AF E0 movx A, @DPTR
B1:53B0 64 02 xrl A, #2 ; proibe menu tempo em alguns titulos
B1:53B2 70 31 jnz B1_53E5
E, para finalizar, VCD/SVCD:Novamente foram feitas as mesmas modificações, sem muito novidade. Não houve muitos problemas, como no caso do DVD. Na verdade, o menu é mais simples que o de DivX e as modificações são mais fáceis. O detalhe é que essas rotinas também ficam no bloco 1 e podem confundir com as de DVD. Além disso, como usam outros endereços de memória e outras flags, tive que criar rotinas só para elas também.
Rotina "mostra tempo": B1_A74D
Trechos que atualizam tempo: B1_40EA, B1_6D99 (rotina principal), B1_78CE e B1_7DF4.
Trecho que põe simbolos < >:
B1_C785:
mov DPTR, #XRAM_FBF0
mov A, R7
movx @DPTR, A
movx A, @DPTR
xrl A, #1 ; impede simbolos < > opcao tempo
jnz B1_C792
Rotina roteamento controle remoto: BankSw_202_B1_3B81
Trecho da string "time":
B1:73E2 B1_73E2: ; CODE XREF: B1_733D+90_j
B1:73E2 90 FB F1 mov DPTR, #XRAM_FBF1
B1:73E5 74 01 mov A, #1
B1:73E7 F0 movx @DPTR, A
B1:73E8 A3 inc DPTR
B1:73E9 74 19 mov A, #0x19 ; string tempo VCD
B1:73EB F0 movx @DPTR, A
B1:73EC 80 0A sjmp B1_73F8