FORUM.RYAN.COM.BR
Video e Audio => DivX Players => Firmware Mediatek MT13x9 - Desenvolvimento => Topic started by: rictad on September 30, 2009, 07:44:26 PM
-
Olá jmaraujo,
Olhando nos ARM codes do seu firmware, eu havia identificado a rotina sub_E64C como possível responsável pela exibição das legendas, mas achei ela muito diferente das usadas nos aparelhos LG. Porém, com o email que você me mandou, com várias identificações encontradas por você dos pontos mostrados no texto "MPEG4 Subtitle Display in ARM", eu pude confirmar que é ela mesma. Interessante que a rotina que origina a chamada a ela, que começa em sub_AEE4, é idêntica à que eu já identifiquei em alguns aparelhos LG.
Bom, o maior problema dessa rotina é que não dá para identificar de forma clara em que posição de RAM fica o buffer de legenda. Parece que o caractere é lido neste trecho:
ROM:0000E6F0 60 1C ADDS R0, R4, #1
ROM:0000E6F2 21 1C ADDS R1, R4, #0
ROM:0000E6F4 75 5C LDRB R5, [R6,R1] ; le caractere?
ROM:0000E6F6 00 06 LSLS R0, R0, #0x18
ROM:0000E6F8 00 0E LSRS R0, R0, #0x18
ROM:0000E6FA 04 1C ADDS R4, R0, #0
ROM:0000E6FC 0D 2D CMP R5, #0xD
A posição inicial do buffer está carregada em R6. Porém, o registrador R6 não tem a posição carregada diretamente. Isso ocorre aqui:
ROM:0000E66A 08 9E LDR R6, [SP,#0x38+var_18]
ROM:0000E66C 01 36 ADDS R6, #1
ROM:0000E66E 30 78 LDRB R0, [R6]
ROM:0000E670 01 36 ADDS R6, #1
Ele é carregado com o conteúdo de uma posição relativa ao Stack Pointer e depois incrementado 2 vezes. Então fica mais difícil saber exatamente o valor da primeira posição do buffer e procurar a região em que o buffer é preenchido, com a leitura do buffer primário (se é que no Philips tem isso).
De qualquer forma, a própria rotina que exibe a legenda possui um contador próprio para percorrer o buffer de legenda, de forma que é possível para você colocar um filtro de tags. Se olharmos novamente o trecho de leitura do caractere, podemos ver o contador:
ROM:0000E6F0 60 1C ADDS R0, R4, #1 ; adiciona 1 a R4, que é o contador, e guarda o valor em R0 para atualizar R4 depois.
ROM:0000E6F2 21 1C ADDS R1, R4, #0 ; temporariamente copia o valor atual do contador em R1
ROM:0000E6F4 75 5C LDRB R5, [R6,R1] ; le caractere, na posição atual R6+R1 = R6+R4
ROM:0000E6F6 00 06 LSLS R0, R0, #0x18 ; ainda não entendi essa sequencia, muito utilizada no ARM. a primeira multiplica R0 por 2^18
ROM:0000E6F8 00 0E LSRS R0, R0, #0x18 ; a segunda divide R0 por 2^18. R0 fica com o mesmo valor (R4 + 1). a utilidade deve ser zerar
; alguma flag ou truncar alguns bits de R0
ROM:0000E6FA 04 1C ADDS R4, R0, #0 ; o contador R4 é atualizado com o valor em R0, que é R4+1
ROM:0000E6FC 0D 2D CMP R5, #0xD ; caractere é quebra de linha?
A partir de ROM:0000E6F0, você pode tentar fazer algumas modificações, com um salto para uma rotina que filtra as tags. Segue um exemplo:
ROM:0000E6F0 21 1C ADDS R1, R4, #0 ; temporariamente copia o valor atual do contador em R1
ROM:0000E6F2 75 5C LDRB R5, [R6,R1] ; le caractere, na posição atual R6+R1 = R6+R4
ROM:0000E6F4 XX XX XX XX BL filtra_tag
ROM:0000E6F8 04 1C ADDS R4, R0, #0 ; o contador R4 é atualizado com o valor em R0, que é R4+1
ROM:0000E6FA 00 00 NOP ; pseudo nop
ROM:0000E6FC 0D 2D CMP R5, #0xD
....................................................................
....................................................................
3C 2D filtra_tag CMP R5, #0x3C ; caractere ="<"?
06 D1 BNE prossiga ; se não, vai embora
01 31 procura_fim_tag ADDS R1, R1, #1 ; se sim, atualiza contador para procurar fim da tag ">"
75 5C LDRB R5, [R6,R1]
3D 2D CMP R5, #0x3D ; caractere =">"?
FB D1 BNE procura_fim_tag ; se não, volta e continua procurando
01 31 ADDS R1, #1 ; se sim, atualiza contador para próximo caractere fora da tag
75 5C LDRB R5, [R6,R1]
F6 E7 B filtra_tag ; e se o próximo caractere for outra tag?
48 1C prossiga ADDS R0, R1, #1 ; atualiza contador em R0 para ser repassado a R4 depois
00 06 LSLS R0, R0, #0x18
00 0E LSLS R0, R0, #0x18
70 47 BX LR ; retorna
O problema dessa modificação é que ela considera que o buffer é infinito. Então, se tivermos uma tag enorme, por exemplo <akjkj............asas> maior que o buffer de legenda ou ainda se a tag começar em um quadro de legenda e só terminar em outro (são 2 situações bem raras, só uma legenda feita propositalmente com defeito teria isso), poderemos ter falhas na exibição da legenda. Caso queira evitar esse tipo de coisa, pode dar uma olhada no trecho que verifica o limite do contador R4:
ROM:0000E7D8 loc_E7D8 ; CODE XREF: sub_E64C:loc_E78E_j
ROM:0000E7D8 ; sub_E64C+14A_j ...
ROM:0000E7D8 03 98 LDR R0, [SP,#0x38+var_2C]
ROM:0000E7DA 84 42 CMP R4, R0
ROM:0000E7DC 88 D3 BCC loc_E6F0
Espero ter ajudado. Tudo isso é hipotético, pois precisa ser testado de fato.
-
Obrigadão, rictad. :yahoo!: Ficou muito claro e bem explicadinho. ;)
Vou dar uma olhada hoje a noite... ;D
-
Ah, esqueci. Só para confirmar se aquele é o ponto exato em que o caractere exibido é lido (eu sei que o caractere é lido ali, só não tenho certeza se é para ser exibido ou para cálculos, como largura, espaçamento etc.), troque a instrução em #E6F4 para:
ROM:0000E6F4 61 25 MOVS R5, 61 ; caractere "a"
Se na sua legenda aparecer somente a letra "a" como caractere, é o ponto certo. Se não, teremos que procurar outro ponto em que o caractere lido é enviado para exibição. Mas eu acho que é ali. 8)
-
Ok, muito obrigado.
-
Acho que você está certo. Isto é o que eu tenho analizado nesse endereço. Faz tanto tempo que fiz a análise que nem me lembrava direito:
ROM:0000E6F0 ProcessNextChar
ROM:0000E6F0 60 1C ADD R0, R4, #1
ROM:0000E6F2 21 1C ADD R1, R4, #0
ROM:0000E6F4 75 5C LDRB R5, [R6,R1]
ROM:0000E6F6 00 06 LSL R0, R0, #0x18
ROM:0000E6F8 00 0E LSR R0, R0, #0x18
ROM:0000E6FA 04 1C ADD R4, R0, #0
ROM:0000E6FC 0D 2D CMP R5, #0xD
ROM:0000E6FE 1C D1 BNE ProcessCurrentChar
ROM:0000E700 60 1C ADD R0, R4, #1
ROM:0000E702 00 06 LSL R0, R0, #0x18
ROM:0000E704 00 0E LSR R0, R0, #0x18
ROM:0000E706 21 1C ADD R1, R4, #0
ROM:0000E708 04 1C ADD R4, R0, #0
ROM:0000E70A 70 5C LDRB R0, [R6,R1]
ROM:0000E70C 0A 28 CMP R0, #0xA
ROM:0000E70E 3E D1 BNE JumpTO__Check_AllCharsDisplayed
-
Ah, esqueci. Só para confirmar se aquele é o ponto exato em que o caractere exibido é lido (eu sei que o caractere é lido ali, só não tenho certeza se é para ser exibido ou para cálculos, como largura, espaçamento etc.), troque a instrução em #E6F4 para:
ROM:0000E6F4 61 25 MOVS R5, 61 ; caractere "a"
Se na sua legenda aparecer somente a letra "a" como caractere, é o ponto certo. Se não, teremos que procurar outro ponto em que o caractere lido é enviado para exibição. Mas eu acho que é ali. 8)
Bem, o primeiro teste foi favorável: O texto exibido e um monte de "aaaaaaaaaaaaaaaaaaaa"... :laugh: Agora vou experimentar com o patch. :)
-
Infelizmente não funcionou... O player ficou travado com o seguinte texto na tela "úllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll". :(
-
Infelizmente não funcionou... O player ficou travado com o seguinte texto na tela "úllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll". :(
Bom, como o "a" passou no teste, então o ponto é ali mesmo. 8)
Deve haver algum erro na rotina. Algum detalhe. Mas o esquema é mais ou menos daquele jeito. Tenta ver como ficou no IDA depois da modificação, para ver se os códigos estão certos, se o BL ficou apontando para o endereço certo também e se os outros BRANCHS estão certos. Olha essas coisas, porque eu fiz o código de cabeça ;D. Vou conferir mais algumas coisas aqui.
-
Achei um erro. Mas o código está certo. Na penúltima linha da rotina:
00 0E LSLS R0, R0, #0x18
deve ser:
00 0E LSRS R0, R0, #0x18
EDIT: Você também pode tentar trocar o NOP em #E6FA por um NOP mais confiável, como #46 #C0 (MOVS R8,R8, o mais usado como NOP, até o IDA chama de NOP) ou #1C #00 (MOVS R0,R0), pois não estou absolutamente certo de #00 #00 (LSLS R0,R0,#0) ser totalmente um NOP. Acho que uma vez isso me deu problemas, mas não tenho certeza.
-
Ok, rictad, achei um erro no meu patch. Mas ainda não está dando certo. Agora o player não trava mas somente exibe dois pontos nas falas da legenda "..".
Aqui estão as minhas mudanças:
ROM:0000E6F0 ProcessNextChar
ROM:0000E6F0 21 1C ADD R1, R4, #0
ROM:0000E6F2 75 5C LDRB R5, [R6,R1]
ROM:0000E6F4 66 F0 7C FF BL Filtrado_de_Italicas
ROM:0000E6F8 04 1C ADD R4, R0, #0
ROM:0000E6FA C0 46 NOP
ROM:0000E6FC 0D 2D CMP R5, #0xD
ROM:0000E6FE 1C D1 BNE ProcessCurrentChar
ROM:0000E700 60 1C ADD R0, R4, #1
ROM:0000E702 00 06 LSL R0, R0, #0x18
ROM:0000E704 00 0E LSR R0, R0, #0x18
ROM:0000E706 21 1C ADD R1, R4, #0
ROM:0000E708 04 1C ADD R4, R0, #0
ROM:0000E70A 70 5C LDRB R0, [R6,R1]
ROM:0000E70C 0A 28 CMP R0, #0xA
ROM:0000E70E 3E D1 BNE JumpTO__Check_AllCharsDisplayed
E o patch:
ROM:000755F0 Filtrado_de_Italicas
ROM:000755F0 3C 2D CMP R5, #0x3C ; '<'
ROM:000755F2 06 D1 BNE Proseguir
ROM:000755F4
ROM:000755F4 Busca_End_Tag
ROM:000755F4 01 31 ADD R1, #1
ROM:000755F6 75 5C LDRB R5, [R6,R1]
ROM:000755F8 3D 2D CMP R5, #0x3D ; '='
ROM:000755FA FB D1 BNE Busca_End_Tag
ROM:000755FC 01 31 ADD R1, #1
ROM:000755FE 75 5C LDRB R5, [R6,R1]
ROM:00075600 F6 E7 B Filtrado_de_Italicas
ROM:00075602 ; ---------------------------------------------------------------------------
ROM:00075602
ROM:00075602 Proseguir
ROM:00075602 48 1C ADD R0, R1, #1
ROM:00075604 00 06 LSL R0, R0, #0x18
ROM:00075606 00 0E LSR R0, R0, #0x18
ROM:00075608 70 47 BX LR
ROM:00075608 ; End of function Filtrado_de_Italicas
-
Ok, rictad, achei um erro no meu patch. Mas ainda não está dando certo. Agora o player não trava mas somente exibe dois pontos nas falas da legenda "..".
Mas esses pontos aparecem em qualquer trecho ou só quando há alguma tag?
Descobri outro erro no código que te passei:
ROM:000755F8 3D 2D CMP R5, #0x3D ; '='
Na verdade, deve ser:
ROM:000755F8 3E 2D CMP R5, #0x3E ; '>' ; fim da tag
Aos poucos a gente vai acertando.
-
Faça o seguinte teste. Volte o trecho da rotina ao original e depois apenas tire as instruções de deslocamento. Assim:
ROM:0000E6F0 60 1C ADDS R0, R4, #1
ROM:0000E6F2 21 1C ADDS R1, R4, #0
ROM:0000E6F4 75 5C LDRB R5, [R6,R1] ; le caractere
ROM:0000E6F6 C0 46 NOP
ROM:0000E6F8 C0 46 NOP
ROM:0000E6FA 04 1C ADDS R4, R0, #0
ROM:0000E6FC 0D 2D CMP R5, #0xD
ROM:0000E6FE 1C D1 BNE loc_E73A
Vamos ver como isso afeta a legenda. Caso haja anomalias, como os pontos "..", pode ser que tenha faltado tratar melhor esses deslocamentos na rotina filtro.
-
Agora sim deu certo, rictad! :yahoo!:
Trocando o byte 3D (=) pelo 3E (>) o filtro funciona, mas com uma pequena ressalva: a legenda fica um pouco deslocada para a esquerda, como na seguinte imagem:
(http://img27.imageshack.us/img27/9623/legendal.jpg)
Ainda não fiz o segundo teste.
-
Não precisa fazer o outro teste não. Já que funcionou, não fará diferença. 8)
Com relação ao deslocamento, eu acho que sei o motivo. É devido ao(s) trecho(s) que calcula(m) a largura da linha para poder centralizar. Provavelmente o buffer de legenda é lido novamente, mas com as tags. Aí a legenda é centralizada levando as tags em consideração. Como não foi possível identificar o local do buffer primário (se o patch fosse feito lá, isso não aconteceria, pois o buffer secundário já ficaria sem as tags) a gente terá que identificar em que momento essa outra leitura é feita para fazer mais um patch. Certamente tem a ver com as rotinas SUB_CalcLineStartPosX ou SUB_GetCharWidth (ou ambas) que você já identificou.
Não sei se você já percebeu, mas isso tornou possível implementar o itálico light que o zeurt propôs no tópico do firmware do LG DV256k. ;)
-
Acho que tem de ser em SUB_CalcTextLineWidth. A rotina SUB_GetCharWidth faz parte do patch do wordwrap (o patch do Danny Moroz) e não do firmware original.
No meu patch de quebra de linhas eu tive que copiar boa parte dessa rutina (SUB_CalcTextLineWidth).
Esta parte de SUB_CalcTextLineWidth foi reutilizada no patch do wordwrap (a partir de ROM:00075386).
ROM:0000E3D4 34 49 LDR R1, =PB_B_Storage
ROM:0000E3D6 33 48 LDR R0, =unk_79FF0
ROM:0000E3D8 09 78 LDRB R1, [R1]
ROM:0000E3DA 00 68 LDR R0, [R0]
ROM:0000E3DC A1 23 MOV R3, #0xA1 ; 'í'
ROM:0000E3DE 40 5C LDRB R0, [R0,R1]
ROM:0000E3E0 1B 01 LSL R3, R3, #4
ROM:0000E3E2 32 49 LDR R1, =unk_79FEC
ROM:0000E3E4 58 43 MUL R0, R3
ROM:0000E3E6 09 68 LDR R1, [R1]
ROM:0000E3E8 40 18 ADD R0, R0, R1
ROM:0000E3EA 80 19 ADD R0, R0, R6
ROM:0000E3EC 00 7C LDRB R0, [R0,#0x10]
-
Acho que tem de ser em SUB_CalcTextLineWidth.
Isso, é ela mesma! Está lá o ponto em que o buffer é lido novamente. É só fazer um patch parecido e pronto. Acho que vai centralizar. Depois eu posto o patch aqui.
-
Algumas mudanças que eu fiz no patch do wordwrap:
Antes:
ROM:0000E66E Display_subtitle
ROM:0000E66E 30 78 LDRB R0, [R6]
ROM:0000E670 01 36 ADD R6, #1
ROM:0000E672 03 90 STR R0, [SP,#0x38+SubtitleTextLength]
ROM:0000E674 03 98 LDR R0, [SP,#0x38+SubtitleTextLength]
ROM:0000E676 FF 28 CMP R0, #0xFF
ROM:0000E678 01 D9 BLS loc_E67E
ROM:0000E67A FF 20 MOV R0, #0xFF
ROM:0000E67C 03 90 STR R0, [SP,#0x38+SubtitleTextLength]
ROM:0000E67E
ROM:0000E67E loc_E67E
ROM:0000E67E 03 99 LDR R1, [SP,#0x38+SubtitleTextLength] <-- O código foi mudado daqui
ROM:0000E680 00 20 MOV R0, #0
ROM:0000E682 70 54 STRB R0, [R6,R1] <-- até aqui
ROM:0000E684 30 1C ADD R0, R6, #0
Depois:
ROM:0000E66E Display_subtitle
ROM:0000E66E 30 78 LDRB R0, [R6]
ROM:0000E670 01 36 ADD R6, #1
ROM:0000E672 03 90 STR R0, [SP,#0x38+SubtitleTextLength]
ROM:0000E674 03 98 LDR R0, [SP,#0x38+SubtitleTextLength]
ROM:0000E676 FF 28 CMP R0, #0xFF
ROM:0000E678 01 D9 BLS loc_E67E
ROM:0000E67A FF 20 MOV R0, #0xFF
ROM:0000E67C 03 90 STR R0, [SP,#0x38+SubtitleTextLength]
ROM:0000E67E
ROM:0000E67E loc_E67E
ROM:0000E67E 69 46 MOV R1, SP
ROM:0000E680 0C 31 ADD R1, #0xC
ROM:0000E682 C0 46 NOP
ROM:0000E684 30 1C ADD R0, R6, #0
Outra coisa interessante que diz no documento do wordwrap: "For stack variable SubtitleTextLength find it's offset from SP."
LDR R0, [SP,#0x30+SubtitleTextLength]No meu player o Offset = C
-
O segundo patch pode ser assim:
ROM:0000E39C 21 1C ADDS R1, R4, #0 ; temporariamente copia o valor atual do contador em R1
ROM:0000E39E 7E 5C LDRB R6, [R7,R1] ; le caractere, na posição atual R7+R1 = R7+R4
ROM:0000E3A0 XX XX XX XX BL filtra_tag2
ROM:0000E3A4 04 1C ADDS R4, R0, #0 ; o contador R4 é atualizado com o valor em R0, que é R4+1
ROM:0000E3A6 C0 46 NOP ; pseudo nop
ROM:0000E3A8 00 2E CMP R6, #0
....................................................................
....................................................................
3C 2E filtra_tag2 CMP R6, #0x3C ; caractere ="<"?
06 D1 BNE prossiga2 ; se não, vai embora
01 31 procura_fim_tag2 ADDS R1, R1, #1 ; se sim, atualiza contador para procurar fim da tag ">"
7E 5C LDRB R6, [R7,R1]
3E 2E CMP R6, #0x3E ; caractere =">"?
FB D1 BNE procura_fim_tag2 ; se não, volta e continua procurando
01 31 ADDS R1, #1 ; se sim, atualiza contador para próximo caractere fora da tag
7E 5C LDRB R6, [R7,R1]
F6 E7 B filtra_tag2 ; e se o próximo caractere for outra tag?
48 1C prossiga2 ADDS R0, R1, #1 ; atualiza contador em R0 para ser repassado a R4 depois
00 06 LSLS R0, R0, #0x18
00 0E LSRS R0, R0, #0x18
70 47 BX LR ; retorna
Veja que agora o buffer está em R7 e é lido em R6. Só confere os códigos do IDA antes, porque fazer isso na mão às vezes falha... ;D
Se der tudo certo, a legenda estará centralizada mesmo quando houver tags escondidas.
-
Outra coisa interessante que diz no documento do wordwrap: "For stack variable SubtitleTextLength find it's offset from SP."
LDR R0, [SP,#0x30+SubtitleTextLength]No meu player o Offset = C
Certo, vi a modificação aqui:
ROM:0000E67E 69 46 MOV R1, SP
ROM:0000E680 0C 31 ADDS R1, #0xC
Mas como você descobriu esse offset? No original era assim:
ROM:0000E67E 03 99 LDR R1, [SP,#0x38+SubtitleTextLength]
Como é possível saber o valor do offset guardado nessas variáveis somadas a SP? No IDA eu nunca consegui descobrir....
-
Faça clique com a tecla direita do mouse sobre o texto SubtitleTextLenght e esolha a opção #16. Ou faça clique no texto e presione a tecla "Q".
-
Agora sim, perfeito! Muito obrigado pela ajuda, rictad! ;D
Antes:
(http://img27.imageshack.us/img27/9623/legendal.jpg)
Agora:
(http://img59.imageshack.us/img59/402/legenda2.jpg)
-
Faça clique com a tecla direita do mouse sobre o texto SubtitleTextLenght e esolha a opção #16. Ou faça clique no texto e presione a tecla "Q".
Ah... isso facilita as coisas!
Mesmo assim, identificar corretamente o ponteiro do buffer de legenda fica difícil, pois temos que rastrear o Stack Pointer. O endereço é carregado assim em R6, então:
ROM:0000E66A 08 9E LDR R6, [SP,#0x20]
Porém, no início da rotina temos um PUSH que, como se sabe, incrementa a pilha (SP):
ROM:0000E64C F1 B5 PUSH {R0,R4-R7,LR}
Pelo que eu acho, isso deve incrementar o SP em uma palavra (4 bytes) para cada registrador guardado. Ainda não tenho certeza, mas acho que são 6 registradores (R0, de R4 a R7 e o LR). Então SP é incrementado com um offset de 24. Mas, em seguida, temos a instrução:
ROM:0000E64E 88 B0 SUB SP, SP, #0x20
Isso retira 32 (em decimal) do SP.
Então, se todos os cálculos estiverem certos, o LDR R6, [SP,#0x20] carrega em R6 o valor guardado na posição apontada por SP logo após o PUSH (já que o offset de 32 anula o -32 no SUB). Ainda teríamos que percorrer as rotinas prévias (das chamadas originárias) para ver o que foi carregado em SP nessa posição, descontados PUSHs, POPs, incrementos e decrementos de SP.
Agora sim, perfeito! Muito obrigado pela ajuda, rictad! ;D
De nada, jmaraujo. Era só para inibir as tags, mas veja que o Ryan nos botou agora no caminho do itálico. :laugh: Depois desse trabalho, será bem mais fácil implementar o itálico.
-
De nada, jmaraujo. Era só para inibir as tags, mas veja que o Ryan nos botou agora no caminho do itálico. :laugh: Depois desse trabalho, será bem mais fácil implementar o itálico.
É, mas eu não quero abusar da sua ajuda... :oops:
Muitas coisas se passaram desde este post (http://www.forodvp5100.com.ar/viewtopic.php?f=12&t=653) até hoje... Até onde eu sei, o seu player é o único no mundo a implementar o itálico! ;D :clapping:
-
De nada, jmaraujo. Era só para inibir as tags, mas veja que o Ryan nos botou agora no caminho do itálico. :laugh:
Ooops! ;D
Corrigi o título do tópico!
-
É, mas eu não quero abusar da sua ajuda... :oops:
Muitas coisas se passaram desde este post (http://www.forodvp5100.com.ar/viewtopic.php?f=12&t=653) até hoje... Até onde eu sei, o seu player é o único no mundo a implementar o itálico! ;D :clapping:
Que abusar, que nada. Quando tiver dúvida, é só perguntar. Podemos implementar aos poucos.
Seria interessante, agora, descobrir em qual posição de memória fica guardada a opção de alinhamento vertical ou, caso esta não exista, a opção de alinhamento horizontal. Talvez você já as tenha identificado. Estão nos offsets da rotina SUB_FillMpeg4SubtitleParamsRecord:
ROM:0000E350 sub_E350 ; CODE XREF: sub_AA2A+47_p
ROM:0000E350 02 78 LDRB R2, [R0]
ROM:0000E352 52 49 LDR R1, =unk_7A380
ROM:0000E354 0A 72 STRB R2, [R1,#8]
ROM:0000E356 83 78 LDRB R3, [R0,#2]
ROM:0000E358 42 78 LDRB R2, [R0,#1]
ROM:0000E35A 1B 02 LSLS R3, R3, #8
ROM:0000E35C 1A 43 ORRS R2, R3
ROM:0000E35E 0A 80 STRH R2, [R1]
ROM:0000E360 03 79 LDRB R3, [R0,#4]
ROM:0000E362 C2 78 LDRB R2, [R0,#3]
ROM:0000E364 1B 02 LSLS R3, R3, #8
ROM:0000E366 1A 43 ORRS R2, R3
ROM:0000E368 4A 80 STRH R2, [R1,#2]
ROM:0000E36A 83 79 LDRB R3, [R0,#6]
ROM:0000E36C 42 79 LDRB R2, [R0,#5]
ROM:0000E36E 1B 02 LSLS R3, R3, #8
ROM:0000E370 1A 43 ORRS R2, R3
ROM:0000E372 8A 80 STRH R2, [R1,#4]
ROM:0000E374 03 7A LDRB R3, [R0,#8]
ROM:0000E376 C2 79 LDRB R2, [R0,#7]
ROM:0000E378 1B 02 LSLS R3, R3, #8
ROM:0000E37A 1A 43 ORRS R2, R3
ROM:0000E37C CA 80 STRH R2, [R1,#6]
ROM:0000E37E 42 7A LDRB R2, [R0,#9]
ROM:0000E380 4A 72 STRB R2, [R1,#9]
ROM:0000E382 82 7A LDRB R2, [R0,#0xA]
ROM:0000E384 8A 72 STRB R2, [R1,#0xA]
ROM:0000E386 C0 7A LDRB R0, [R0,#0xB]
ROM:0000E388 C8 72 STRB R0, [R1,#0xB]
ROM:0000E38A 70 47 BX LR
Com uma dessas posições, de preferência a que guarda o alinhamento vertical, fica mais fácil ter um local para guardar a flag indicativa do itálico e até mesmo a opção de ligar/desligar itálicos.
Ooops! ;D
Corrigi o título do tópico!
Talvez você tenha que corrigir de novo em breve. ;D
-
Jmaraujo,
Tem como você disponibilizar os ARM codes do firmware após ter colocado o filtro? Queria dar uma olhada depois para estudar a implementação do itálico. Se você não estiver fazendo o mesmo, claro. ;)
-
Tem como você disponibilizar os ARM codes do firmware após ter colocado o filtro? Queria dar uma olhada depois para estudar a implementação do itálico.
Mas é claro! ;) Por email hoje eu mando somente os ArmCodes, e no sábado ou domingo eu posto o firmware completo aqui no fórum. ;D
Se você não estiver fazendo o mesmo, claro. ;)
Vai ser difícil. :laugh: Sem a sua ajuda não teria feito nem o filtrado dos tags, muito menos a implementação do itálico!!! :P O meu conhecimento do Arm é muito limitado. Me sinto mais a vontade com o 8032.
-
Rictad, como ficaria o menu dos tags do italico? É uma tarefa que eu posso ir adiantando aqui.
São tres opções, certo? Ficaria assim?: 1) Mostrar o itálico, 2) Filtrar os tags e 3) Não fazer nada.
Qual o valor para cada opção, 0, 1 e 2?
-
Mas é claro! ;) Por email hoje eu mando somente os ArmCodes, e no sábado ou domingo eu posto o firmware completo aqui no fórum. ;D
Recebi o e-mail!
Rictad, como ficaria o menu dos tags do italico? É uma tarefa que eu posso ir adiantando aqui.
São tres opções, certo? Ficaria assim?: 1) Mostrar o itálico, 2) Filtrar os tags e 3) Não fazer nada.
Qual o valor para cada opção, 0, 1 e 2?
Sim, 3 opções são suficientes. O valor vai depender. Para repassar o valor ao ARM, é mais fácil utilizar os bits de uma outra opção que não faça uso de todos os seus bits. Fazemos um OR e fundimos as duas opções no mesmo byte.
Por exemplo, no meu caso, usei a opção de alinhamento vertical da legenda. Percebi que o alinhamento vertical só depende de 1 bit. Se a opção for 0, o alinhamento é inferior, se for 1, superior. Se for 2, novamente inferior, 3, superior. Só há duas opções de fato, que são rotativas. Então, o alinhamento é definido apenas pelo bit 0 do byte da opção. Se for XXXXXXX0, o alinhamento é inferior. Se for XXXXXXX1, o alinhamento é superior.
Assim, foi possível utilizar os demais bits para passar outras opções do 8032 ao ARM. Deixei o bit 7 para ser usado como flag indicativa de itálico ativado/desativado (tag <i> encontrada ou tag </i> encontrada) na rotina de itálico no próprio ARM. Já os bits 6, 5 e 4 foram usados para as opções. Precisei de 3 bits devido à quantidade de opções que criei.
Como você utilizará apenas 3 opções, bastariam apenas 2 bits: o 6 e o 5. Então daria para utilizar o valor 00000000 = #00 para "Não fazer nada", o valor 00100000 = #20 para "Filtrar as tags" e valor 01000000 = #40 para "Habilitar itálico". Na hora de repassar ao ARM, basta ler a EEPROM com essa opção, fazer um OR com o valor de EEPROM da opção de alinhamento vertical e repassar o resultado junto com o alinhamento. Então teremos combinações, como:
01000000 + 00000001 = 01000001 --> Alinhamento superior e itálico ligado;
00100000 + 00000000 = 00100000 --> Alinhamento inferior e filtrar tags.
e todas as demais combinações.
O mais importante agora é saber como são os ciclos das opções de alinhamento de legenda (pode ser das cores de legenda também) do seu firmware. Você deve seguir os seguintes passos:
O seu firmware tem opção de alinhamento vertical? Se sim, você deve testar os valores 0, 1, 2, 3 e os valores #20, #21, #22, #23, #40, #41, #42 e #43 para ver se o padrão de alinhamento se repete: o alinhamento deve ser o mesmo para 0, #20 e #40, o mesmo para 1, #21 e #41, o mesmo para 2, #22 e #42 e o mesmo para 3, #23 e #43. Se isso se confirmar, você deve criar as opções do itálico com valores 0, #20 e #40 e fazer um OR com a opção de alinhamento vertical antes de enviá-la ao ARM.
Se o seu firmware não tem opção de alinhamento vertical, tente o mesmo com o horizontal. Se não tiver também, então é porque você deixou os alinhamentos padrões do firmware. Ainda assim, pode testar mudar um dos dois diretamente no firmware para ver se segue os ciclos acima. Se seguir, então basta criar as opções de itálico e fazer o OR com o valor padrão do alinhamento antes de enviá-lo. Também é possível tentar testar a opção de cor da legenda para ver se há ciclos. Mas como há mais cores que alinhamentos, a opção de cor deve utilizar mais bits.
Em todo caso, deverá descobrir em qual posição na rotina SUB_FillMpeg4SubtitleParamsRecord (sub_E350) a opção de alinhamento (ou outra escolhida) fica carregada no ARM, para utilizarmos na rotina do itálico. Isso é fácil.
Talvez tenha ficado meio confuso. ;D Qualquer dúvida, é só perguntar. O padrão de ciclos das opções também pode ser outro, especialmente se os bits que importam forem mais significativos. Neste caso, as opções terão que ter outro valor. Mas eu acho que será igual aos LGs.
Enfim, tente descobrir alguma opção da legenda, preferencialmente um dos alinhamentos, que seja cíclica e dependa de poucos bits para a gente começar as modificações.
-
Sim, o meu firmware tem alinhamento vertical.
Poxa, pensei que fosse mais fácil :( Algo do tipo: no inicio do patch ler o endereço da EEPROM, se for 0, sair/retornar; se for 1, pular para o filtrado do itálico; se for 2, pular para a rotina do itálico.
Não me sinto capacitado para tal tarefa. :( :( :(
-
É porque eu escrevi demais ;D, mas acredite, é bem simples.
Quais os valores das opções de menu do seu alinhamento vertical?
-
0 e 1:
5. No Pic. | Vertical alignment | Set the vertical alignment
0008 FFFF 056C 058E 0063 0000 0001 0001 FFF989 0000 - ROM:F920
1. Top | Top | [00]
0590 0590 0561 00 - ROM:F974
=> 2. Bottom | Bottom | [00]
058F 058F 0561 01 - ROM:F97B
-
Mas, é possivel assim como eu disse? Fica mais fácil, ou mais difícil?
-
Mas, é possivel assim como eu disse? Fica mais fácil, ou mais difícil?
Sim, mas é assim mesmo. O que você disse é como realmente será feito no ARM, só que não com aqueles valores (muito provavelmente com 0, #20 e #40). Eu estava falando no 8032, para criar a opção no menu. Como descobrir os valores e repassá-los ao ARM.
0 e 1:
5. No Pic. | Vertical alignment | Set the vertical alignment
0008 FFFF 056C 058E 0063 0000 0001 0001 FFF989 0000 - ROM:F920
1. Top | Top | [00]
0590 0590 0561 00 - ROM:F974
=> 2. Bottom | Bottom | [00]
058F 058F 0561 01 - ROM:F97B
Se e quando você tiver tempo, apenas teste os valores #20 (top) e #21 (bottom), #40 (top) e #41 (bottom) e #80 (top) e #81 (bottom). Se a opção de alinhamento vertical funcionar do mesmo jeito com esses valores, apenas crie o menu dos itálicos com as 3 opções que você sugeriu, com os valores 00, #20 e #40 e deixe o resto comigo.
-
Ok, agora é que eu entendi. Depois eu posto aqui os resultados. ;D
Muito obrigado. ;)
-
Beleza!
Eu estou quase conseguindo um DVP5100K! Hoje, descobri que minha irmã tem um aparelho. Ela vai me emprestar e poderei ajudar nos testes. ;D
-
O itálico para o DVP5100 está pronto e funcionando! :yahoo!:
Acabei de testar. Modifiquei aquelas 2 rotinas para que permitissem também o itálico. E incluí mais 1 para desfazer o itálico no início de cada quadro.
Além disso, já deixei tudo pronto para receber 3 opções de menu, que são: mostrar tags, esconder tags, ligar itálico.
Jmaraujo,
se você quiser, é só criar um menu, por exemplo, "tags SRT", com as três opções e os seguintes valores (somente podem ser esses os valores, em hexadecimal):
#40 para "mostrar todas as tags"
#20 para "esconder todas as tags"
#00 para "habilitar o itálico"
Você pode escolher o endereço de EEPROM que quiser. Mas lembre-se, o valor deve ser mesclado, utilizando a operação OR, com o valor da opção de alinhamento horizontal!. Isso quer dizer que você deve modificar, no 8032, o trecho que lê a opção de alinhamento horizontal para que também leia a opção de tags. Aí você faria um OR entre os 2 valores e enviaria o resultado como se fosse o valor de alinhamento. Porém, como eu ainda não tenho certeza se a posição de memória que usei no ARM realmente corresponde ao alinhamento horizontal, deixe essa parte do OR para depois de eu realizar mais alguns testes. Mesmo sem as opções, temos o itálico light: sempre funciona quando encontra as tags de itálico e as demais tags ficam ocultas. ;D
Eu também vi que você dasabilitou o alinhamento horizontal na última versão do seu firmware. Isso não faz diferença. Seria só mesclar o valor da opção de tags com o valor default de alinhamento que você deixou. Se um dia voltar a habilitar o alinhamento horizontal, não fará diferença.
A última providência é com relação às fontes. Para testar, eu troquei sua Fonte 1 pela Arial Narrow Bold do meu firmware, com 479 caracteres. As fontes devem ter os 256 primeiros caracteres normais e os últimos 223 itálicos, pois correspondem ao itálico dos caracteres a partir do código 33 (não faz sentido itálico nos anteriores e podemos economizar espaço). Não precisei substituir nenhuma das demais fontes pela fonte de apenas 1 caractere para compensar o espaço. Pelo visto, seu firmware terá menos problemas com o espaço das fontes, mas não sei o que acontecerá se todas as 8 forem aumentadas. Talvez você terá que reduzir (excluir) alguma. As fontes que não são substituídas não exibem nenhum caractere quando o texto está em itálico. Notei que nossas fontes possuem alguns poucos caracteres diferentes, o que talvez as torne parcialmente incompatíveis. Além disso, eu só fiz 4 fontes, as quais podem não ser boas para você. Então talvez você tenha um trabalho adicional com as fontes. Porém, nada impede que você utilize minhas fontes e deixe apenas algumas fontes do seu player com suporte a itálico. As informações sobre as fontes estão lá no tópico do LG DV397H.
Amanhã eu posto as rotinas comentadas e envio um email para você com o firmware modificado para que possa testá-lo.
-
Excelentes noticias! Hoje eu vou postar o firmware v1.4 com o filtrado de itálicas e já começo com o trabalho do itálico para a versão 1.5.
A versão 1.4 volta a ter o alinhamento horizontal e vertical. De uma olhada no seu email que estou enviando a v1.4 "quase pronta" que tenho usado nos meus testes aqui, caso precisar fazer testes.
-
Certo Jmaraujo,
Vou fazer testes com o alinhamento da nova versão. Também enviarei para você o 1.3 com itálico para você testar.
Seguem as rotinas do itálico (patchs) no ARM, ainda sem comentários.
Inibe tags ou habilita itálico na rotina principal:
ROM:000755F0 sub_755F0 ; CODE XREF: sub_E64C+A8_p
ROM:000755F0 ; sub_75670+6_p
ROM:000755F0 2A 4A LDR R2, =unk_7A380
ROM:000755F2
ROM:000755F2 loc_755F2 ; CODE XREF: sub_755F0+20_j
ROM:000755F2 53 7A LDRB R3, [R2,#9]
ROM:000755F4 60 20 MOVS R0, #0x60 ; '`'
ROM:000755F6 03 40 ANDS R3, R0
ROM:000755F8 40 2B CMP R3, #0x40 ; '@'
ROM:000755FA 2E D0 BEQ loc_7565A
ROM:000755FC 3C 2D CMP R5, #0x3C ; '<'
ROM:000755FE 24 D1 BNE loc_7564A
ROM:00075600 20 2B CMP R3, #0x20 ; ' '
ROM:00075602 06 D1 BNE loc_75612
ROM:00075604
ROM:00075604 loc_75604 ; CODE XREF: sub_755F0+1A_j
ROM:00075604 ; sub_755F0+30_j ...
ROM:00075604 01 31 ADDS R1, #1
ROM:00075606 75 5C LDRB R5, [R6,R1]
ROM:00075608 3E 2D CMP R5, #0x3E ; '>'
ROM:0007560A FB D1 BNE loc_75604
ROM:0007560C
ROM:0007560C loc_7560C ; CODE XREF: sub_755F0+3A_j
ROM:0007560C ; sub_755F0+58_j
ROM:0007560C 01 31 ADDS R1, #1
ROM:0007560E 75 5C LDRB R5, [R6,R1]
ROM:00075610 EF E7 B loc_755F2
ROM:00075612 ; ---------------------------------------------------------------------------
ROM:00075612
ROM:00075612 loc_75612 ; CODE XREF: sub_755F0+12_j
ROM:00075612 01 31 ADDS R1, #1
ROM:00075614 75 5C LDRB R5, [R6,R1]
ROM:00075616 69 2D CMP R5, #0x69 ; 'i'
ROM:00075618 08 D1 BNE loc_7562C
ROM:0007561A 01 31 ADDS R1, #1
ROM:0007561C 75 5C LDRB R5, [R6,R1]
ROM:0007561E 3E 2D CMP R5, #0x3E ; '>'
ROM:00075620 F0 D1 BNE loc_75604
ROM:00075622 53 7A LDRB R3, [R2,#9]
ROM:00075624 80 20 MOVS R0, #0x80 ; 'Ç'
ROM:00075626 03 43 ORRS R3, R0
ROM:00075628 53 72 STRB R3, [R2,#9]
ROM:0007562A EF E7 B loc_7560C
ROM:0007562C ; ---------------------------------------------------------------------------
ROM:0007562C
ROM:0007562C loc_7562C ; CODE XREF: sub_755F0+28_j
ROM:0007562C 2F 2D CMP R5, #0x2F ; '/'
ROM:0007562E E9 D1 BNE loc_75604
ROM:00075630 01 31 ADDS R1, #1
ROM:00075632 75 5C LDRB R5, [R6,R1]
ROM:00075634 69 2D CMP R5, #0x69 ; 'i'
ROM:00075636 E5 D1 BNE loc_75604
ROM:00075638 01 31 ADDS R1, #1
ROM:0007563A 75 5C LDRB R5, [R6,R1]
ROM:0007563C 3E 2D CMP R5, #0x3E ; '>'
ROM:0007563E E1 D1 BNE loc_75604
ROM:00075640 53 7A LDRB R3, [R2,#9]
ROM:00075642 7F 20 MOVS R0, #0x7F ; ''
ROM:00075644 03 40 ANDS R3, R0
ROM:00075646 53 72 STRB R3, [R2,#9]
ROM:00075648 E0 E7 B loc_7560C
ROM:0007564A ; ---------------------------------------------------------------------------
ROM:0007564A
ROM:0007564A loc_7564A ; CODE XREF: sub_755F0+E_j
ROM:0007564A 53 7A LDRB R3, [R2,#9]
ROM:0007564C
ROM:0007564C loc_7564C ; DATA XREF: ROM:loc_75268_r
ROM:0007564C 80 20 MOVS R0, #0x80 ; 'Ç'
ROM:0007564E 03 40 ANDS R3, R0
ROM:00075650 80 2B CMP R3, #0x80 ; 'Ç'
ROM:00075652 02 D1 BNE loc_7565A
ROM:00075654 20 2D CMP R5, #0x20 ; ' '
ROM:00075656 00 D9 BLS loc_7565A
ROM:00075658 DF 35 ADDS R5, #0xDF ; '¯'
ROM:0007565A
ROM:0007565A loc_7565A ; CODE XREF: sub_755F0+A_j
ROM:0007565A ; sub_755F0+62_j ...
ROM:0007565A 48 1C ADDS R0, R1, #1
ROM:0007565C 00 06 LSLS R0, R0, #0x18
ROM:0007565E 00 0E LSRS R0, R0, #0x18
ROM:00075660 70 47 BX LR
ROM:00075660 ; End of function sub_755F0
Inibe tags ou habilita itálico na rotina "centraliza" (agora aproveita a rotina anterior, para não repetir código):
ROM:00075670 sub_75670 ; CODE XREF: sub_E38C:loc_E3A0_p
ROM:00075670 20 B5 PUSH {R5,LR}
ROM:00075672 35 1C ADDS R5, R6, #0
ROM:00075674 3E 1C ADDS R6, R7, #0
ROM:00075676 FF F7 BB FF BL sub_755F0
ROM:0007567A 2E 1C ADDS R6, R5, #0
ROM:0007567C 20 BC POP {R5}
ROM:0007567E 08 BC POP {R3}
ROM:00075680 18 47 BX R3
ROM:00075680 ; End of function sub_75670
Desliga itálico antes de cada quadro:
ROM:00075686 sub_75686 ; CODE XREF: sub_E64C+98_p
ROM:00075686 05 4A LDR R2, =unk_7A380
ROM:00075688 53 7A LDRB R3, [R2,#9]
ROM:0007568A 7F 24 MOVS R4, #0x7F ; ''
ROM:0007568C 23 40 ANDS R3, R4
ROM:0007568E 53 72 STRB R3, [R2,#9]
ROM:00075690 00 24 MOVS R4, #0
ROM:00075692 01 30 ADDS R0, #1
ROM:00075694 70 47 BX LR
ROM:00075694 ; End of function sub_75686
Palavra com endereço inicial da tabela de opções de legenda:
ROM:0007569C 80 A3 07 00 off_7569C DCD unk_7A380 ; DATA XREF: sub_755F0_r
ROM:0007569C ; sub_75686_r
ROM:000756A0 00 DCB 0
Agora os pontos modificados para chamar as rotinas (BLs):
Desliga o itálico no começo de cada quadro:
ROM:0000E6E2 05 98 LDR R0, [SP,#0x38+var_24]
ROM:0000E6E4 66 F0 CF FF BL sub_75686
ROM:0000E6E8 00 04 LSLS R0, R0, #0x10
Inibe tags ou habilita itálico na rotina principal:
ROM:0000E6F0 21 1C ADDS R1, R4, #0
ROM:0000E6F2 75 5C LDRB R5, [R6,R1]
ROM:0000E6F4 66 F0 7C FF BL sub_755F0
ROM:0000E6F8 04 1C ADDS R4, R0, #0
ROM:0000E6FA C0 46 NOP
Inibe tags ou habilita itálico na rotina "centraliza":
ROM:0000E3A0 67 F0 66 F9 BL sub_75670
ROM:0000E3A4 04 1C ADDS R4, R0, #0
ROM:0000E3A6 C0 46 NOP
-
Obrigado. Hoje a noite vou criar quatro fontes (acho que são mais do que suficientes) com o Photoshop, que acho deve ser o método mais fácil.
Fique tranquilo que vou compartir os créditos com você tanto nos posts de anuncio do novo firmware, como também dentro do próprio firmware e no arquivo readme.txt incluído com o firmware.
-
Rictad, tenho algumas (muitas) dúvidas... Agora eu entendi o processo, mas fiquei confuso com o fato do alinhamento e o itálico compartirem a mesma eeprom. Mudar uma opção no menu não vai afetar a outra? O fato do alinhamento não ser dinâmico, vai fazer com que a escolha do itálico também não seja dinâmico? Você explicou essa parte, mas não entendi como é que fica:
Mas lembre-se, o valor deve ser mesclado, utilizando a operação OR, com o valor da opção de alinhamento horizontal!. Isso quer dizer que você deve modificar, no 8032, o trecho que lê a opção de alinhamento horizontal para que também leia a opção de tags. Aí você faria um OR entre os 2 valores e enviaria o resultado como se fosse o valor de alinhamento. Porém, como eu ainda não tenho certeza se a posição de memória que usei no ARM realmente corresponde ao alinhamento horizontal, deixe essa parte do OR para depois de eu realizar mais alguns testes.
Você já viu como e que funciona o patch do carregamento de legendas com nome distinto?
(http://img53.imageshack.us/img53/8995/rutina.jpg)
O menu tem tres opções: 00, 01 e 02. O patch lé o endereço da eeprom, se o byte guardado for 00 carrega primeiro a original e depois todas legendas, se for 01 carrega todas as legendas, e se for 02 carrega somente as legendas originais (mesmo nome)...
-
Rictad, tenho algumas (muitas) dúvidas... Agora eu entendi o processo, mas fiquei confuso com o fato do alinhamento e o itálico compartirem a mesma eeprom. Mudar uma opção no menu não vai afetar a outra? O fato do alinhamento não ser dinâmico, vai fazer com que a escolha do itálico também não seja dinâmico?
Não é bem assim. Os endereços de EEPROM devem ser diferentes, senão uma opção irá realmente afetar a outra. Mas na hora que o endereço de EEPROM do alinhamento for carregado no 8032, você deve também carregar o endereço de EEPROM do itálico e fazer um OR entre os dois valores. O resultado do OR entre os dois valores (dos dois endereços de EEPROM) é que deve ser enviado ao ARM, no lugar de apenas o valor do alinhamento. Aí sim, no ARM, o endereço de memória, e não o de EEPROM, é compartilhado. O endereço no ARM que eu usei foi o unk_7A380 + 9 (#7A389), que provavelmente é o endereço do alinhamento horizontal.
Sim, o fato do alinhamento não ser dinâmico vai fazer com que a opção de itálico também não seja dinâmica. Mas, de repente, a gente pode mudar isso também 8).
A rotina do itálico é do mesmo estilo dessa rotina dos nomes de arquivos de legenda. Verifica as opções e toma as decisões. Só é preciso filtrar antes as opções do alinhamento para sobrar só as opções de itálico, pois estão ambas em unk_7A380 + 9. Veja o trecho:
Inibe tags ou habilita itálico na rotina principal:
ROM:000755F0 sub_755F0 ; CODE XREF: sub_E64C+A8_p
ROM:000755F0 ; sub_75670+6_p
ROM:000755F0 2A 4A LDR R2, =unk_7A380
ROM:000755F2
ROM:000755F2 loc_755F2 ; CODE XREF: sub_755F0+20_j
ROM:000755F2 53 7A LDRB R3, [R2,#9] ; posição do alinhamento horizontal (unk_7A380 + 9)
ROM:000755F4 60 20 MOVS R0, #0x60 ; '`'
ROM:000755F6 03 40 ANDS R3, R0 ; filtra alinhamento
ROM:000755F8 40 2B CMP R3, #0x40 ; '@' ; verifica se opção itálico está desligada
ROM:000755FA 2E D0 BEQ loc_7565A ; se sim, vai embora
No firmware 1.4 que você me mandou, com as opções de alinhamento de volta ao menu, o itálico não está funcionando corretamente. Provavelmente é devido aos valores do alinhamento horizontal. Eu terei que mudar os valores das rotinas do itálico ou terei que mudar o endereço "emprestado" do alinhamento horizontal para o alinhamento vertical. Seja como for, eu preciso ver a sua estrutura de menus, com os valores das opções e os endereços EERPOM, dos dois alinhamentos. Eu tentei localizar o seu menu no MTKRemaker, mas ele não aparece (não sei porque). Como você faz para visualizar as opções, strings e ícones do menu? ;D
O menu do alinhamento vertical você já me passou. Ele continua o mesmo?
5. No Pic. | Vertical alignment | Set the vertical alignment
0008 FFFF 056C 058E 0063 0000 0001 0001 FFF989 0000 - ROM:F920
1. Top | Top | [00]
0590 0590 0561 00 - ROM:F974
=> 2. Bottom | Bottom | [00]
058F 058F 0561 01 - ROM:F97B
Se continua o mesmo, basta mostrar agora como é o menu do alinhamento horizontal que eu vou verificar a rotina do itálico de novo. :)
-
Jmaraujo,
Consegui fazer o itálico funcionar junto com as opções de alinhamento e consegui fazer com que as opções se tornem dinâmicas! :yahoo!:
Vamos às modificações:
Em primeiro lugar, as opções de alinhamento vertical e horizontal no firmware 1.4 estão trocadas (verifica isso lá) e bugando a legenda. Troquei os endereços no menu e tudo ficou certo.
Em segundo lugar, não sei o porquê, os valores para o alinhamento vertical, 00 e 01, não deixavam o itálico funcionar, mesmo que eu usasse o endereços do alinhamento horizontal emprestado para o itálico (não o vertical :-[). Tive que alterar para os padrões dos firmwares mediatek, que são 08 e 09. Veja como ficou os menus dos alinhamentos. Tudo que está em vermelho foi alterado:
4. No Pic. | Horizontal alignment | Set the horizontal alignment
0008 FFFF 056D 058D 0063 0000 0002 0001 FFF9A7 0000 - ROM:F935
1. Left | Left | [00]
0578 0578 0561 00 - ROM:F992
=> 2. Center | Center | [00]
0579 0579 0561 01 - ROM:F999
3. Right | Right | [00]
057A 057A 0561 02 - ROM:F9A0
5. No Pic. | Vertical alignment | Set the vertical alignment
0008 FFFF 056C 058E 0062 0000 0009 0001 FFF989 0000 - ROM:F920
1. Top | Top | [00]
0590 0590 0561 08 - ROM:F974
=> 2. Bottom | Bottom | [00]
058F 058F 0561 09 - ROM:F97B
Aí o itálico passou a funcionar.
Agora, vamos ao alinhamento dinâmico. Eu vi que você usou a seguinte rotina para interceptar os valores do alinhamento:
B1:FF54 ; aplica alinhamentos legenda
B1:FF54
B1:FF54 B1_FF54: ; CODE XREF: B1_EE21+25_p
B1:FF54 7F 57 mov R7, #0x57 ; 'W'
B1:FF56 7E 00 mov R6, #0
B1:FF58 12 05 D7 lcall B1_BS_125_B4_E0AE
B1:FF5B 74 28 mov A, #0x28 ; '('
B1:FF5D C3 clr C
B1:FF5E 9F subb A, R7
B1:FF5F 90 FB F0 mov DPTR, #XRAM_FBF0
B1:FF62 F0 movx @DPTR, A
B1:FF63 C3 clr C
B1:FF64 24 82 add A, #0x82 ; 'é'
B1:FF66 90 FB F8 mov DPTR, #XRAM_FBF8
B1:FF69 F0 movx @DPTR, A
B1:FF6A 7F 62 mov R7, #0x62 ; 'b'
B1:FF6C 7E 00 mov R6, #0
B1:FF6E 12 05 D7 lcall B1_BS_125_B4_E0AE
B1:FF71 EF mov A, R7
B1:FF72 FB mov R3, A
B1:FF73 7F 63 mov R7, #0x63 ; 'c'
B1:FF75 7E 00 mov R6, #0
B1:FF77 12 05 D7 lcall B1_BS_125_B4_E0AE
B1:FF7A EF mov A, R7
B1:FF7B 22 ret
Pelo visto, essa rotina só é chamada 1 vez, ao iniciar um CD.
Mas a rotina que você criou para tratar as opções de cor da legenda é chamada várias vezes (possivelmente por todas as Sub_Style, secundárias e primária). Daí, foi só fazer como eu fiz no meu firmware: um salto (com bank switch) da rotina que aplica as cores para a rotina que aplica os alinhamentos. Ela era assim:
B3:FAC2 ; aplica cores legenda
B3:FAC2
B3:FAC2 B3_FAC2: ; CODE XREF: BankSw_223_B3_519C+2CE_p
B3:FAC2 7F 4E mov R7, #0x4E ; 'N'
B3:FAC4 7E 00 mov R6, #0
B3:FAC6 12 05 D7 lcall B3_BS_125_B4_E0AE
B3:FAC9 EF mov A, R7
B3:FACA FB mov R3, A
B3:FACB 7F 7B mov R7, #0x7B ; '{'
B3:FACD 7E 00 mov R6, #0
B3:FACF 12 05 D7 lcall B3_BS_125_B4_E0AE
B3:FAD2 EF mov A, R7
B3:FAD3 FA mov R2, A
B3:FAD4 7F 2E mov R7, #0x2E ; '.'
B3:FAD6 7E 00 mov R6, #0
B3:FAD8 12 05 D7 lcall B3_BS_125_B4_E0AE
B3:FADB EF mov A, R7
B3:FADC F9 mov R1, A
B3:FADD 7D 00 mov R5, #0
B3:FADF 7F 11 mov R7, #0x11
B3:FAE1 90 FB A4 mov DPTR, #XRAM_FBA4
B3:FAE4 EA mov A, R2
B3:FAE5 F0 movx @DPTR, A
B3:FAE6 A3 inc DPTR
B3:FAE7 E9 mov A, R1
B3:FAE8 F0 movx @DPTR, A
B3:FAE9 22 ret
Ficou assim:
B3:FAC2 ; aplica cores legenda
B3:FAC2
B3:FAC2 B3_FAC2: ; CODE XREF: BankSw_223_B3_519C+2CE_p
B3:FAC2 90 EE 21 mov DPTR, #0xEE21 ; primeiro, chama rotina que aplica alinhamento
B3:FAC5 12 02 40 lcall B3_Bank_1
B3:FAC8 7F 4E mov R7, #0x4E ; 'N'
B3:FACA 7E 00 mov R6, #0
B3:FACC 12 05 D7 lcall B3_BS_125_B4_E0AE
B3:FACF EF mov A, R7
B3:FAD0 FB mov R3, A
B3:FAD1 7F 7B mov R7, #0x7B ; '{'
B3:FAD3 7E 00 mov R6, #0
B3:FAD5 12 05 D7 lcall B3_BS_125_B4_E0AE
B3:FAD8 EF mov A, R7
B3:FAD9 FA mov R2, A
B3:FADA 7F 2E mov R7, #0x2E ; '.'
B3:FADC 7E 00 mov R6, #0
B3:FADE 12 05 D7 lcall B3_BS_125_B4_E0AE
B3:FAE1 EF mov A, R7
B3:FAE2 F9 mov R1, A
B3:FAE3 7D 00 mov R5, #0
B3:FAE5 7F 11 mov R7, #0x11
B3:FAE7 90 FB A4 mov DPTR, #XRAM_FBA4
B3:FAEA EA mov A, R2
B3:FAEB F0 movx @DPTR, A
B3:FAEC A3 inc DPTR
B3:FAED E9 mov A, R1
B3:FAEE F0 movx @DPTR, A
B3:FAEF 22 ret
Pronto, alinhamentos dinâmicos! 8).
Agora, vou explicar como você deverá fazer com as opções de itálico, já que tenho os pontos de alteração do seu firmware:
Como dito antes, você deve criar um menu com as seguintes opções (só podem ser esses valores, pois são os esperados na rotina do itálico no ARM):
"mostrar todas as tags" --> valor #40
"esconder todas as tags" --> valor #20
"habilitar o itálico" --> valor #00
Você pode usar o endeço de EEPROM que quiser (que estiver disponível). Vamos considerar que você use o endereço XX. Após criar o menu, você deverá fazer a seguinte modificação na rotina que aplica o alinhamento:
B1:FF54 ; aplica alinhamentos legenda
B1:FF54
B1:FF54 B1_FF54: ; CODE XREF: B1_EE21+25_p
B1:FF54 7F 57 mov R7, #0x57 ; 'W'
B1:FF56 7E 00 mov R6, #0
B1:FF58 12 05 D7 lcall B1_BS_125_B4_E0AE
B1:FF5B 74 28 mov A, #0x28 ; '('
B1:FF5D C3 clr C
B1:FF5E 9F subb A, R7
B1:FF5F 90 FB F0 mov DPTR, #XRAM_FBF0
B1:FF62 F0 movx @DPTR, A
B1:FF63 C3 clr C
B1:FF64 24 82 add A, #0x82 ; 'é'
B1:FF66 90 FB F8 mov DPTR, #XRAM_FBF8
B1:FF69 F0 movx @DPTR, A
B1:FF6A 7F 62 mov R7, #0x62 ; 'b'
B1:FF6C 7E 00 mov R6, #0
B1:FF6E 12 05 D7 lcall B1_BS_125_B4_E0AE
B1:FF71 EF mov A, R7
B1:FF72 FB mov R3, A
B1:FF73 7F 63 mov R7, #0x63 ; 'c' ; alinhamento horizontal agora é em 63!
B1:FF75 7E 00 mov R6, #0
B1:FF77 12 05 D7 lcall B1_BS_125_B4_E0AE
B1:FF7A EF mov A, R7
B1:FF7B FA mov R2, A ; alinhamento horizontal guardado temporariamente em R2
B1:FF7C 7F XX mov R7, #0xXX ; 'c' ; valor da nova opção de itálico, endereço XX da eeprom
B1:FF7E 7E 00 mov R6, #0
B1:FF80 12 05 D7 lcall B1_BS_125_B4_E0AE
B1:FF83 EF mov A, R7
B1:FF85 4A orl A, R2 ; OR entre opção de itálico e alinhamento horizontal
B1:FF7B 22 ret
Assim, as duas opções serão mescladas e chegarão no mesmo byte ao endereço #7A380 + 9 da RAM para o ARM. Como as rotinas que processam o alinhamento horizontal apenas consideram os bits finais, não fará diferença no alinhamento. Já as rotinas do itálico vão filtrar apenas os bits 6 e 5 para processarem a opção.
Vou enviar um email para você com o firmware 1.4 modificado e com 1 fonte com itálicos. Você precisará fazer a nova opção de menu, com os valores que falei, e a modificação acima (senão o itálico sempre ficará habilitado e as demais tags serão filtradas), além de mais algumas fontes com itálicos para ficar tudo em 100%.
-
Obrigadão mesmo, Rictad! ;D Vou fazer os testes agora mesmo. ;)
-
Fiz um video pra mostrar o funcionamento do firmware v1.5. ;D
Subtítulos en firmware jmaraujo 1.5 (http://www.youtube.com/watch?v=xTMK3aCEkfo#normal)
Somente notei um probleminha bem menor por culpa da quebra de linhas. Quando a quebra de linhas é feita perde-se o itálico da última linha. Por exemplo se o texto for:
<i>Exemplo de uma legenda comprida com
quebra de linha automática.</i>
Em vez de aparecer assim:
Exemplo de uma legenda comprida
com quebra de linha automática.
Fica assim:
Exemplo de uma legenda comprida
com quebra de linha automática.
Mas, como eu disse, é um probleminha bem menor e sem importância...
-
É, possivelmente ocorre quando a linha é dividida pelo patch que corrige a quebra de linhas. Vou dar uma olhada nisso.
E no teste rápido que fiz, o alinhamento horizontal parece não estar 100% (parece que às vezes muda com o itálico). Vou verificar isso também. Deve ser fácil de corrigir. EDIT: Acabei de verificar de novo e o alinhamento horizontal está certo. :) Agora falta dar uma olhada na quebra de linhas para ver como funciona e tentar manter o itálico após a quebra.
-
Pronto! O problema era o mesmo que acontecia no LG DV39H. A rotina que calcula a largura da linha (SUB_CalcTextLineWidth), que faz parte da rotina responsável pelo alinhamento horizontal (centraliza), também faz uma varredura pelos caracteres do quadro de legenda (pois precisa calcular a largura da linha levando em consideração a largura dos caracteres em itálico, senão o alinhamento fica deslocado). Quando isso é feito, o itálico é acionado ou desativado conforme as tags são encontradas. Se uma tag </i> era encontrada ao final de uma linha quebrada, a rotina deixava o itálico desativado. Quando a rotina que exibe a legenda (Display_subtitle) fosse exibir a linha, exibia sem itálico, pois a tag <i> fica na linha anterior (antes da quebra), que já foi processada. Assim, foi só incluir uma rotina para fazer uma cópia do estado do itálico, que deve ser chamada no início da SUB_CalcTextLineWidth, e uma outra para restaurar o estado ao sair da SUB_CalcTextLineWidth. Dessa forma, o estado do itálico deixou de ser alterado quando se calcula a largura da linha.
Novas rotinas:
ROM:00075662 Copia estado do itálico de 7A380 + 9 para 7A380 + #F
ROM:00075662 10 4B LDR R3, =unk_7A380
ROM:00075664 5A 7A LDRB R2, [R3,#9]
ROM:00075666 DA 73 STRB R2, [R3,#0xF]
ROM:00075668 07 1C ADDS R7, R0, #0 ; esse trecho restante é o que estava na
ROM:0007566A 00 25 MOVS R5, #0 ; rotina SUB_CalcTextLineWidth e foi substituído pelo BL
ROM:0007566C 70 47 BX LR
ROM:00075696 Restaura estado do itálico de 7A380 + #F para 7A380 + 9
ROM:00075696 03 4B LDR R3, =unk_7A380
ROM:00075698 DA 7B LDRB R2, [R3,#0xF]
ROM:0007569A 5A 72 STRB R2, [R3,#9]
ROM:0007569C 28 1C ADDS R0, R5, #0 ; esse trecho restante é o que estava na
ROM:0007569E FC BC POP {R2-R7} ; rotina SUB_CalcTextLineWidth e foi substituído pelo BL
ROM:000756A0 70 47 BX LR
Nova posição da palavra que define o endereço das opções da legenda (as novas rotinas precisaram de espaço):
ROM:000756A4 80 A3 07 00 off_756A4 DCD unk_7A380
Como a posição da palavra mudou, as instruções que dependem de sua posição tiveram que ser corrigidas:
ROM:000755F0 2C 4A LDR R2, =unk_7A380
................
................
ROM:00075686 07 4A LDR R2, =unk_7A380
Pontos alterados na SUB_CalcTextLineWidth para chamar as novas rotinas:
ROM:0000E38C FC B5 PUSH {R2-R7,LR}
ROM:0000E38E 67 F0 68 F9 BL sub_75662
ROM:0000E392 3C 48 LDR R0, =unk_7A00C
...........................
...........................
...........................
ROM:0000E434 B2 D3 BCC loc_E39C
ROM:0000E436
ROM:0000E436 loc_E436 ; CODE XREF: sub_E38C+1E_j
ROM:0000E436 ; sub_E38C+32_j
ROM:0000E436 67 F0 2E F9 BL sub_75696
ROM:0000E43A 08 BC POP {R3}
Eu fiz a cópia do estado do itálico no endereço 7A380 + #F do mesmo modo que no LG DV397H. Na rotina SUB_ClearMpeg4SubtitleParams vemos que os endereços de 7A38C a 7A38F são zerados:
ROM:0000E328 sub_E328 ; CODE XREF: sub_9992+1A_p
ROM:0000E328 5C 48 LDR R0, =unk_7A380
ROM:0000E32A FF 21 MOVS R1, #0xFF
ROM:0000E32C 01 72 STRB R1, [R0,#8]
ROM:0000E32E 00 22 MOVS R2, #0
ROM:0000E330 C2 60 STR R2, [R0,#0xC]
ROM:0000E332 02 80 STRH R2, [R0]
Em #E32E, R2 é zerado e todo seu conteúdo, ou seja, a palavra 00 00 00 00, é colocado a partir de 7A380 + #C (STR guarda a palavra e STRB guarda somente 1 byte). E na rotina SUB_FillMpeg4SubtitleParamsRecord vemos que esses endereços não são utilizados.
ROM:0000E350 sub_E350 ; CODE XREF: sub_AA2A+47_p
ROM:0000E350 02 78 LDRB R2, [R0]
ROM:0000E352 52 49 LDR R1, =unk_7A380
ROM:0000E354 0A 72 STRB R2, [R1,#8]
ROM:0000E356 83 78 LDRB R3, [R0,#2]
ROM:0000E358 42 78 LDRB R2, [R0,#1]
ROM:0000E35A 1B 02 LSLS R3, R3, #8
ROM:0000E35C 1A 43 ORRS R2, R3
ROM:0000E35E 0A 80 STRH R2, [R1]
ROM:0000E360 03 79 LDRB R3, [R0,#4]
ROM:0000E362 C2 78 LDRB R2, [R0,#3]
ROM:0000E364 1B 02 LSLS R3, R3, #8
ROM:0000E366 1A 43 ORRS R2, R3
ROM:0000E368 4A 80 STRH R2, [R1,#2]
ROM:0000E36A 83 79 LDRB R3, [R0,#6]
ROM:0000E36C 42 79 LDRB R2, [R0,#5]
ROM:0000E36E 1B 02 LSLS R3, R3, #8
ROM:0000E370 1A 43 ORRS R2, R3
ROM:0000E372 8A 80 STRH R2, [R1,#4]
ROM:0000E374 03 7A LDRB R3, [R0,#8]
ROM:0000E376 C2 79 LDRB R2, [R0,#7]
ROM:0000E378 1B 02 LSLS R3, R3, #8
ROM:0000E37A 1A 43 ORRS R2, R3
ROM:0000E37C CA 80 STRH R2, [R1,#6]
ROM:0000E37E 42 7A LDRB R2, [R0,#9]
ROM:0000E380 4A 72 STRB R2, [R1,#9]
ROM:0000E382 82 7A LDRB R2, [R0,#0xA]
ROM:0000E384 8A 72 STRB R2, [R1,#0xA]
ROM:0000E386 C0 7A LDRB R0, [R0,#0xB]
ROM:0000E388 C8 72 STRB R0, [R1,#0xB]
ROM:0000E38A 70 47 BX LR
Assim, achei seguro usar 7A380 + #F.
Jmaraujo, vou enviar essas modificações na versão 1.5beta2 para você testar. Acho que agora sim, é só fazer as fontes. :)
-
Obrigado, rictad. ;D Já
fiz as mudanças recebi o email é vou testar o firmware esta noite. ;)
Um abraço.
Juan M.
-
Ate agora está perfeito, Rictad. ;) Não achei nenhum bug ou comportamento extranho. ;D
-
;D Legal!
Na verdade, todo o trabalho inicial de ler a EEPROM, mesclar com valor do alinhamento e repassar ao ARM poderia ser evitado se eu soubesse exatamente como ler um endereço de EEPROM diretamente no ARM. Já li alguns documentos do mtk Group mas ainda não entendi. Para ler a memória, por exemplo, tem um offset, que pode ser #CC00 ou #C400 (ou outro, no caso dos players mais recentes). Mas para ler a EEPROM ainda não achei.. Na rotina dos nomes das legendas, que você passou acima, está escrito bem no começo:
LDR R3, =EEPROM_LOAD_SUBS
Olhando no código, temos:
ROM:000752CA 0F 4B LDR R3, =unk_376E636
Você sabe como calcular esse endereço? Não precisamos mudar isso agora, pois não trará diferenças para o usuário, mas seria interessante descobrir para outras mudanças futuras.
-
Na verdade, todo o trabalho inicial de ler a EEPROM, mesclar com valor do alinhamento e repassar ao ARM poderia ser evitado se eu soubesse exatamente como ler um endereço de EEPROM diretamente no ARM.
Claro, era a parte que achei mais complicada. Por isso tinha sugerido escrever direto na eeprom.
Você sabe como calcular esse endereço? Não precisamos mudar isso agora, pois não trará diferenças para o usuário, mas seria interessante descobrir para outras mudanças futuras.
Sei sim; foi um método que descobri por acaso, he-he! ;D
Aquela parte no começo do patch das legendas fui eu que mudei; se olhar o documento do patch do "Load org. then all" do Hej456 (ou mesmo o da sincronia do audio) você vai ver que ele usa endereços da Shared Memory. Mas eu estava tendo problemas para achar endereços de shared memory livres. Cada vez que eu tentava fazer um memory dump com o meu cabo USB o meu computador travava e eu tinha que fazer um reset. Ficava impossível.
Daí peguei a ideia de um post do grupo MT13x9 do Y! e sem muitas esperanças tentei escrever direto na EEPROM, e para a minha surpresa... deu certo!
Você tem de calcular deste jeito:
Shared Memory + Offset + Endereço EEPROM a usar
No meu player fica assim:
0376CC00 + 19E3 + EEPROM
No caso do carregamento das legendas, a EEPROM usada é a 53:
0376CC00 + 19E3 + 53 = 0376E636, daí que usei R3, =unk_376E636
O offset é achado na rotina PREF_GetChar (bEepromReadByte). No meu player o offset 0x19E3 esta ali:
ROM:E0AE ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
ROM:E0AE
ROM:E0AE ; PREF_GetChar
ROM:E0AE
ROM:E0AE bEepromReadByte:
ROM:E0AE CD xch A, R5 ; Read Shared memory
ROM:E0AF EF mov A, R7
ROM:E0B0 CD xch A, R5
ROM:E0B1 CC xch A, R4
ROM:E0B2 EE mov A, R6
ROM:E0B3 CC xch A, R4
ROM:E0B4 BC FF 06 cjne R4, #0xFF, ROM_E0BD
ROM:E0B4
ROM:E0B7 BD FF 03 cjne R5, #0xFF, ROM_E0BD
ROM:E0B7
ROM:E0BA 7F 00 mov R7, #0
ROM:E0BC 22 ret
ROM:E0BC
ROM:E0BD ; ---------------------------------------------------------------------------
ROM:E0BD
ROM:E0BD ROM_E0BD:
ROM:E0BD C3 clr C
ROM:E0BE ED mov A, R5
ROM:E0BF 94 CC subb A, #0xCC ; '¦'
ROM:E0C1 EC mov A, R4
ROM:E0C2 94 00 subb A, #0
ROM:E0C4 40 09 jc ROM_E0CF
ROM:E0C4
ROM:E0C6 90 FC 03 mov DPTR, #0xFC03
ROM:E0C9 74 24 mov A, #0x24 ; '$'
ROM:E0CB F0 movx @DPTR, A
ROM:E0CC 7F 00 mov R7, #0
ROM:E0CE 22 ret
ROM:E0CE
ROM:E0CF ; ---------------------------------------------------------------------------
ROM:E0CF
ROM:E0CF ROM_E0CF:
ROM:E0CF ED mov A, R5
ROM:E0D0 24 E3 add A, #0xE3 ; 'Ò'
ROM:E0D2 FF mov R7, A
ROM:E0D3 EC mov A, R4
ROM:E0D4 34 19 addc A, #0x19
ROM:E0D6 FE mov R6, A
ROM:E0D7 12 04 7B lcall bReadSInfo ; Arm_GetChar
ROM:E0D7
ROM:E0DA 22 ret
ROM:E0DA
ROM:E0DA ; End of function bEepromReadByte
Espero que sirva de ajuda. ;)
-
Espero que sirva de ajuda. ;)
Mas é claro!! Foi uma ajuda e tanto (uma descoberta). Obrigado!
O offset é achado na rotina PREF_GetChar (bEepromReadByte). No meu player o offset 0x19E3 esta ali:
Bem observado. Já tinha notado que a rotina PREF_GetChar chama a rotina Arm_GetChar (assim como a PREF_SetChar usa a Arm_PutChar). Mas nunca tinha pensado sobre a importância dessa relação. Parabéns!
Isso quer dizer que o hardware é desenhado para que a EEPROM funcione como uma página de endereços da RAM compartilhada. Com esse tipo de paginação, o código não faz distinção entre os dispositivos físicos reais de armazenamento. Para o programa, é como se tudo fosse a RAM.
-
Espero que sirva de ajuda. ;)
Mas é claro!! Foi uma ajuda e tanto (uma descoberta). Obrigado!
Concordo. Eu estava há muito tempo querendo saber como se chegava a esse offset da EEPROM na Shared Memory.