Divulgação Xmega

Software e Hardware para ATMEL

Moderadores: 51, guest2003, brasilma

Mensagempor msamsoniuk » 16 Nov 2009 20:00

a ausencia de rotate nao eh de hoje nao: a linguagem B de 69 nao tinha e a linguagem BCPL de 66 tambem nao. pode ser a forma que aprendemos logica de programacao, mas eu ao menos nao lembro na vida de ter precisado usar um rotate! e olha q eu programo em C desde 1993. vale lembrar que verilog usa as mesmas notacoes da linguagem C, de modo que nao existe uma notacao direta para rotate em verilog... e o ironico eh que a maioria dos processadores sao projetados em verilog e as pessoas sempre lembram de adicionar instrucoes rotate nos processadores, embora nao as use no dia a dia! hehehe
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Mensagempor vtrx » 16 Nov 2009 20:51

Eu uso a intrução rotate para receber dados seriais.
Na memoria de video da para gerar efeitos legais,tipo como os video games fazem.
Avatar do usuário
vtrx
Dword
 
Mensagens: 2239
Registrado em: 20 Abr 2008 21:01

Mensagempor Djalma Toledo Rodrigues » 16 Nov 2009 21:04

O MPLAB C18 tem :

RLCF
RRCF

RLNCF
RRNCF

Estas duas últimas Ñ Carry

Fonte: Livro Micro Controladores PIC18 / Linguagem C
Autor: Alberto N. Miyadaira
Editora: Érica

Abraço Marcelo

Bom ASM ops! Bom C
.
Avatar do usuário
Djalma Toledo Rodrigues
Dword
 
Mensagens: 2334
Registrado em: 03 Ago 2008 13:22

Mensagempor msamsoniuk » 17 Nov 2009 01:57

estranho... eu sempre usei shift logico para receber e enviar dados seriais e nunca precebi se teria uma vantagem usar rotate. por exemplo, para receber serialmente (lsb first):

rx_reg = (rx_reg << 1)|rx_line;

para transmitir serialmente (lsb first):

tx_line = tx_reg&1;
tx_reg = tx_reg >> 1;

e eh praticamente o mesmo codigo em verilog, quer dizer, se vc implementa um bom codigo em C, eh facil portar isso para hardware direto.

mesmo para video, nao consigo visualizar a vantagem de rotate, pq mesmo quando trabalhei com display monocromatico, o scroll lateral de imagens era feito com shift logico, por exemplo, scroll para a direta uma linha de video:

Código: Selecionar todos
last_pixel = 0;

for(i=0;i!=width;i++)
{
  pixel = buffer[i]&0x1;
  buffer[p]=(buffer[i]>>1)|(last_pixel);
  last_pixel = pixel?0x80:0;
}


poderia ter algum ganho com um shift para o carry, mas nao sei se eh muito critico e eu lembro que foram bem raros os casos de usar esse tipo de artificio... e como faz tempo q displays monocromaticos estao obsoletos, nao sei se alguem um dia vai precisar disso.

vtrx escreveu:Eu uso a intrução rotate para receber dados seriais.
Na memoria de video da para gerar efeitos legais,tipo como os video games fazem.
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Mensagempor vtrx » 17 Nov 2009 19:23

Se não me engano,um Shift lógico preenche as lacunas criadas com zero,o shift aritmético preenche as lacunas criadas com a cópia do bit de sinal.
No Rotate,desloca cada bit,nehum bit é perdido.
Agora sobre display monocromaticos não sei oque voce desloca,mas eu uso interface SVGA e desloco a memoria de video,qualquer coisa em mais ou menos 786.432 endereços de memoria sendo rotacionados por quadro.
Agora ja que me parece que voce me ironizou sobre ASM,voce poderia me mostrar uma rotina feita em C para ver se fica legal no meu Hardware de bancada.
É bem simples,preciso de uma rotina de delay Delay de 64µ e dentro deste 64µ testar um pino de uma porta,e caso o pino tenha nível Alto,a rotina deve ser interrompida,mas sem gastar interrupção para isto.Cristal de 4MHZ.
Avatar do usuário
vtrx
Dword
 
Mensagens: 2239
Registrado em: 20 Abr 2008 21:01

Mensagempor msamsoniuk » 17 Nov 2009 20:00

eu nao ironizei, mas jah que vc reclamou vou descer o verbo! hehehe :)

veja que nao tem logica vc pensar em shifts de bits se vc esta usando um display *colorido*, onde as operacoes sao pixel a pixel, nao bit a bit como em um display monocromatico. alem disso, q diferenca faz o shift perder os bits se vc nao esta mais usando eles no mesmo byte? alem de rotinas de criptografia, nao apenas nao vejo utilidade para rotate, como ele atrapalharia em varias situacoes (eu quero me livrar dos bits jah rotacionados, nao ter que tratar eles!).

