Karoshi MSX Community

Desarrollo MSX => Desarrollo (Español/Spanish) => Mensaje iniciado por: aorante en 16 de Abril de 2010, 07:28:33 am



Título: puntero en una función asm en SDCC
Publicado por: aorante en 16 de Abril de 2010, 07:28:33 am
Hola!
Help!!! ??? Estoy bloqueado intentando pasar a una función en assembler, la dirección de un puntero a un char donde tengo una cadena.
En el manual del SDCC no he encontrado nada.
¿se puede hacer?

Código:
char *cadena = "Hola Mundo";
Funcion(*cadena);

void Funcion(char *cadena)
{
__asm
  ld l,4(ix)
  ld h,5(ix)
__endasm;
}


Título: Re: puntero en una función asm en SDCC
Publicado por: aorante en 16 de Abril de 2010, 11:33:41 am
He visto que Konamiman, lo utiliza en su lib ASMLIB, pero no consigo descifrar su código ???

@Nerlaska, esta muy bien explicado el punto "assembler inline", de tu doc para hacer ROMs con SDCC. Si sabes como funciona el tema de los punteros podrías añadirlo y de paso actualizar los tags de _asm ya que al compilar sale un warning diciendo que esta "deprecado". Ahora es con doble subrayado "__asm" (que chorrada  ;) ).

Saludos!!!


Título: Re: puntero en una función asm en SDCC
Publicado por: OKI09 en 16 de Abril de 2010, 12:00:04 pm
No se si te entiendo bien, pero creo que lo que quieres es pasarle a un registro una direccion de memoria que apunte a una cadena. ???

Si es asi, yo lo haria poniendo esa direccion de memoria en una posicion en RAM y la leeria con el registro que quiero desde la rutina ASM.

No se si me explico. :D


Título: Re: puntero en una función asm en SDCC
Publicado por: aorante en 16 de Abril de 2010, 12:50:10 pm
Gracias Oki09!
Es la solución que justamente he utilizado y me funciona bien, pero quiero aprender a hacerlo con los punteros.


Título: Re: puntero en una función asm en SDCC
Publicado por: nerlaska en 19 de Abril de 2010, 04:45:40 am
A ver .. tu lo que quieres es acceder al puntero cadena, no?

Código:
char *cadena = "Hola Mundo";
Funcion(cadena); // Aqui solo deberias poner cadena, que es el valor de la dirección a "Hola Mundo" y no *cadena que seria 'H'

void Funcion(char *cadena)
{
__asm
  ld l,4(ix)
  ld h,5(ix)
__endasm;
}

Luego en función, en HL tendrias la dirección a "Hola Mundo" o sea ld a, (HL) te meteria en A el valor 'H'

Estas preguntando eso?


Título: Re: puntero en una función asm en SDCC
Publicado por: aorante en 19 de Abril de 2010, 10:55:56 am
Gracias, funciona!
pero no se por que motivo, necesita que le de al puntero una dirección:
Lo utilizo para una adaptación de una función de conversión de un número a ASCII, para luego mostrarlo en una screen 2.

La llamada a la función:
Código:
char *strBuff;                           
strBuff = 0xC400;
Num2Dec16(1000, strBuff);

La función:
Código:
/*
16-bit Integer to ASCII (decimal)
by baze
Input: HL = number to convert, DE = location of ASCII string
Output: ASCII string at (DE)
*/
void Num2Dec16(int aNumber, char *address)
{
  aNumber;
  address;
__asm
  ld l,4(ix)
  ld h,5(ix)
 
  ld e,6(ix)
  ld d,7(ix)
 
  ld bc,#-10000
call $Num1
ld bc,#-1000
call $Num1
ld bc,#-100
call $Num1
ld c,#-10
call $Num1
ld c,b
call $Num1
  jr  $Num3 
$Num1:
  ld a,#47  ;codigo ASCII de "0" -1
$Num2:
  inc a
add hl,bc
jr c,$Num2
sbc hl,bc
ld (de),a
inc de
ret
$Num3:
__endasm;
}


Título: Re: puntero en una función asm en SDCC
Publicado por: nerlaska en 20 de Abril de 2010, 07:20:09 am
Es lo que te decia .. lo que necesita que le pases a DE es una dirección donde guardar el ASCIIZ (string).
Tu pones 0xC400 que imagino será donde quieres almacenar el numero convertido a String, correcto?
si tuvieras...

char myNumber[10];

Num2Dec16 (145, myNumber);

Al salir de la función tendriás el numero convertido en la variable myNumber.


Título: Re: puntero en una función asm en SDCC
Publicado por: aorante en 21 de Abril de 2010, 08:08:23 pm
Solucionado!!!
Me funciona perfectamente.
Aunque utilizando el puntero, al compilar la salida me ocupa menos espacio, por lo que deduzco que debe de ser más optimo (no suelo mirar la salida en assembler por que no tengo nivel para entenderlo).
Me gusta más así por que no acabo de controlar la memoria y así le dejo la tarea al compilador. :P (cuando sea mayor ya haré más hard code ;) )

Gracias!

Antes:
Código:
void vPrintNumber(byte column, byte line, uint aNumber, byte aLength)
{
  uint tiladdre=0;
  char *strBuff;                           
  strBuff = 0xC400;

  Num2Dec16(aNumber, strBuff);
 
  // proporciona la direccion de la VRAM a partir de una posicion
  tiladdre = getAddress(column, line);
 
  //coloca el puntero en la posicion donde se ha de empezar a mostrar
  strBuff = strBuff + (5-aLength);
 
  // muestra el numero en la pantalla
  while (aLength-->0){ vpoke(tiladdre++,*(strBuff++));}
}

Ahora:
Código:
void vPrintNumber(byte column, byte line, uint aNumber, byte aLength)
{
  byte pos=5;
  uint tiladdre=0;
  char strBuff[5];   

  Num2Dec16(aNumber, strBuff);
 
  // proporciona la direccion de la VRAM a partir de una posicion
  tiladdre = getAddress(column, line);
 
  //posicion de inicio de la cadena
  pos= 5-aLength;
 
  // muestra el numero en la pantalla
  while (aLength-->0){ vpoke(tiladdre++,strBuff[pos++]);}
}