Postar resposta

Observação: Este post não será mostrado enquanto não for aprovado por um moderador.

Nome:
Email:
Assunto:
Ícone de mensagem:

Verificação:
Escreva as letras mostradas na imagem
Escutar as letras / Pedir uma nova imagem

Escreva as letras mostradas na imagem:
Escreva "convidado" (sem as aspas) na caixa ao lado (ou abaixo).:

atalhos: pressione alt+s para enviar ou alt+p para pré-visualizar


Resumo do Tópico

Enviado por: RodrigoFG
« Online: Outubro 21, 2009, 07:05:16 pm »

Que péssima notícia, estava ansioso e acompanhando o site toda semana. Espero que você consiga ressucitar o player.
Enviado por: zeurt
« Online: Outubro 05, 2009, 12:40:48 pm »

Que coisa mais chata, zeurt. :(
Você sabe se isso está relacionado com as alterações no buffer primário ou com a inclusão de mais fontes de 479 caracteres? Ou foi outra coisa?

Acho que deve ter sido outra coisa. A fonte não é, pois só usei uma fonte de 479 caracteres e não tinha dado problema antes.  Estou desconfiado da área de erros. Acho que tinha algo lá no meio que não podia ter alterado... Ou então foi alguma distração, etc. De qualquer modo, valeu pela força, rictad!
Enviado por: rictad
« Online: Outubro 04, 2009, 06:34:57 pm »

Que coisa mais chata, zeurt. :(
Você sabe se isso está relacionado com as alterações no buffer primário ou com a inclusão de mais fontes de 479 caracteres? Ou foi outra coisa?

(...) para tentar fazer uns malabarismos e recussitar o aparelho sem soldar o cabo ou o conector na porta serial (já que não tenho a menor condição de fazer isso).  :laugh:

Como? Sua FLASH é socketada?
Com ajuda de um conhecido que trabalhe com eletrônica, você consegue fazer o cabo. Ou mesmo sozinho, pois você tem condições de sobra para aprender.  ;)
Enviado por: zeurt
« Online: Outubro 04, 2009, 05:05:59 pm »

Sinto avisar que o projeto do itálico light está temporariamente suspenso.  :(
Isso porque eu "matei" o meu LG DV256K na última atualização que fiz. Não sei se cometi algum erro que afetou alguma área crítica do ARM, etc. O DVD player está "funcionalmente morto", ou seja, não reconhece mais nenhum disco, e assim não posso mais atualizá-lo por CD.
Inicia-se então mais uma saga de um ignorante em eletrônica, se enrolando com conversores RS-232/CMOS, conectores de 4 pinos, flat cables, etc., para tentar fazer uns malabarismos e recussitar o aparelho sem soldar o cabo ou o conector na porta serial (já que não tenho a menor condição de fazer isso).  :laugh:
Enviado por: rictad
« Online: Outubro 03, 2009, 05:13:33 am »

1- Não entendi como você fez o artifício contra a problema do limite de tamaho do buffer primário. Assim, acho que no meu esboço falta isso.

Pois é, temos que ver isso. Você fez aquele teste, mudando os 3 trechos para 9 e não aconteceu nada. Talvez 8 seja um valor "de segurança" e caiba mais alguma coisa. Se couber mais 3 caracteres não precisaremos do artifício. Imagine que o primeiro caractere da tag, que é "<", esteja na posição 8 (vamos considerá-la como última do buffer). Quando você buscar pelo próximo caractere da tag, que pode ser o "i" ou a barra, irá somar 1 ao contador e tentará ler algo na posição 9, que estará fora do buffer (e poderá ser qualquer caractere que estiver na memória naquela posição). Assim, a rotina, muito provavelmente, "perderá" essa tag, a qual somente terá o próximo caractere carregado na primeira posição do buffer após o novo preenchimento.

Mas, pelo teste, parece que o buffer tem ao menos 9 posições. Para o pior caso, que é quando a maior tag (tag </i>) estiver começando na posição 8 do buffer, teríamos que ter pelo menos mais 3 posições para garantir a leitura. 8+3 = 11 = #B. Teste com o valor #B naquelas 3 posições para ver se perdem-se caracteres da legenda (ou se são adicionados caracteres estranhos). Caso não aconteça nada, só para tirar uma dúvida sobre o tamanho do buffer, teste valores maiores, como #20 ou #40.

Caso dê problemas com #B, tente o valor #A. Depois de descobir o valor máximo do buffer, você poderá deixar que ele seja lido até o valor máximo - 3 (para garantir a tag </i>). Por exemplo, se for 9, o máximo até agora testado, então deixe aqueles valores somente até 6 (9-3).

Mas caso nada disso dê algum resultado prático, deixe em 8 mesmo. Se após o itálico ser implementado tivermos problemas com algumas tags não sendo reconhecidas, então o limitador do buffer estará em outro lugar. Depois descobriremos. :)
Enviado por: rictad
« Online: Outubro 02, 2009, 11:14:28 pm »

Acabei de descobrir que eu inventei o BLNE.  :dashhead1:

Não, ela realmente existe. Mas só no modo ARM, fui ver agora :(.
Enviado por: zeurt
« Online: Outubro 02, 2009, 11:01:52 pm »

Acabei de descobrir que eu inventei o BLNE.  :dashhead1:

Vou trocar por alguma das outras alternativas. Obrigado, rictad!  :)

P.S.: Vou ficar com essa alternativa. Ficou meio feio, mas pelo menos ocupa o mesmo número de bytes que a anterior (errada).

Código: [Selecionar]
0C 1C       FIM2            ADDS    R4, R1, #0
00 5D                       LDRB    R0, [R0,R4]
0D 28                       CMP     R0, #0xD
XX XX                       BNE     COMPLEMENTO
12 BC                       POP     {R1,R4}
70 47                       BX      LR       ; continua rotina anterior
00 5D       FIM1            LDRB    R0, [R0,R4] ; retorna sem mudar nada
0D 28                       CMP     R0, #0xD
XX XX                       BNE     COMPLEMENTO
12 BC                       POP     {R1,R4}
70 47                       BX      LR       ; continua rotina anterior
XX XX XX XX COMPLEMENTO     BL      loc_6DD58

Enviado por: rictad
« Online: Outubro 02, 2009, 10:53:34 pm »

Os PUSH/POP parecem certos. Você só precisa preservar R1 e R4 mesmo. R3 não precisa, pois na rotina de origem (como geralmente ocorre na maioria dessas rotinas) só é usado para retornos com BX. R0 será devolvido com o valor lido. E você retorna os valores a R1 e a R4 em ambos os possíveis fins da rotina.

Eu nem conhecia o BLNE. Já aprendi coisa nova!  ;D

Mas não daria para você deixar o BNE original no lugar do NOP na rotina de origem? Se você fizer isso economiza alguns bytes. Se bem que eu não sei qual o comportamento da flag Z depois de um BX, o que pode invalidar o BNE. Mas eu tenho uma "intuição" de que ela não é alterada. Outra saída, que pode ficar legal, é você fazer o salto em #6DD22 mesmo. Aí você carrega o código do caractere no próprio filtro e o devolve para a rotina principal em R0. Mas para isso precisará fazer uma tabela com a palavra F0 65 08 00 (para o endereço #865F0 ser lido) no final. Mas enfim, isso tudo que escrevi é só perfumaria. O seu código está excelente! E se não funcionar, é por algum detalhe ainda não reparado por nós.

E dá para ver como você se dedicou ao assunto. Já está sabendo praticamente tudo! :clapping:
Enviado por: zeurt
« Online: Outubro 02, 2009, 09:18:46 pm »

Descobri um problema, pois esqueçi que o salto BL ocupa 4 bytes. Então tive que fazer as seguintes mudanças na rotina que le o buffer primario e no fim da nova rotina que filtra as tags:

Rotina que le buffer primario (original):

Código: [Selecionar]
ROM:0006DD22 80 48                       LDR     R0, =unk_865F0
ROM:0006DD24 00 5D                       LDRB    R0, [R0,R4]     ; ESQUEÇI QUE O DESVIO QUE COLOCARIA AQUI OCUPA 4 BYTES
ROM:0006DD26 0D 28                       CMP     R0, #0xD        
ROM:0006DD28 16 D1                       BNE     loc_6DD58      

Ficaria Assim:

Código: [Selecionar]
ROM:0006DD22 80 48                       LDR     R0, =unk_865F0
ROM:0006DD24 XX XX XX XX                 BL      NOVA ROTINA    
ROM:0006DD26 XX XX                       NOP

Então, teria que mudar o FIM (1 e 2) da NOVA ROTINA:

Como eu tinha feito antes:

Código: [Selecionar]
0C 1C       FIM2            ADDS    R4, R1, #0
12 BC                       POP     {R1,R4}
XX XX XX XX                 BL      6DD26       ; continua rotina anterior
00 5D       FIM1            LDRB    R0, [R0,R4] ; retorna sem mudar nada
12 BC                       POP     {R1,R4}
XX XX XX XX                 BL      6DD26       ; continua rotina anterior

Como deve ser feito agora:

Código: [Selecionar]
0C 1C       FIM2            ADDS    R4, R1, #0
00 5D                       LDRB    R0, [R0,R4]
0D 28                       CMP     R0, #0xD
XX XX XX XX                 BLNE     loc_6DD58
12 BC                       POP     {R1,R4}
XX XX                       BX      LR       ; continua rotina anterior
00 5D       FIM1            LDRB    R0, [R0,R4] ; retorna sem mudar nada
0D 28                       CMP     R0, #0xD
XX XX XX XX                 BLNE     loc_6DD58
12 BC                       POP     {R1,R4}
XX XX                       BX      LR       ; continua rotina anterior

Obs: Mesmo assim, não sei se ainda tem algum erro (isso porque eu ainda me confundo com os PUSH/POP... preciso estudar mais  ;) ).
Enviado por: rictad
« Online: Outubro 02, 2009, 04:33:03 am »

Que legal! Olhando bem rapidamente, parece tudo certo. Gostei do jeito que você filtrou as tags. Legal que tenha achado o endereço do alinhamento horizontal. Acho que vai funcionar direitinho! Mas amanhã vou olhar com mais calma, qualquer coisa te aviso.

Com relação ao teste de salto na rotina do buffer primário para a área de erros, basta fazer o seguinte:

use um BL para área de erros;
na área de erros ponha apenas as 2 instruções que foram ocupadas pelos 4 bytes do BL seguidas do BX LR para retornar.

Se o player não travar quando exibir as legendas, o salto funcionou. Se travar ou exibir as legendas com erro, você vai ter que aumentar o ARM code 2. É simples, sei que você já viu: basta extrair apenas o ARM code 2 no MTKRemaker, adicionar alguns bytes (256 bytes dão e sobram) com um HEX editor e substituir no firmware com o MTKReplacer (o MTKRemaker costuma dar erro e não aceitar a substituição). Aí você abre novamente no MTKRemaker para corrigir o checksum e verificar se o firmware ainda aparece corretamente, com todos os trechos de antes.
Enviado por: zeurt
« Online: Outubro 02, 2009, 02:58:18 am »

Oi rictad,

Depois de estudar bastante as suas modificações já pude fazer um esboço do Itálico Light para o LG DV256K. Fiz apenas o básico: falta as partes que corrigem a centralização e que cancelam o itálico no início de cada quadro. Porém, ainda tenho dúvidas, como:
1- Não entendi como você fez o artifício contra a problema do limite de tamaho do buffer primário. Assim, acho que no meu esboço falta isso.
2- Ainda não sei se poderei usar as áreas de erro para colocar a nova rotina do buffer primário. Isso porque o buffer primário fica no ARM code 2, e as áreas de erro no ARM code 1. Farei um teste rápido (desvio do buffer primário para área de erro, para legendas ficarem só com "aaaaaaaaaaa..."  ;D ), porém hoje não estou em casa e não posso fazer ainda.

Aqui vão os esboços das modificações:

Rotina do Buffer Primário Original (com o possível ponto para o desvio para nova rotina que filtra as tags de itálico)

Código: [Selecionar]
ROM:0006DD10             ; =============== S U B R O U T I N E =======================================
ROM:0006DD10
ROM:0006DD10
ROM:0006DD10             sub_6DD10                               ; CODE XREF: sub_6DE6C+52p
ROM:0006DD10                                                     ; sub_6DE6C+62p
ROM:0006DD10 F8 B5                       PUSH    {R3-R7,LR}
ROM:0006DD12 00 26                       MOVS    R6, #0
ROM:0006DD14 00 25                       MOVS    R5, #0
ROM:0006DD16 00 20                       MOVS    R0, #0
ROM:0006DD18 F2 F7 56 F8                 BL      sub_5FDC8
ROM:0006DD1C 85 4F                       LDR     R7, =unk_85FF4
ROM:0006DD1E
ROM:0006DD1E             loc_6DD1E                               ; CODE XREF: sub_6DD10+7Ej
ROM:0006DD1E 00 24                       MOVS    R4, #0
ROM:0006DD20 23 E0                       B       loc_6DD6A
ROM:0006DD22             ; ---------------------------------------------------------------------------
ROM:0006DD22
ROM:0006DD22             loc_6DD22                               ; CODE XREF: sub_6DD10+5Cj
ROM:0006DD22 80 48                       LDR     R0, =unk_865F0
ROM:0006DD24 00 5D                       LDRB    R0, [R0,R4]     ; COLOCAR O DESVIO PARA FILTROS DE ITALICO AQUI
ROM:0006DD26 0D 28                       CMP     R0, #0xD
ROM:0006DD28 16 D1                       BNE     loc_6DD58
ROM:0006DD2A 00 22                       MOVS    R2, #0
ROM:0006DD2C 01 21                       MOVS    R1, #1
ROM:0006DD2E 20 1C                       ADDS    R0, R4, #0
ROM:0006DD30 F2 F7 20 F8                 BL      sub_5FD74
ROM:0006DD34 FF F7 5D FF                 BL      sub_6DBF2
ROM:0006DD38 00 28                       CMP     R0, #0
ROM:0006DD3A 13 D0                       BEQ     loc_6DD64
ROM:0006DD3C 01 36                       ADDS    R6, #1
ROM:0006DD3E 01 2E                       CMP     R6, #1
ROM:0006DD40 15 D1                       BNE     loc_6DD6E
ROM:0006DD42 B2 2D                       CMP     R5, #0xB2 ; '¦'
ROM:0006DD44 13 D2                       BCS     loc_6DD6E
ROM:0006DD46 EA 19                       ADDS    R2, R5, R7
ROM:0006DD48 0D 21                       MOVS    R1, #0xD
ROM:0006DD4A 91 70                       STRB    R1, [R2,#2]
ROM:0006DD4C 68 1C                       ADDS    R0, R5, #1
ROM:0006DD4E 45 1C                       ADDS    R5, R0, #1
ROM:0006DD50 0A 21                       MOVS    R1, #0xA
ROM:0006DD52 C0 19                       ADDS    R0, R0, R7
ROM:0006DD54 81 70                       STRB    R1, [R0,#2]
ROM:0006DD56 0A E0                       B       loc_6DD6E
ROM:0006DD58             ; ---------------------------------------------------------------------------
ROM:0006DD58
ROM:0006DD58             loc_6DD58                               ; CODE XREF: sub_6DD10+18j
ROM:0006DD58 01 1C                       ADDS    R1, R0, #0
ROM:0006DD5A 28 1C                       ADDS    R0, R5, #0
ROM:0006DD5C 01 35                       ADDS    R5, #1
ROM:0006DD5E C0 19                       ADDS    R0, R0, R7
ROM:0006DD60 81 70                       STRB    R1, [R0,#2]
ROM:0006DD62 00 26                       MOVS    R6, #0
ROM:0006DD64
ROM:0006DD64             loc_6DD64                               ; CODE XREF: sub_6DD10+2Aj
ROM:0006DD64 01 34                       ADDS    R4, #1
ROM:0006DD66 08 2C                       CMP     R4, #8
ROM:0006DD68 01 D2                       BCS     loc_6DD6E
ROM:0006DD6A
ROM:0006DD6A             loc_6DD6A                               ; CODE XREF: sub_6DD10+10j
ROM:0006DD6A B4 2D                       CMP     R5, #0xB4 ; '¦'
ROM:0006DD6C D9 D3                       BCC     loc_6DD22
ROM:0006DD6E
ROM:0006DD6E             loc_6DD6E                               ; CODE XREF: sub_6DD10+30j
ROM:0006DD6E                                                     ; sub_6DD10+34j ...
ROM:0006DD6E 08 2C                       CMP     R4, #8
ROM:0006DD70 04 D1                       BNE     loc_6DD7C
ROM:0006DD72 00 22                       MOVS    R2, #0
ROM:0006DD74 01 21                       MOVS    R1, #1
ROM:0006DD76 08 20                       MOVS    R0, #8
ROM:0006DD78 F1 F7 FC FF                 BL      sub_5FD74
ROM:0006DD7C
ROM:0006DD7C             loc_6DD7C                               ; CODE XREF: sub_6DD10+60j
ROM:0006DD7C 00 20                       MOVS    R0, #0
ROM:0006DD7E F2 F7 23 F8                 BL      sub_5FDC8
ROM:0006DD82 02 2E                       CMP     R6, #2
ROM:0006DD84 02 D1                       BNE     loc_6DD8C
ROM:0006DD86 28 1C                       ADDS    R0, R5, #0
ROM:0006DD88 FE 30                       ADDS    R0, #0xFE ; '¦'
ROM:0006DD8A 02 E0                       B       loc_6DD92
ROM:0006DD8C             ; ---------------------------------------------------------------------------
ROM:0006DD8C
ROM:0006DD8C             loc_6DD8C                               ; CODE XREF: sub_6DD10+74j
ROM:0006DD8C B4 2D                       CMP     R5, #0xB4 ; '¦'
ROM:0006DD8E C6 D3                       BCC     loc_6DD1E
ROM:0006DD90 B4 20                       MOVS    R0, #0xB4 ; '¦'
ROM:0006DD92
ROM:0006DD92             loc_6DD92                               ; CODE XREF: sub_6DD10+7Aj
ROM:0006DD92 78 70                       STRB    R0, [R7,#1]
ROM:0006DD94 61 49                       LDR     R1, =unk_86E2C
ROM:0006DD96 00 20                       MOVS    R0, #0
ROM:0006DD98 14 39                       SUBS    R1, #0x14
ROM:0006DD9A 08 60                       STR     R0, [R1]
ROM:0006DD9C F8 BC                       POP     {R3-R7}
ROM:0006DD9E 08 BC                       POP     {R3}
ROM:0006DDA0 18 47                       BX      R3
ROM:0006DDA0             ; End of function sub_6DD10

Nova Rotina, que filtra as tags de itálico:

Código: [Selecionar]
12 B4       INICIO          PUSH    {R1,R4}
 03 5D                       LDRB    R3, [R0,R4]
 3C 2B                       CMP     R3, #0x3C ; '<'
 XX D1                       BNE     FIM1
 61 1C                       ADDS    R1, R4, #1
 43 5C                       LDRB    R3, [R0,R1]
 69 2B                       CMP     R3, #0x69 ; 'i'
 XX D1                       BNE     VERIFBARRA
 01 31                       ADDS    R1, #1
 43 5C                       LDRB    R3, [R0,R1]
 3E 2B                       CMP     R3, #0x3E ; '>'
 XX D1                       BNE     FIM1
 03 20                       MOVS    R0, #3
 0A E0                       B       FIM2
 2F 2B       VERIFBARRA      CMP     R3, #0x2F ; '/'
 XX D1                       BNE     FIM1
 01 31                       ADDS    R1, #1
 43 5C                       LDRB    R3, [R0,R1]
 69 2B                       CMP     R3, #0x69 ; 'i'
 XX D1                       BNE     FIM1
 01 31                       ADDS    R1, #1
 43 5C                       LDRB    R3, [R0,R1]
 3E 2B                       CMP     R3, #0x3E ; '>'
 XX D1                       BNE     FIM1
 04 20                       MOVS    R0, #4
 0C 1C       FIM2            ADDS    R4, R1, #0
 22 BC                       POP     {R1,R4}
 XX XX XX XX                 BL      6DD26       ; continua rotina anterior
 00 5D       FIM1            LDRB    R0, [R0,R4] ; retorna sem mudar nada
 12 BC                       POP     {R1,R4}
 XX XX XX XX                 BL      6DD26       ; continua rotina anterior

Rotinas do buffer secundário, ocupando o mesmo espaço da rotina original, e depois as áreas de erro:

Código: [Selecionar]
            ; =============== S U B R O U T I N E =======================================

 XX XX                       LDR     R1, =unk_85FF4  ; end. inicial buffer secundario
 08 18                       ADDS    R0, R1, R0
 80 78                       LDRB    R0, [R0,#2]
 70 47                       BX      LR

No espaço que sobra logo a seguir da rotina acima:

             ; =============== S U B R O U T I N E =======================================

 XX XX                       LDR     R1, =unk_85FF4  
 08 18                       ADDS    R0, R1, R0
 XX XX                       LDR     R2, =unk_800C8  ; end. que guarda opcoes da legenda
 80 78                       LDRB    R0, [R0,#2]
 D1 79                       LDRB    R1, [R2,#7]     ; no DV256K o Alin. Horiz. fica em 800C8 + #7
 00 B5                       PUSH    {LR}
 XX XX XX XX                 BL      NOVA ROTINA
 08 BC                       POP     {R3}
 18 47                       BX      R3

Na área de erros:

             ; =============== S U B R O U T I N E =======================================

 03 28       NOVA ROTINA     CMP     R0, #3
 03 D1                       BNE     PARTE2
 80 23                       MOVS    R3, #0x80
 19 43                       ORRS    R1, R3          ; seta bit 7 do alin. horiz.
 D1 71                       STRB    R1, [R2,#7]
 70 47                       BX      LR
 04 28       PARTE2          CMP     R0, #4
 03 D1                       BNE     PARTE3
 7F 23                       MOVS    R3, #0x7F
 19 40                       ANDS    R1, R3          ; reseta bit 7 do alin. horiz.
 D1 71                       STRB    R1, [R2,#7]
 70 47                       BX      LR
 20 28       PARTE3          CMP     R0, #0x20
 09 D9                       BLS     FIM
 D1 79                       LDRB    R1, [R2,#7]
 70 22                       MOVS    R2, #0x70        ; retirar essas 4 linhas (checam se italico esta habilitado pelo menu)
 0A 40                       ANDS    R2, R1           ; (idem)
 50 2A                       CMP     R2, #0x50        ; (idem)
 04 D1                       BNE     FIM              ; (idem)
 80 22                       MOVS    R2, #0x80
 0A 40                       ANDS    R2, R1
 80 2A                       CMP     R2, #0x80        ; checa se bit 7 esta setado
 00 D1                       BNE     FIM
 DF 30                       ADDS    R0, #0xDF
 70 47       FIM             BX      LR

Rictad, se você detectar alguma coisa errada, avise.  :) Obrigado! Nesse fim-de-semana pretendo testar na prática...
Enviado por: zeurt
« Online: Setembro 30, 2009, 02:08:05 am »

Eu cheguei a pensar rapidamente sobre as outras tags (negrito,etc.), e acabei chegando a conclusão que eu as deixaria sem alterações (ou seja, seriam exibidas como já são atualmente) no Plano Itálico Light, já que essas outras tags são bem mais raras. Porém, se não for muito difícil, talvez seria legal filtrá-las e desprezá-las (ou seja, não exibí-las).
Enviado por: rictad
« Online: Setembro 30, 2009, 01:15:55 am »

Então vai ficar ainda mais fácil implementar o itálico light, pois não terá que se preocupar com outro valor para o alinhamento horizontal. E será bem simples adicionar no futuro ao menos uma opção de habilitar/desabilitar o itálico no menu, ou mesmo mais uma outra para eliminar/mostrar as tags. Você já pensou como vai fazer com as outras tags? Quando o itálico estiver habilitado, como vai fazer com as tags de negrito, por exemplo? Vai mostrá-las ou eliminá-las?
Enviado por: zeurt
« Online: Setembro 29, 2009, 10:35:42 pm »

Isso, o meu firmware não tem alinhamento a esquerda (e ele deve ser defeituoso mesmo).
Enviado por: rictad
« Online: Setembro 29, 2009, 10:28:06 pm »

Teste 1: As legendas ficaram apenas com a letra "a", como era esperado.
             Aproveitei para testar o alinhamento horizontal - #00: ficou alinhado a esquerda, porém de um jeito meio louco; a primeira linha ficava a esquerda corretamente, enquanto que a segunda linha às vezes estava correta (à esquerda) e às vezes estava posicionada nos mais variados locais: no meio da tela, mais à direita, etc.

O seu firmware tem opção de alinhamento à esquerda? Se não, talvez #00 (e possivelmente #80 e #C0) sejam alinhamentos à esquerda defeituosos. Eu pensei que você já usava o #80 para isso. Se não tem alinhamento à esquerda e #C0 também centralizar, já temos nossos 2 bits disponíveis (e provavelmente um terceiro, se #E0 e #E1 seguirem o padrão ;)).