sobre o temporizador para 64us, nao vejo pq vc acha dificil fazer em C, visto que eh possivel gerar delays controlados muito mais curtos que isso. na verdade o problema eh que tanto em C quanto em asm vc vai chamar sua rotina e ela vai rodar e depois vc tem que descontar o tempo em que ela rodou, do contrario vc vai ter o delay de 64us mais o tempo da rotina... se tivesse tempo livre eu fazia na boa.

vtrx escreveu:Se não me engano,um Shift lógico preenche as lacunas criadas com zero,o shift aritmético preenche as lacunas criadas com a cópia do bit de sinal.
No Rotate,desloca cada bit,nehum bit é perdido.
Agora sobre display monocromaticos não sei oque voce desloca,mas eu uso interface SVGA e desloco a memoria de video,qualquer coisa em mais ou menos 786.432 endereços de memoria sendo rotacionados por quadro.
Agora ja que me parece que voce me ironizou sobre ASM,voce poderia me mostrar uma rotina feita em C para ver se fica legal no meu Hardware de bancada.
É bem simples,preciso de uma rotina de delay Delay de 64µ e dentro deste 64µ testar um pino de uma porta,e caso o pino tenha nível Alto,a rotina deve ser interrompida,mas sem gastar interrupção para isto.Cristal de 4MHZ.
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Mensagempor Jozias del Rios » 17 Nov 2009 20:04

Oh yeah, lembrei.

Sem rotate, como vc dividiria por 2 rapidamente um número de 64bits em um uC de 8bits?
Os vencedores são aqueles que sabem o que fazer se perderem.
Os perdedores são aqueles que não sabem o que fazer se ganharem.
Avatar do usuário
Jozias del Rios
Byte
 
Mensagens: 279
Registrado em: 31 Out 2009 03:36
Localização: SJCampos-SP

Mensagempor Jozias del Rios » 17 Nov 2009 20:13

Oh yeah again...

como vc faria divisão num uC que não tem a instrução "div" e também sem rotate? (divisor variável!)

e conversão de base, para uma base arbitrária?

tudo bem, eu sei, são aplicações específicas.
Mas se houvesse rotate em C, elas serião escritas totalmente em C.
Os vencedores são aqueles que sabem o que fazer se perderem.
Os perdedores são aqueles que não sabem o que fazer se ganharem.
Avatar do usuário
Jozias del Rios
Byte
 
Mensagens: 279
Registrado em: 31 Out 2009 03:36
Localização: SJCampos-SP

Mensagempor vtrx » 17 Nov 2009 21:38

Marcelo,sem esticar a coversa,imagem Bit a Bit é apenas no modo monocromático de resolução de 1 Bit.
Podemos ter imagem monocromática de 1,2,3,4,5,6,7,8 ou mais Bits de resolução e um Pixel pode ter esses mesmos bits.
Veja,um pixel azul pode ser de resolução de 8 Bits,ou seja apenas um pixel aceso mas com 255 'tonalidades' deste mesmo azul.
Agora sobre a rotina,apenas em ASM voce pode calcular o tempo exato da chamda da rotina até o seu retorno.
Como voce foi 'gentil' na sua segunda resposta,não vou entrar e mais detalhes sobre oque voce comentou. :wink:
Avatar do usuário
vtrx
Dword
 
Mensagens: 2239
Registrado em: 20 Abr 2008 21:01

Mensagempor msamsoniuk » 18 Nov 2009 00:20

nao sei pq voces ficam perdendo tempo pensando sobre isso...se vc quer reinventar a roda, pode usar:

Código: Selecionar todos
  unsigned char p[8]={ 0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78 };

  p[7] = (p[7]>>1) | ((p[6]&1)?0x80:0);
  p[6] = (p[6]>>1) | ((p[5]&1)?0x80:0);
  p[5] = (p[5]>>1) | ((p[4]&1)?0x80:0);
  p[4] = (p[4]>>1) | ((p[3]&1)?0x80:0);
  p[3] = (p[3]>>1) | ((p[2]&1)?0x80:0);
  p[2] = (p[2]>>1) | ((p[1]&1)?0x80:0);
  p[1] = (p[1]>>1) | ((p[0]&1)?0x80:0);
  p[0] = (p[0]>>1);
  printf("%02x%02x%02x%02x%02x%02x%02x%02x\n",p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7]);



