Moderadores: 51, guest2003, brasilma
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;
}
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.
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.
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]);
unsigned long long q = 0x1234567812345678;
printf("%016llx\n",q>>1);
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?
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;
}
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;
}
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.
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.
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>
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.
Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante