Página 1 de 1

[Assembler] - Solicitud Función POKE

Publicado: 20 Oct 2015, 11:08
por Hark0
Buenas!

Aquí es cuando demuestro mi ignorancia máxima.

¿Alguien me pega aquí una función para Z88DK en ensamblador para hacer un triste "POKE"?

:oops:

Re: [Assembler] - Solicitud Función POKE

Publicado: 20 Oct 2015, 11:19
por Hark0
Bueno, de momento me he escrito esto y me vale....

Código: Seleccionar todo

void poke (void)
{
	#asm
	ld a,255
	ld (16384),a
	ret
	#endasm
}
:P

Re: [Assembler] - Solicitud Función POKE

Publicado: 21 Oct 2015, 09:18
por Radastan
Efectivamente, eso es, pero digo yo que querrás usar ese "poke" de forma genérica. Si sólo vas a escribir un valor lo suyo es emplear punteros

Código: Seleccionar todo

int *puntero

void main (void)
{
	puntero=16384;
	*puntero=256;
}
Usar ASM queda relegado a rutinas con iteraciones o críticas en velocidad, para un simple poke usa punteros. El compilador lo traduce a código ASM como el que has escrito.

Si lo que quieres es una función:

Código: Seleccionar todo

poke (int *puntero, unsigned char valor)
{
	*puntero=valor;
}

Re: [Assembler] - Solicitud Función POKE

Publicado: 21 Oct 2015, 11:21
por mcleod_ideafix
Radastan escribió:Efectivamente, eso es, pero digo yo que querrás usar ese "poke" de forma genérica. Si sólo vas a escribir un valor lo suyo es emplear punteros

Código: Seleccionar todo

int *puntero

void main (void)
{
	puntero=16384;
	*puntero=256;
}
Aquí has definido puntero como un puntero a entero (int), que son 16 bits. La instrucción *puntero=256 mete un valor de 16 bits, y habitualmente los POKEs se entienden que son de 8 bits. Por ejemplo, este programa rellena la pantalla con un patrón de barras verticales:

Código: Seleccionar todo

void main (void)
{
  char *p;  /* para hacer "POKEs" de 8 bits */

  for (p=16384;p<=22527;p++)
    *p = 0x0F;
}
Equivaldría al siguiente programa BASIC:

Código: Seleccionar todo

10 FOR p=16384 TO 22527
20 POKE p,15
30 NEXT p

Re: [Assembler] - Solicitud Función POKE

Publicado: 21 Oct 2015, 11:33
por Radastan
Ya he editado mi respuesta con una función "elegante" y con los tipos perfectos.

Y McLeod, no seré yo el que te corrija porque corro el riesgo de equivocarme, pero el puntero... tiene que ser de 16 bits, no queda otra para direccionar 64K. Una cosa es el puntero y otra el contenido del puntero.

Re: [Assembler] - Solicitud Función POKE

Publicado: 22 Oct 2015, 00:10
por mcleod_ideafix
Radastan escribió:Y McLeod, no seré yo el que te corrija porque corro el riesgo de equivocarme, pero el puntero... tiene que ser de 16 bits, no queda otra para direccionar 64K. Una cosa es el puntero y otra el contenido del puntero.
Todos los punteros en el Spectrum son de 16 bits. Si defines:

Código: Seleccionar todo

char *p1;
int *p2;
Ambos, p1 y p2 son variables que ocupan 16 bits, pero p1, al escribir en su contenido, es equivalente a una escritura de un byte en memoria, mientras que al escribir en el contenido de p2, estás haciendo una escritura de una palabra de 16 bits en memoria.

Por tanto tu función corregida sigue siendo errónea: sigues escribiendo un valor de 16 bits en memoria y no un valor de 8 bits en memoria. Lo que hace exactamente tu función, de acuerdo con la semántica del lenguaje C es:
- Evalúa "valor". Es de 8 bits sin signo
- Mira el tipo de datos de la variable a la que apunta "puntero". Ese tipo de datos es "int": 16 bits con signo
- Se promociona automáticamente "valor" de 8 bits sin signo a 16 bits con signo. Para ello, se añaden 8 bits a 0 por la izquierda.
- El nuevo valor de 16 bits así obtenido se escribe en memoria, a partir de la dirección indicada en "puntero". Dado que el Spectrum no tiene instrucciones para realizar escrituras de 16 bits en donde el operando de memoria sea un registro que contenga la dirección del mismo, lo que se hacen son dos escrituras de 8 bits a la dirección "puntero" y a "puntero+1"

Convertida en ensamblador, haría algo como esto (dejando aparte el manejo del marco de pila, que no sé cómo es en el Z88DK) suponiendo que puntero estuviera en HL y valor en A:

Código: Seleccionar todo

  ld (hl),a
  inc hl
  ld (hl),0
Esta función, por otra parte:

Código: Seleccionar todo

void poke (unsigned char *puntero, unsigned char valor)
{
   *puntero=valor;
}
Sí que se traduce a:

Código: Seleccionar todo

  ld (hl),a

Re: [Assembler] - Solicitud Función POKE

Publicado: 22 Oct 2015, 08:07
por Radastan
Y yo manejando punteros erróneamente en Z88DK, tela.

Lo dicho, muchas gracias porque así no meto la pata.

Re: [Assembler] - Solicitud Función POKE

Publicado: 22 Oct 2015, 09:02
por Hark0
Joe, mucho más de lo que preguntaba!!!!

(De hecho estaba averiguando/estudiando) como pasarle valores al ASM.

Gracias 1000!!!!!!!

;)

Re: [Assembler] - Solicitud Función POKE

Publicado: 23 Oct 2015, 09:44
por Radastan
Hark0 escribió:(De hecho estaba averiguando/estudiando) como pasarle valores al ASM.
Es fácil, mira esta rutina:

Código: Seleccionar todo

// ___________________________________________
// Función para sacar un dato por un puerto
// ___________________________________________

void port_out (int port, int value)
{
	#asm
	ld hl,2
	add hl,sp
	ld a, (hl)
	inc hl
	inc hl
	ld c, (hl)
	inc hl
	ld b, (hl)
	out (c),a
	#endasm
}
En primer lugar sumas en hl el valor 2 y sp (para que apunte a donde están las variables de entrada). A partir de ahí coges los valores del último al primero (orden inverso).

Re: [Assembler] - Solicitud Función POKE

Publicado: 23 Oct 2015, 10:09
por Hark0
Justamente ESO estaba yo estudiando... ;)

Gracias again!