mas tem que entender que cabe ao compilador usar a implementacao nao portavel. nem todo processador, principalmente os processadores risc, possuem instrucoes multi-precisao de forma simples, o q nao quer dizer q nao se possa usar certos truques inteligentes. assim, seria muito mais facil usar um compilador *decente* e deixar isso a cargo do compilador:

Código: Selecionar todos
  unsigned long long q = 0x1234567812345678;

  printf("%016llx\n",q>>1);


dah o mesmo resultado que o codigo acima! e olha que nao rodei nenhum dos dois casos em um mcu de 64 bits! hehehe nao sei pq voces complicam tanto as coisas! :)

Jozias del Rios escreveu:Oh yeah, lembrei.

Sem rotate, como vc dividiria por 2 rapidamente um número de 64bits em um uC de 8bits?
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Mensagempor msamsoniuk » 18 Nov 2009 00:36

conversao de base arbitraria seria isso? tem uma divisao ali no meio... sera que dah pau?

Código: Selecionar todos
char *itostr(unsigned int i, char base)
{
  const char  *hex = "0123456789abcdef";
  static char tmp[sizeof(int)*8+1];
  char   j,k;

  tmp[j = sizeof(int)*8]=0;

  if(i)
  {
    for (k=0; i; i=i/base, k++)
      tmp[--j] = hex[i%base];
  }
  else
  {
    tmp[--j] = '0';
    k=1;
  }
  while(j&1)
  {
    tmp[--j] = '0';
  }

  return tmp + j;
}

int strtoi(char *p,char base)
{
  const char  *hex = "0123456789abcdef";
  int   i,j;
 
  for(i=0;*p;p++)
  {
    i=i*base;
    for(j=0;j!=base;j++)
      if(hex[j]==*p)
        i+=j;
  }   
  return i; 
}


eu uso o mesmo codigo no Z80, HC908, 68340, coldfire, 320LF2402 e nunca tive problemas... e tem uns caras que nem tem instrucao de divisao!

mas isso depende do compilador: eu tenho implementacao de divisao e multiplicacao para em C, que nao eh das mais eficientes, mas sempre quebra o galho:

Código: Selecionar todos
unsigned __mulsi3(unsigned a,unsigned b) {

   unsigned d,count;

   if(a<b) { d=a; a=b; b=d; }
   
   for(count=0,d=0;b;a=a<<1,b=b>>1,count++)
      if(b&1) d+=a;

   return d;
}

unsigned __divsi3(unsigned a,unsigned b) {

   unsigned c,d,s1,s2;

   if(!b) return 0;

   s1=b&0x80000000;
   s2=a&0x80000000;

   if(s1) b=-b;
   if(s2) a=-a;

   for(c=1,d=b;d<a;c=c<<1,d=d<<1,b=d);
   for(d=0;a&&c;c=c>>1,b=b>>1) if(b<=a)
      a-=b,d+=c;

   return (s1^s2)?-d:d;
}

unsigned __modsi3(unsigned a,unsigned b) {

   unsigned c,d,s1,s2;

   if(!b) return 0;

   s1=b&0x80000000;
   s2=a&0x80000000;

   if(s1) b=-b;
   if(s2) a=-a;

   for(c=1,d=b;d<a;c=c<<1,d=d<<1,b=d);
   for(d=0;a&&c;c=c>>1,b=b>>1)
      if(b<=a) a-=b,d+=c;

   return a;
}


acho que isso veio de uma implementacao para Z80, foi usado em um prototipo de processador risc de 16 bits de um colega e acabou quebrando um galho para um piripaque de gcc ae... e nao tem rotate, apenas shift... eu nao consigo ver onde rotate melhoraria algo! :P

Jozias del Rios escreveu:Oh yeah again...

como vc faria divisão num uC que não tem a instrução "div" e também sem rotate? (divisor variável!)

e conversão de base, para uma base arbitrária?

tudo bem, eu sei, são aplicações específicas.
Mas se houvesse rotate em C, elas serião escritas totalmente em C.
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Mensagempor msamsoniuk » 18 Nov 2009 01:06

eh que nao fica muito eficiente computacionalmente ter pixels de tamanhos quebrados... os melhores casos sao com 1, 8, 16 ou 32 bits por pixel. para 1 bit por pixel vc tem bastante necessidade de shift (mas nao consigo pensar em como usar rotate). para 8 ou 16 bits a necessidade eh apenas na hora de encodificar cores: encodificacao 332 para 8 bits ou 556 para 16 bits, requerem varios shifts, mas tambem nao consigo pensar em como usar rotate para isso.

