Activar un pixel de pantalla con ensamblador
Moderador: Sir Cilve Sinclair
- iadvd
- rst 0
- Mensajes: 39
- Registrado: Mar Abr 09, 2019 9:48 am
- Ubicación: Tokio, Japon
- Contactar:
Activar un pixel de pantalla con ensamblador
Hola a tod@s, tengo una duda de ensamblador, si alguien con experiencia
me puede echar una mano con la duda y tiene un momento para darme pistas de esto
me ayudaría muchísimo:
En un 48k, tengo una pantalla mostrándose en la zona de memoria de pantalla,
ahora dependiendo de unas condiciones, quiero activar un único pixel de la pantalla x,y ,
el paper de dicho pixel es negro y el ink es amarillo (es decir, el paper y el ink
del udg - se dice asi al bloque de pixels verdad?- al que pertenece dicho pixel es así),
lo que quiero es según una condición que pasa en un bucle es poner en ese pixel determinado x,y
el ink activado y por tanto se ve ese pixel amarillo o desactivado y por tanto se ve el paper, es decir negro.
Existe una forma fácil de hacer este set/unset de un solo pixel con ensamblador?
En un principio pensé que no, que me tocara hacer algo como esto:
1. leer el udg que esta en la posición que incluye dicho pixel y meterlo en una variable con LD
2. Para hacer "set" hacer algún tipo de operación OR con otro udg que solo tiene un "1" justo
en el pixel que quiero activar; y si lo quiero desactivar un AND con un udg que tiene todo unos
excepto justo un "0" en la misma posición del pixel.
3. poner de nuevo el udg modificado en la zona de memoria de pantalla a través de la variable del
paso 1 ya modificado otra vez con LD.
Aun así no se como implementarlo. Esto leyendo algunos cursos de ensamblador, y creo que me va a costar
un tiempo ponerme al día y entender el proceso, pero si alguien me puede explicar un código que lo haga
por aquí lo agradecería muchísimo, ya que hace mucho que no toco el ensamblador. Al menos la
estructura básica seria una gran ayuda.Mientras sigo mirando a ver si consigo hacerlo por mi cuenta (en tal caso pondré mi solución por aquí)
Saludos y gracias!
me puede echar una mano con la duda y tiene un momento para darme pistas de esto
me ayudaría muchísimo:
En un 48k, tengo una pantalla mostrándose en la zona de memoria de pantalla,
ahora dependiendo de unas condiciones, quiero activar un único pixel de la pantalla x,y ,
el paper de dicho pixel es negro y el ink es amarillo (es decir, el paper y el ink
del udg - se dice asi al bloque de pixels verdad?- al que pertenece dicho pixel es así),
lo que quiero es según una condición que pasa en un bucle es poner en ese pixel determinado x,y
el ink activado y por tanto se ve ese pixel amarillo o desactivado y por tanto se ve el paper, es decir negro.
Existe una forma fácil de hacer este set/unset de un solo pixel con ensamblador?
En un principio pensé que no, que me tocara hacer algo como esto:
1. leer el udg que esta en la posición que incluye dicho pixel y meterlo en una variable con LD
2. Para hacer "set" hacer algún tipo de operación OR con otro udg que solo tiene un "1" justo
en el pixel que quiero activar; y si lo quiero desactivar un AND con un udg que tiene todo unos
excepto justo un "0" en la misma posición del pixel.
3. poner de nuevo el udg modificado en la zona de memoria de pantalla a través de la variable del
paso 1 ya modificado otra vez con LD.
Aun así no se como implementarlo. Esto leyendo algunos cursos de ensamblador, y creo que me va a costar
un tiempo ponerme al día y entender el proceso, pero si alguien me puede explicar un código que lo haga
por aquí lo agradecería muchísimo, ya que hace mucho que no toco el ensamblador. Al menos la
estructura básica seria una gran ayuda.Mientras sigo mirando a ver si consigo hacerlo por mi cuenta (en tal caso pondré mi solución por aquí)
Saludos y gracias!
- iadvd
- rst 0
- Mensajes: 39
- Registrado: Mar Abr 09, 2019 9:48 am
- Ubicación: Tokio, Japon
- Contactar:
Re: Activar un pixel de pantalla con ensamblador
Parece que ha avanzado un poquito...
He podido comprender que se leen 8 bits de pantalla de una tacada, asi que si mi
pantalla tiene (creo) 32 bloques de 8 bits de ancho y la altura es de 21*8=168 bits de alto
(tengo que mirarlo bien) entonces si mi (x,y) es uno de los ocho bits -ambos empiezan en indice 0-
del bloque B de la linea de pixels L por ejemplo, entonces quiero leer:
LD HL, 16384+(32*L)+B
LD A, (HL)
AND A, _asm_int
LD (HL), A
_asm_int es una variable en la que tengo el valor 11011111 binario
esto esta mapeando los pixels activos de dicha linea de pixels de pantalla.
Lo he probado y funciona, pero mi calculo de la posicion de pantalla esta mal, sale en otra posicion,
pero lo que es en si la rutina de leer de pantalla y hacer and / or dependiendo de lo que
necesite y volver a color, parece que funciona.
Si alguien sabe bien los calculos de la posicion de un pixel en pantalla a partir de la posicion 16384 de un 48k
se agradece (estoy usando una pantalla de 16 tiles * 8 de ancho de resolucion (creo que es la estandar
que se suele usar)
Gracias de nuevo!
He podido comprender que se leen 8 bits de pantalla de una tacada, asi que si mi
pantalla tiene (creo) 32 bloques de 8 bits de ancho y la altura es de 21*8=168 bits de alto
(tengo que mirarlo bien) entonces si mi (x,y) es uno de los ocho bits -ambos empiezan en indice 0-
del bloque B de la linea de pixels L por ejemplo, entonces quiero leer:
LD HL, 16384+(32*L)+B
LD A, (HL)
AND A, _asm_int
LD (HL), A
_asm_int es una variable en la que tengo el valor 11011111 binario
esto esta mapeando los pixels activos de dicha linea de pixels de pantalla.
Lo he probado y funciona, pero mi calculo de la posicion de pantalla esta mal, sale en otra posicion,
pero lo que es en si la rutina de leer de pantalla y hacer and / or dependiendo de lo que
necesite y volver a color, parece que funciona.
Si alguien sabe bien los calculos de la posicion de un pixel en pantalla a partir de la posicion 16384 de un 48k
se agradece (estoy usando una pantalla de 16 tiles * 8 de ancho de resolucion (creo que es la estandar
que se suele usar)
Gracias de nuevo!
- Nat
- Herbert
- Mensajes: 95
- Registrado: Lun Mar 25, 2019 9:31 am
Re: Activar un pixel de pantalla con ensamblador
La memoria de pantalla del ZX Spectrum tiene una organización optimizada para que a la ULA le sea muy sencillo leerla mientras representa su contenido en la TV. En tu código falta que considere los 3 tercios de 2048 bytes que forman la memoria de pantalla, 8 líneas cada uno, y después con un XOR inviertes el valor del pixel que tú quieras.
Si recuerdas cómo se carga una pantalla de presentación, ahí se observa sin problemas la organización real en la memoria.
Si X e Y son las coordenadas de un pixel en pantalla, la columna C (C=X/8) en el intervalo [0,32) e Y en [0,192), la dirección calculada en HL tiene este formato:
y este es un ejemplo de uso:
que puedes probar con este programa en BASIC:
Si recuerdas cómo se carga una pantalla de presentación, ahí se observa sin problemas la organización real en la memoria.
Si X e Y son las coordenadas de un pixel en pantalla, la columna C (C=X/8) en el intervalo [0,32) e Y en [0,192), la dirección calculada en HL tiene este formato:
Código: Seleccionar todo
; Get screen address
; B = Y pixel position
; C = X pixel position
; Returns address in HL
Get_Pixel_Address:
ld A,B ; Calculate Y2,Y1,Y0
and %00000111 ; Mask out unwanted bits
or %01000000 ; Set base address of screen
ld H,A ; Store in H
ld A,B ; Calculate Y7,Y6
rra ; Shift to position
rra
rra
and %00011000 ; Mask out unwanted bits
or H ; OR with Y2,Y1,Y0
ld H,A ; Store in H
ld A,B ; Calculate Y5,Y4,Y3
rla ; Shift to position
rla
and %11100000 ; Mask out unwanted bits
ld L,A ; Store in L
ld A,C ; Calculate X4,X3,X2,X1,X0
rra ; Shift into position
rra
rra
and %00011111 ; Mask out unwanted bits
or L ; OR with Y5,Y4,Y3
ld L,A ; Store in L
ret
Código: Seleccionar todo
org $8000
call FIND_INT2 ; Fetch the coordinates (B=Y, C=X)
push BC
ld BC,1 ; Push 1 to FP stack
call STACK_BC
pop BC
call Get_Pixel_Address ; Get screen address
ld A,(HL)
xor 128 ; Bit 7 leftmost pixel
ld (HL),A
ret
; Get screen address
; B = Y pixel position
; C = X pixel position
; Returns address in HL
Get_Pixel_Address:
ld A,B ; Calculate Y2,Y1,Y0
and %00000111 ; Mask out unwanted bits
or %01000000 ; Set base address of screen
ld H,A ; Store in H
ld A,B ; Calculate Y7,Y6
rra ; Shift to position
rra
rra
and %00011000 ; Mask out unwanted bits
or H ; OR with Y2,Y1,Y0
ld H,A ; Store in H
ld A,B ; Calculate Y5,Y4,Y3
rla ; Shift to position
rla
and %11100000 ; Mask out unwanted bits
ld L,A ; Store in L
ld A,C ; Calculate X4,X3,X2,X1,X0
rra ; Shift into position
rra
rra
and %00011111 ; Mask out unwanted bits
or L ; OR with Y5,Y4,Y3
ld L,A ; Store in L
ret
FIND_INT2 equ $1E99
STACK_BC equ $2D2B
Código: Seleccionar todo
10 LET x=255
20 LET y=191
30 LET l=(x+256*y)*USR 32768
40 PAUSE 0
50 GO TO 10
Última edición por Nat el Jue Nov 14, 2019 5:26 pm, editado 14 veces en total.
Saludos,
Nat
Nat
- iadvd
- rst 0
- Mensajes: 39
- Registrado: Mar Abr 09, 2019 9:48 am
- Ubicación: Tokio, Japon
- Contactar:
Re: Activar un pixel de pantalla con ensamblador
Fantástico muchas gracias Natohara!
- Nat
- Herbert
- Mensajes: 95
- Registrado: Lun Mar 25, 2019 9:31 am
Re: Activar un pixel de pantalla con ensamblador
De nada.
En un juego real y en función de la memoria libre, no se usan estos cálculos. En su lugar se recurre a tablas precalculadas de las direcciones de memoria de pantalla para el píxel más a la izquierda de cada línea. Esta otra técnica consume 384 (2x192) bytes de un bloque de 2 páginas (512 bytes) pero es mucho más rápida.
En un juego real y en función de la memoria libre, no se usan estos cálculos. En su lugar se recurre a tablas precalculadas de las direcciones de memoria de pantalla para el píxel más a la izquierda de cada línea. Esta otra técnica consume 384 (2x192) bytes de un bloque de 2 páginas (512 bytes) pero es mucho más rápida.
Saludos,
Nat
Nat
- Metalbrain
- Freddy Hardest
- Mensajes: 592
- Registrado: Lun May 07, 2007 8:17 am
- Ubicación: Sevilla
- Contactar:
Re: Activar un pixel de pantalla con ensamblador
Hola iadvd,
Para este tema, te aconsejo el curso de ensamblador de Santiago Romero que tenemos en esta misma página. El tema de las direcciones de los gráficos se trata de forma extensa en este capítulo:
https://wiki.speccy.org/cursos/ensambla ... ionamiento
Para este tema, te aconsejo el curso de ensamblador de Santiago Romero que tenemos en esta misma página. El tema de las direcciones de los gráficos se trata de forma extensa en este capítulo:
https://wiki.speccy.org/cursos/ensambla ... ionamiento
Para esa tabla, X en el intervalo [0,31] (porque estamos hablando de caracteres, no pixels) e Y en [0,191]Nat escribió:Si X e Y son las coordenadas de un pixel en pantalla, X en el intervalo [0,192) e Y en [0,256)
SevenuP se escribe con u minúscula y P mayúscula.
- Nat
- Herbert
- Mensajes: 95
- Registrado: Lun Mar 25, 2019 9:31 am
Re: Activar un pixel de pantalla con ensamblador
Gracias por la corrección, muy bien visto. La confusión surgió cuando primero puse el código que sí usa píxeles y en una edición posterior la tabla y se me pasó hablar de la transformación sobre el valor de X porque estuve entretenido de más buscando el conversor de GIFs con soporte para vídeos de más de 15 segundos por la dichosa pantalla de presentación.
Saludos,
Nat
Nat
- iadvd
- rst 0
- Mensajes: 39
- Registrado: Mar Abr 09, 2019 9:48 am
- Ubicación: Tokio, Japon
- Contactar:
Re: Activar un pixel de pantalla con ensamblador
Por cierto, que conseguí programarlo y funciona de maravilla! tengo un nuevo juego casi a puntito, y ahí se podrá ver el resultado! saludos y gracias de nuevo a todos por las recomendaciones!
¿Quién está conectado?
Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 15 invitados