sobre a rotina asm, note que a maioria dos compiladores produz o resultado em asm. entao se vc vai ter o trabalho de calcular o tempo de cada instrucao, daria na mesma fazer am asm ou C... mas ao inves de contar instrucoes vc poderia usar um timer ou ateh mesmo usar logica discreta, afinal software nunca substitui um bom hardware (veja o "exemplo" da microsoft).

vtrx escreveu:Marcelo,sem esticar a coversa,imagem Bit a Bit é apenas no modo monocromático de resolução de 1 Bit.
Podemos ter imagem monocromática de 1,2,3,4,5,6,7,8 ou mais Bits de resolução e um Pixel pode ter esses mesmos bits.
Veja,um pixel azul pode ser de resolução de 8 Bits,ou seja apenas um pixel aceso mas com 255 'tonalidades' deste mesmo azul.
Agora sobre a rotina,apenas em ASM voce pode calcular o tempo exato da chamda da rotina até o seu retorno.
Como voce foi 'gentil' na sua segunda resposta,não vou entrar e mais detalhes sobre oque voce comentou. :wink:
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Mensagempor Jozias del Rios » 18 Nov 2009 04:09

É, eu não conhecia essas implementações. São bem legais! Vivendo, conhecendo e aprendendo! Obrigado Samsoniuk.

Então minha conclusão sobre "rotate" é que eles realmente são opcionais, embora se há implementado no processador, eu não gostaria de trabalhar numa linguagem que me ajude a subir de nivel mas ao mesmo tempo me limite no domínio mais baixo. Ainda fico mais bravo ainda com o fato de não poder usar os flags diretamente a partir dos resultados das contas.... sei que isso não seria portável, mas... vontade é vontade, gosto é gosto hehehe

PS: Sobre o Flexis, me interessei bastante. Falei com o Denis@Informat e pedi amostras/cotações dos modelos mais baratos. Vc tambem tem interesse em algum? veja MCF51JM32VLD (LQFP-44) (esse que provavelmente será trazido). Se vc tambem quiser unidades, acho que pode baratear.

Abraços
Os vencedores são aqueles que sabem o que fazer se perderem.
Os perdedores são aqueles que não sabem o que fazer se ganharem.
Avatar do usuário
Jozias del Rios
Byte
 
Mensagens: 279
Registrado em: 31 Out 2009 03:36
Localização: SJCampos-SP

Mensagempor RobL » 18 Nov 2009 09:24

Veja um exemplo com ROR gerado pelo GCC AVR
Código: Selecionar todos
      for(int i = 128; i > 1; i -= i>>1)

 41a:   c9 01          movw   r24, r18

 41c:   95 95          asr   r25

 41e:   87 95          ror   r24

 420:   28 1b          sub   r18, r24

 422:   39 0b          sbc   r19, r25

 424:   22 30          cpi   r18, 0x02   ; 2

 426:   31 05          cpc   r19, r1

 428:   a4 f7          brge   .-24        ; 0x412 <__stack+0x113>

 42a:   81 e0          ldi   r24, 0x01   ; 1

 42c:   90 e0          ldi   r25, 0x00   ; 0

 42e:   ec cf          rjmp   .-40        ; 0x408 <__stack+0x109>



Veja neste for em C foi gerado um ROR logo na terceira linha.

Tenho outra rotina bin - bcd2 na qual há vários ROR (4 pelo menos) gerado pelo compilador.

O que te impede em C de verificar um Flag no registro de STATUS ?
Não há problema nenhum, pode testar os flags mesmo em C. Só que em C não haverá essa necessidade pois, quase sempre essa verificação será feita "automaticamente". Mas se sua rotina quiser testar todos os flags pode sim com simplicidade maior que em assembly.

Dizer que rotate é opcional é similar a dizer que subtração também seria pois podemos realizá-la por uma soma. Depende, há momentos em que rotate será mais eficiente e o compilador irá usá-lo, como na rotina acima.
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56

Mensagempor Djalma Toledo Rodrigues » 18 Nov 2009 10:09

RobL escreveu:Veja um exemplo com ROR gerado pelo GCC AVR
Mas se sua rotina quiser testar todos os flags pode sim com simplicidade maior que em assembly.

Dizer que rotate é opcional é similar a dizer que subtração também seria pois podemos realizá-la por uma soma. Depende, há momentos em que rotate será mais eficiente e o compilador irá usá-lo, como na rotina acima.

Simplicidade maior que em ASM, creio ser impossível.

C é tão bom mas, tão bom, que usa o Assembly . rs
.
Avatar do usuário
Djalma Toledo Rodrigues
Dword
 
Mensagens: 2334
Registrado em: 03 Ago 2008 13:22

AnteriorPróximo

Voltar para AVR

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

x