limpieza de trailing whitespace

This commit is contained in:
sejo 2022-02-10 14:47:52 -06:00
parent c506c16cb3
commit 292ca4b33a
74 changed files with 759 additions and 759 deletions

View File

@ -1,16 +1,16 @@
# about
compudanzas is a research project exploring alternative modes of learning and creating computation.
compudanzas is a research project exploring alternative modes of learning and creating computation.
en español: {acerca}
we attempt to transition from a logic of productivity and efficiency, and circuits that destroy life, to dances, rituals, and other types of seemingly useless computers!
we attempt to transition from a logic of productivity and efficiency, and circuits that destroy life, to dances, rituals, and other types of seemingly useless computers!
we move calmly, patiently, and with curiosity.
we identify with the ideas of {permacomputing} and computing within limits.
=> ./img/foto_laconsagracion_playa.jpg photo of the rite of computing: there is a wiggly row of shapes in the floor, each of them composed of small blocks of wood. a person is crouching, building one of these shapes. other two people are watching, sitting in the floor. there are some cardboard shapes with symbols, also in the floor.
=> ./img/foto_laconsagracion_playa.jpg photo of the rite of computing: there is a wiggly row of shapes in the floor, each of them composed of small blocks of wood. a person is crouching, building one of these shapes. other two people are watching, sitting in the floor. there are some cardboard shapes with symbols, also in the floor.
# research
@ -40,13 +40,13 @@ we see the project existing in these three dimensions:
* pedagogic: can we guide others to learn in a critical and embodied way about the fundamentals of computers and digital technologies?
* performative: can we play with and inspire through explorations of emerging complexity?
* speculative: can we use this practice to imagine alternative present-futures?
* speculative: can we use this practice to imagine alternative present-futures?
=> ./img/foto_laconsagracion_04.jpg photo of pieces of wood in the floor, with some hands manipulating them
# meta
this {wiki} is always under construction.
this {wiki} is always under construction.
it exists in the web and in the {gemini} protocol:

View File

@ -25,7 +25,7 @@ nuestra principal línea de exploración son {las danzas}, pero también diseña
=> ./talks_and_workshops.gmi {talks and workshops}
=> ./tutorials.gmi {tutorials}
cuando escribimos software intentamos hacerlo siguiendo el {s-camino}, haciéndolo a un bajo nivel de abstracción.
cuando escribimos software intentamos hacerlo siguiendo el {s-camino}, haciéndolo a un bajo nivel de abstracción.
tendemos a escribir poesía/{poetry} relacionada a estos intereses, y también tenemos algunas publicaciones:
=> ./publications.gmi {publications}
@ -40,7 +40,7 @@ a través de nuestros experimentos nos preguntamos: ¿qué pasa cuando las compu
¿cuál puede ser el rol de computadoras aparentemente inútiles, no electrónicas, muy lentas, a escala humana, en un mundo que parece estar en colapso?
¿son materiales didácticos alternativos y empoderadores? ¿{performances}? ¿puzzles? ¿pasatiempos? ¿trucos de magia?
¿son materiales didácticos alternativos y empoderadores? ¿{performances}? ¿puzzles? ¿pasatiempos? ¿trucos de magia?
concebimos al proyecto existiendo en estas tres dimensiones:
@ -61,7 +61,7 @@ existe en la web y en el protocolo {gemini}:
somos un proyecto bilingüe; por el momento algunos contenidos están solo en castellano y algunos solo en inglés. si te interesa, puedes colaborar con nosotres realizando {traducciones}.
en el {log} puedes encontrar actualizaciones en el proyecto, en el {roadmap} puedes encontrar actualizaciones que quieren suceder en el proyecto, o también puedes ver el índice de todas las páginas en el sitio:
en el {log} puedes encontrar actualizaciones en el proyecto, en el {roadmap} puedes encontrar actualizaciones que quieren suceder en el proyecto, o también puedes ver el índice de todas las páginas en el sitio:
=> ./pages.gmi {pages}
estamos coleccionando referencias que nos inspiran y nutren:
@ -75,7 +75,7 @@ por acá encuentras distintas formas de ponernos en {contacto}.
¡necesitamos de tu {apoyo} para lograr la meta de tener a este proyecto de ensueño como nuestra actividad principal!
=> https://www.patreon.com/compudanzas apoya a compudanzas en patreon
=> https://www.patreon.com/compudanzas apoya a compudanzas en patreon
=> https://ko-fi-com/compudanzas apoya a compudanzas en ko-fi
¡también nos puedes apoyar comprando nuestro libro: {introducción a programación uxn}!

View File

@ -73,7 +73,7 @@ PROGRAMMER = usbasp
# ensambla programa a .hex
hex:
avr-gcc -Os -DF_CPU=8000000 -mmcu=$(BOARD) -c $(PROG).S
avr-gcc -Os -DF_CPU=8000000 -mmcu=$(BOARD) -c $(PROG).S
avr-ld -o $(PROG).elf $(PROG).o
avr-objcopy $(PROG).elf -O ihex $(PROG).hex
rm $(PROG).o $(PROG).elf

View File

@ -10,7 +10,7 @@ presented in the itp winter show 2017.
# interaction
each brick/bit has two possible states: high or low.
each brick/bit has two possible states: high or low.
the string of bricks/bits encodes an instruction for the computer: the cell in the screen that will be modified, and the visual pattern that will be assigned to it.

View File

@ -20,7 +20,7 @@ the directions come from combining these 3 levels with the 9 possible point dire
* medium
* high
## point directions
## point directions
* left
* right

View File

@ -8,7 +8,7 @@ un "dispositivo"-danza que almacena información binaria, con capacidad de ser e
# guía
cada persona ve a alguien más, y es vista por otra distinta.
cada persona ve a alguien más, y es vista por otra distinta.
para iniciar, podemos acomodarnos en círculo. nuestra red es un ciclo.
@ -18,7 +18,7 @@ cada persona ve a alguien más, poniendo atención en cuál de las tres señales
* alto
* bajo
hay música con pulso.
hay música con pulso.
en cada beat, la persona replica la señal que vio adelante.
@ -30,7 +30,7 @@ para leer el dato almacenado, una persona-lectora fuera del ciclo se sintoniza a
la persona-lectora se enfoca en observar a una sola persona dentro, que se convierte en la persona-salida.
al observar la señal de corte, la persona-lectora empieza a anotar, repetir, transmitir, las señales de alto o bajo que vengan después.
al observar la señal de corte, la persona-lectora empieza a anotar, repetir, transmitir, las señales de alto o bajo que vengan después.
así continúa hasta observar de nuevo el corte: el dato habrá sido leído, y se mantiene en circulación.

View File

@ -27,8 +27,8 @@ deep adaptation agenda, the 4 Rs:
## how to live like the world is ending
* act like were about to die.
* act like we might not die right away.
* act like we might have a chance to stop this.
* act like we might not die right away.
* act like we might have a chance to stop this.
* act like everything will be okay.
=> http://birdsbeforethestorm.net/2019/12/how-to-live-like-the-world-is-ending/ how to live the world is ending - margaret killjoy

View File

@ -2,7 +2,7 @@
non-electronic computers that work when you color them according to a simple set of rules.
an exploration of computation without electricity and semiconductors, an attempt to reinvent digital systems away from efficiency and productivity, and hopeful prototypes to expose the inner workings of computers.
an exploration of computation without electricity and semiconductors, an attempt to reinvent digital systems away from efficiency and productivity, and hopeful prototypes to expose the inner workings of computers.
=> https://ipfs.io/ipfs/QmaiMEk5Stw5Xvfs1btAwMg2sctwEq1MS9NDJAUEr1SHvf/ coloring computers pack archive
@ -14,7 +14,7 @@ related and inspired by some previous experiments like {arte generativo en papel
=> ./img/foto_20201130_hex7segdecoder_02.png a human coloring the wires according to the logic rules
=> ./img/foto_20201130_hex7segdecoder_03.png the coloring computer/decoder, with an input of 0011, and an output that can be read as 3
a coloring decoder built with NOT (triangle), AND (semicircle), and OR (the other shape (?)) gates ({compuertas}), based on a manual design.
a coloring decoder built with NOT (triangle), AND (semicircle), and OR (the other shape (?)) gates ({compuertas}), based on a manual design.
=> ./img/dibujo_20201207_hex7segdecoder_small.png the complete decoder
@ -37,7 +37,7 @@ the original ones
=> ./img/foto_coloring-computers_7seg-lee.png photo of a pair of colored pages of the zine, with a 7 segment display showing the digits 2 and 3
=> ./img/foto_coloring-computers_pcd2019.png photo of a pair of colored pages of the zine, showing a digital circuit answering if two colors are the same
the booklet contains three series of computers: computers that compare, computers that count, and computers that play. they are all {nor}-based logic circuits designed by using truth tables, karnaugh maps, and maxterm expansions.
the booklet contains three series of computers: computers that compare, computers that count, and computers that play. they are all {nor}-based logic circuits designed by using truth tables, karnaugh maps, and maxterm expansions.
=> https://ipfs.io/ipfs/QmYz7DPRWypGQcbAHr7Mi8EKB6ntSPsEnUsCXbAhBiHQZP/ original site and resources
=> https://ipfs.io/ipfs/QmYz7DPRWypGQcbAHr7Mi8EKB6ntSPsEnUsCXbAhBiHQZP/coloringcomputers_pages.pdf download the page-by-page zine (pdf, ~1.5MB)

View File

@ -18,7 +18,7 @@ la salida es igual a la entrada
## NOT
la salida es lo opuesto a la entrada.
la salida es lo opuesto a la entrada.
también podríamos decir que la salida es lo que no es la entrada.
@ -94,9 +94,9 @@ en cualquier otro caso, la salida es falsa.
también la podemos describir así: la salida es verdadera cuando las entradas son diferentes, y es falsa cuando las entradas son iguales.
## NOR
## NOR
la salida es verdadera cuando ninguna de sus entradas es verdadera.
la salida es verdadera cuando ninguna de sus entradas es verdadera.
que es lo mismo que decir que su salida es verdadera cuando todas sus entradas son falsas.
@ -127,7 +127,7 @@ por cómo funciona, también la podemos considerar como un AND que funciona con
## NAND
la salida es verdadera cuando aunque sea una de sus entrada es falsa.
la salida es verdadera cuando aunque sea una de sus entrada es falsa.
únicamente cuando todas sus entradas son verdaderas, su salida es falsa.
@ -154,7 +154,7 @@ por cómo funciona, también la podemos considerar como un OR que funciona con 0
todas las compuertas funcionan igual para más de dos entradas, excepto XOR.
importante: AND y OR poseen la propiedad distributiva.
importante: AND y OR poseen la propiedad distributiva.
por ejemplo, un AND de tres entradas (a, b, c) es equivalente a un AND de dos entradas (a, b), con su salida (x) conectada a la entrada de otro AND de dos entradas (x, c)

View File

@ -88,7 +88,7 @@ este es el programa en formato de lista de números a colocar en la memoria de p
* 4: 2 1
* 5: 0 0
el primer dígito en la lista es el número de línea.
el primer dígito en la lista es el número de línea.
los dos dígitos siguientes son el primer y segundo números de instrucción

View File

@ -1,6 +1,6 @@
# contact
let's connect!
let's connect!
our e-mail address: compudanzas at posteo dot net

View File

@ -52,7 +52,7 @@ la instructora tiene que conocer todos los movimientos nombrados arriba.
hay que acomodar la cinta de símbolos en una configuración inicial adecuada.
la cabeza en cinta se coloca al lado del primer símbolo.
la cabeza en cinta se coloca al lado del primer símbolo.
el semáforo empieza a moverse con el estado inicial.

View File

@ -26,12 +26,12 @@ Our stage space contains a mix of the following elements: single blocks, engrave
The plaques contain formulas that describe the operations to perform during a given configuration. These operations consist in shifting the current point of action in the row of shapes, transforming} a current active shape into another, and transitioning to another configuration.
Once set in motion, the interactions between these heterogeneous parts cause emergent properties that perform computation; in that sense this machine is in dialog with the concept of assemblage as described by DeLanda [2].
Once set in motion, the interactions between these heterogeneous parts cause emergent properties that perform computation; in that sense this machine is in dialog with the concept of assemblage as described by DeLanda [2].
Each choreographic configuration is represented by a specific symbol in a plaque that invokes a predefined atmosphere to improvise with.
The dancers follow the formulas of one of these plaques held in the air, while performing discrete operations on the shapes of the worm. Sometimes these shapes will trigger a formula that require a transition: the plaque is exchanged for another, and the choreography changes into the new configuration.
A difference between this work and other Turing machine dances that could be found [1] is the absence of electronics in its workings and creation. By removing electricity as much as possible, the idea is to help blurring boundaries (organic - inorganic, human - machine) and to prompt questions about the nature} of computers.
Wechsler differentiated between "art that is concerned with computers, or art that is merely created using computers" [8] when discussing dance, computers, and art; the aim of the rite of computing is to be dance concerned with computers, and to be a computer that is [merely] created using dance.

View File

@ -22,7 +22,7 @@ la arquitectura base consta de al menos 6 personas:
* LU: la que responde preguntas lógicas
## materiales
## materiales
como materiales tangibles solo se requiere la lista de números que administra la Memoria.
@ -37,7 +37,7 @@ se necesita contar con, y conocer, el siguiente conjunto de movimientos.
### todas las personas
* dígito-movimiento: un movimiento por cada digito en la base elegida (por ejemplo, del 0 al 9 para trabajar en base 10)
* dígito-movimiento: un movimiento por cada digito en la base elegida (por ejemplo, del 0 al 9 para trabajar en base 10)
* posición: una forma de indicar si un dígito es el primero o el segundo
* finalización: un movimiento que indique que el cómputo ha terminado
@ -117,12 +117,12 @@ les Registros ahora pueden ser inspeccionados para leer los resultados del cómp
* CU se mueve dirigiéndose a les Registros, transmitiendo el dígito-movimiento que recibió como argumento
* Registros reciben el dígito
* Registro que tiene a ese dígito en su nombre, hace más evidente el dígito-movimiento que estaba realizando
* Registro que tiene a ese dígito en su nombre, hace más evidente el dígito-movimiento que estaba realizando
* les demás Registros reducen la amplitud de su propio dígito-movimiento.
* CU se mueve preguntando a LU si el Registro es 0.
* LU recibe la pregunta, y observa al Registro con movimiento amplio
* LU se mueve respondiendo sí o no
* CU recibe la respuesta de LU
* CU recibe la respuesta de LU
* CU se mueve dirigéndose a PC: si la respuesta que recibió de LU fue sí, entonces se mueve indicando un doble incremento; si la respuesta fue no, entonces se mueve indicando un incremento sencillo
* PC recibe la indicación, y pasa al siguiente dígito-movimiento, ya sea una o dos veces según lo recibido.
* la máquina pasa a la etapa fetch
@ -139,7 +139,7 @@ les Registros ahora pueden ser inspeccionados para leer los resultados del cómp
* CU se mueve dirigiéndose a les Registros, transmitiendo el dígito-movimiento que recibió como argumento
* Registros reciben el dígito
* Registro que tiene a ese dígito en su nombre, hace más evidente el dígito-movimiento que estaba realizando
* Registro que tiene a ese dígito en su nombre, hace más evidente el dígito-movimiento que estaba realizando
* les demás Registros reducen la amplitud de su propio dígito-movimiento.
* CU se mueve dirigiéndose a les Registros, transmitiendo la indicación de incremento
* Registro con el movimiento amplio, pasa al dígito-movimiento siguiente al que estaba realizando (incrementa en 1 al valor que estaba almacenando)
@ -153,7 +153,7 @@ les Registros ahora pueden ser inspeccionados para leer los resultados del cómp
* CU se mueve dirigiéndose a les Registros, transmitiendo el dígito-movimiento que recibió como argumento
* Registros reciben el dígito
* Registro que tiene a ese dígito en su nombre, hace más evidente el dígito-movimiento que estaba realizando
* Registro que tiene a ese dígito en su nombre, hace más evidente el dígito-movimiento que estaba realizando
* les demás Registros reducen la amplitud de su propio dígito-movimiento.
* CU se mueve dirigiéndose a les Registros, transmitiendo la indicación de decremento
* Registro con el movimiento amplio, pasa al dígito-movimiento anterior al que estaba realizando (decrementa en 1 al valor que estaba almacenando)
@ -178,7 +178,7 @@ este es el programa en formato de lista de números para que administre Memoria.
* 4: 2 1
* 5: 0 0
el primer dígito en la lista es el número de línea.
el primer dígito en la lista es el número de línea.
los dos dígitos siguientes son el primer y segundo dígitos de instrucción

View File

@ -1,6 +1,6 @@
# danzas compuertas
antiguas historias hablaban de computar en conjunto, en comunidad.
antiguas historias hablaban de computar en conjunto, en comunidad.
tareas sencillas y divertidas que requieren atención y presencia y que combinadas dan paso a complejidad, a olas, a cambios.
@ -30,7 +30,7 @@ más circuitos posibles, en la {logiteca}
qué tal un sumador completo, aprovechando la idea de {ciclo de memoria}
aquí un diagrama animado que muestra un par de ciclos de memoria como entrada a un full-adder.
aquí un diagrama animado que muestra un par de ciclos de memoria como entrada a un full-adder.
el resultado del full-adder está conectado a otro ciclo de memoria. todos los componentes conformados por personas.

View File

@ -6,7 +6,7 @@ una compudanza basada en máquina abstracta (tag systems, o bien, máquina de po
# descripción
las danzasistemas-tag consisten en "batallas" de baile en las que alternamos recibiendo y respondiendo secuencias de movimiento.
las danzasistemas-tag consisten en "batallas" de baile en las que alternamos recibiendo y respondiendo secuencias de movimiento.
las secuencias que respondemos son producto de procesar elementos de la secuencia que recibimos.
@ -49,13 +49,13 @@ si primer símbolo/movimiento es 'b', agrega 'a' al final.
si primer símbolo/movimiento es 'c', agrega 'aaa' al final.
nota cómo cada regla de producción agrega una cantidad distinta de símbolos/movimientos al final.
nota cómo cada regla de producción agrega una cantidad distinta de símbolos/movimientos al final.
## m: número de eliminación
en este caso, siempre descartaremos 2 símbolos/movimientos del inicio de la secuencia.
## desarrollo
## desarrollo
partiendo de una secuencia inicial 'aaa'...
@ -95,7 +95,7 @@ si primer símbolo/movimiento es 'b', agrega 'ba' al final.
en este caso, siempre descartaremos 1 símbolo/movimiento del inicio de la secuencia.
## desarrollo
## desarrollo
partiendo de una secuencia inicial 'aaa'...
@ -107,8 +107,8 @@ respuesta: bbb
respuesta: bbba
respuesta: bbaba
respuesta: bababa
respuesta: abababa
respuesta: bababab
respuesta: abababa
respuesta: bababab
```

View File

@ -6,13 +6,13 @@ textos hacia una práctica post-civilización.
Primero que nada, te invito, nos invito, a estar presentes.
Respirar profundo, y de ser posible, mirar por alguna ventana. Notar el espacio de posibilidades que nos presenta lo que llamamos cielo.
Respirar profundo, y de ser posible, mirar por alguna ventana. Notar el espacio de posibilidades que nos presenta lo que llamamos cielo.
Espero que no fuera hace mucho la vez más reciente que le habías visto.
Ahora bien, en este texto, partimos de la noción de que algo grande se está terminando. No solo grande, sino enorme; tal vez inabarcable, tal vez inconcebible.
Partimos de la noción de que la civilización se está terminando.
Partimos de la noción de que la civilización se está terminando.
O de que ya se terminó, según desde dónde le veamos.
@ -34,7 +34,7 @@ Personalmente, prefiero dejármelo sentir. No me va eso de hacerme creer que no
Ya no me creo el cuento del progreso, de las soluciones tecnocéntricas.
Vivir como si la civilización ya no existiera es lo que mejor me suena. Requiere creatividad, curiosidad, disposición, compasión y paciencia. Es alcanzable. No hay una fórmula específica, homogénea.
Vivir como si la civilización ya no existiera es lo que mejor me suena. Requiere creatividad, curiosidad, disposición, compasión y paciencia. Es alcanzable. No hay una fórmula específica, homogénea.
Es plantar semillas de lo que pueda venir después: puede que no germinen, ¿pero realmente me veo haciendo otra cosa?
@ -46,8 +46,8 @@ Por el momento usamos internet, después ya veremos. Si los cables seguirán pla
---
Te invito a respirar de nuevo. A moverte con cómo te sientes ahora.
Te invito a respirar de nuevo. A moverte con cómo te sientes ahora.
Te invito a acompañarnos en esta búsqueda.
Te invito a acompañarnos en esta búsqueda.
Está bien si todavía no es el momento. Ya sabes dónde me encuentro.

View File

@ -89,7 +89,7 @@ ffmpeg -i out.ogv -filter:v "crop=1280:720:0:0" -codec:v libx264 -codec:a libmp3
# video a partir de una imagen
```
# video de una imagen,
# video de una imagen,
# 10 segundos, 30 frames por segundo
ffmpeg -loop 1 \
-i imagen_verde.png \

View File

@ -1,6 +1,6 @@
# fluidics
the use of a fluid to perform analog or digital operations similar to those performed with electronics.
the use of a fluid to perform analog or digital operations similar to those performed with electronics.
=> https://www.gwern.net/docs/cs/1964-gluskin.pdf FLODAC - a pure fluid digital computer
=> https://www.nature.com/articles/s41598-021-90485-z Microfluidic-based processors and circuits design

View File

@ -16,7 +16,7 @@ this book has a great pace and nice illustrations
# some words
## running
## running
these are some words for doing arithmetic with paces (min/km) and velocities (km/hr) relevant to {running}
@ -40,7 +40,7 @@ these are some words for doing arithmetic with paces (min/km) and velocities (km
for example, to convert a velocity to a pace, and print it:
``` input: 18, output: 3'20"
18 vel>s1k .ms
18 vel>s1k .ms
output:
3'20" ok
@ -53,7 +53,7 @@ to do the opposite operation:
output:
18 km/hr ok
```
```
to get the pace of a given segment, using minutes, seconds and distance in meters:
@ -69,7 +69,7 @@ to get the difference between two times in minutes, seconds:
``` input: 3 20 3 15, output: 0'05"
( 3'20" - 3'15" )
3 20 3 15 ms- .ms
3 20 3 15 ms- .ms
output:
5" ok

View File

@ -1,6 +1,6 @@
# gemini
protocolo del "small internet" para documentos de hipertexto:
protocolo del "small internet" para documentos de hipertexto:
* minimalista en su especificación
* una conexión por documento
@ -70,7 +70,7 @@ echo "gemini://compudanzas.net/" | openssl s_client -connect compudanzas.net:196
para confirmar fingerprint como cliente:
```
openssl s_client -showcerts -servername compudanzas.net -connect compudanzas.net:1965 </dev/null | openssl x509 -fingerprint
openssl s_client -showcerts -servername compudanzas.net -connect compudanzas.net:1965 </dev/null | openssl x509 -fingerprint
```
actualmente el resultado de la fingerprint debe ser:

View File

@ -25,7 +25,7 @@ este es el archivo paquetes.scm que utilizamos:
``` paquetes.scm
; paquetes.scm
(specifications->manifest
(list
(list
; multimedia
"evince" ; pdf viewer
"vlc"
@ -157,7 +157,7 @@ guix install glibc-utf8-locales font-dejavu
agregar lo siguiente a .xsessionrc
```
if [ -f ~/.profile ]; then
if [ -f ~/.profile ]; then
. ~/.profile
fi
```

View File

@ -1,12 +1,12 @@
# hexadecimal
numeral system in base 16: it uses 16 digits, from 0 to 9 and from 'a' to 'f'.
numeral system in base 16: it uses 16 digits, from 0 to 9 and from 'a' to 'f'.
there's a direct mapping between each possible combination of 4 bits (bin), and an hexadecimal (hex) digit.
there's a direct mapping between each possible combination of 4 bits (bin), and an hexadecimal (hex) digit.
a group of 4 bits is called a nibble.
sistema numérico en base 16: utiliza 16 dígitos, del 0 al 9 y de la 'a' a la 'f'.
sistema numérico en base 16: utiliza 16 dígitos, del 0 al 9 y de la 'a' a la 'f'.
hay un mapeo directo entre cada posible combinación de 4 bits (bin) y un dígito hexadecimal (hex).

View File

@ -1,5 +1,5 @@
# compudanzas
explorando computación a escala humana: encuentra en qué estamos {ahora}, visita el {log} de nuestras actividades, o lee {acerca} del proyecto.
explorando computación a escala humana: encuentra en qué estamos {ahora}, visita el {log} de nuestras actividades, o lee {acerca} del proyecto.
explorations of computing at a human scale: find out what we are up to {now}, visit our activity {log}, or read {about} the project.

View File

@ -61,7 +61,7 @@ convert imagen.png -quality 100 -units PixelsPerInch -density 300x300 imagen.pdf
para el caso opuesto:
```
convert -quality 100 -units PixelsPerInch -density 300x300 imagen.pdf imagen.png
convert -quality 100 -units PixelsPerInch -density 300x300 imagen.pdf imagen.png
```
# reduce la cantidad de colores
@ -92,7 +92,7 @@ convert -size 100x100 xc:'rgb(0,255,0)' imagen_verde.png
con ruido:
```
convert -size 100x100 xc: +noise Random imagen_ruido.png
convert -size 100x100 xc: +noise Random imagen_ruido.png
```
# compone/encima imágenes
@ -100,7 +100,7 @@ convert -size 100x100 xc: +noise Random imagen_ruido.png
para componer una imagen con fondo transparente sobre otra que se convertirá en su fondo
```
composite -gravity center imagen_con_alpha.png fondo.png resultado.png
composite -gravity center imagen_con_alpha.png fondo.png resultado.png
```
# extiende imagen

View File

@ -28,7 +28,7 @@ In this workshop we'll introduce the basic concepts to start programming this co
Pre-requisites: This workshop is best for those with some previous programming experience. However, no previous experience with assembly or low-level computing is needed.
We will use the learn-uxn website by metasyn, that requires a web browser with javascript enabled:
We will use the learn-uxn website by metasyn, that requires a web browser with javascript enabled:
=> https://metasyn.github.io/learn-uxn learn-uxn
# outline
@ -42,7 +42,7 @@ We will use the learn-uxn website by metasyn, that requires a web browser with j
=> https://wiki.xxiivv.com/site/varvara.html varvara documentation
=> https://web.archive.org/web/20210415134117/http://www.unknownfieldsdivision.com/summer2014china-aworldadriftpart02.html Unknown Fields Division - Summer 2014 China Cargo ship expedition
=> https://www.youtube.com/watch?v=YMKJ7S7fKOk Rare Earthenware - Unknown Fields
=> https://www.youtube.com/watch?v=YMKJ7S7fKOk Rare Earthenware - Unknown Fields
## 2) uxntal basics
@ -101,7 +101,7 @@ We will use the learn-uxn website by metasyn, that requires a web browser with j
=> https://git.sr.ht/~rabbits/uxn uxn source code
=> ./hexadecimal.gmi {hexadecimal}
## and more
## and more
=> ./uxn_tutorial.gmi {uxn tutorial}
=> https://wiki.xxiivv.com/site/uxntal_reference.html the uxntal opcode manual
@ -124,7 +124,7 @@ irc channel: #uxn on irc.esper.net
|90 @Mouse [ &vector $2 &x $2 &y $2 &state $1 &wheel $1 ]
( init )
|0100
|0100
@on-reset
( set system colors )
#0a6f .System/r DEO2

View File

@ -36,7 +36,7 @@ este ciclo hace que todos los videos estén "en espejo", además de que permite
```
for(v of document.getElementsByTagName('video')){
for(v of document.getElementsByTagName('video')){
v.classList.add('flipVideoX'); // "espejea"
v.style.objectFit = 'cover'; // "redimensiona"
};

View File

@ -24,7 +24,7 @@ la consagración de la computadora es una ceremonia, colaboración y celebració
=> ./img/foto_laconsagracion-riley-4.gif foto: una persona rueda por el suelo observando una pieza de cartón, al lado de la fila de símbolos de piezas de madera
the rite of computing is a ceremony, a collaboration and celebration between human and non-human elements: a slow, sweaty, organic, locally-grown, inefficient, danced, turing-complete, computational machine; performing a potentially endless process of life.
the rite of computing is a ceremony, a collaboration and celebration between human and non-human elements: a slow, sweaty, organic, locally-grown, inefficient, danced, turing-complete, computational machine; performing a potentially endless process of life.
=> ./img/foto_laconsagracion-riley-6.gif foto: una persona en el suelo, cercana a la fila de símbolos de madera, en contraluz

View File

@ -16,7 +16,7 @@ on the other hand, we are interested in thoughtful and lighthearted posts. what
due to its experimental nature, many more things are waiting to be figured out.
if you are interested in joining, make sure to {contact} us. however, please note that for the moment we are only accepting people that we know already.
if you are interested in joining, make sure to {contact} us. however, please note that for the moment we are only accepting people that we know already.
## a little bit of tech-talk

View File

@ -6,7 +6,7 @@ compendio de circuitos lógicos que pueden implementarse en las {danzas compuert
los circuitos lógicos en este compendio están descritos en {verilog}, un lenguaje descriptor de hardware. esto con la idea de estandarizarlos, de facilitar simularlos e implementarlos en otros materiales, y de indicar su cualidad de red abstracta.
cada circuito indica un número de participantes que varía entre dos opciones. el número menor está calculado como el número de entradas más el número de compuertas. el otro número suma también el número de salidas del circuito completo, que de otra forma serían realizadas por alguna(s) de las compuertas.
cada circuito indica un número de participantes que varía entre dos opciones. el número menor está calculado como el número de entradas más el número de compuertas. el otro número suma también el número de salidas del circuito completo, que de otra forma serían realizadas por alguna(s) de las compuertas.
utilizamos el lenguaje a nivel de {compuertas} lógicas solamente: cada compuerta se expresa como una función (and(), not(), or(), nor(), nand(), etc) donde el primer argumento es el nombre de la salida de la compuerta, y el o los otros argumentos son los nombres de las entradas.
@ -81,7 +81,7 @@ al llegar al último número, se regresa a 0.
module contador(a, b, x, y);
input wire a,b;
input wire a,b;
output wire x,y;
not C1(y, b);
@ -93,14 +93,14 @@ endmodule
## contador de 2 bits con nor (7 o 9 participantes)
```
// contador de 2 bits con nor
// contador de 2 bits con nor
// entradas (2): a, b
// salidas (2): x, y
// compuertas (5): 2 de 1 y 3 de 2 entradas
module contador(a, b, x, y);
input wire a,b;
input wire a,b;
output wire x,y;
wire p1, p2, p3;
@ -126,7 +126,7 @@ endmodule
module contador(a, b, c, x, y, z);
input wire a,b,c;
input wire a,b,c;
output wire x,y,z;
wire p1, p2, p3, p4, p5;
@ -140,7 +140,7 @@ xor C2(y, a,b);
// para x
and(p3, p1, b, c)
and(p4, a, p2)
and(p4, a, p2)
and(p5, a, z)
or(x, p3, p4, p5)
@ -157,7 +157,7 @@ endmodule
module contador(a, b, c, x, y, z);
input wire a,b,c;
input wire a,b,c;
output wire x,y,z;
wire p1, p2, p3, p4, p5, p6, p7;
@ -297,7 +297,7 @@ output wire r, carry;
wire p1, p2, p3, p4, p5, p6, p7, p8, p9, p10;
// negadas
nor C1(p1, a);
nor C1(p1, a);
nor C2(p2, b);
nor C3(p3, c);

View File

@ -1,6 +1,6 @@
# mu: a human-scale computer
> Mu is a minimal-dependency hobbyist computing stack
> Mu is a minimal-dependency hobbyist computing stack
=> https://github.com/akkartik/mu mu repository
=> http://akkartik.name/akkartik-convivial-20200607.pdf bicycles for the mind have to be see-through

View File

@ -4,7 +4,7 @@ una de {las danzas} en donde bailamos con y a partir de una fila / tira / cinta
implementación especial de una máquina de turing {d-turing}, con la capacidad de simular, emular, ser, cualquier otra máquina de turing.
# contexto
# contexto
> no one has seriously proposed the use of a turing machine structure for any practical computation. indeed, i do not even know of one built for demonstration purposes (minsky, 1967, p128)
@ -47,7 +47,7 @@ la máquina cuenta con 23 estados posibles, expresados con las siguientes figura
las figuras con bordes curvos indican mover la cabeza hacia el origen, y las que tienen bordes rectos indican mover la cabeza lejos del origen.
las figuras solo indican los símbolos en la cinta (en naranja) que causan algun efecto:
las figuras solo indican los símbolos en la cinta (en naranja) que causan algun efecto:
* en verde está el símbolo al cual hay que transformar el símbolo leído
* en amarillo está el estado siguiente al que hay que transicionar.

View File

@ -138,7 +138,7 @@ halted
# comprobador de paréntesis
esta máquina revisa una secuencia con pares de paréntesis, y al finalizar escribe 1 si es una secuencia bien formada, o 0 si no.
esta máquina revisa una secuencia con pares de paréntesis, y al finalizar escribe 1 si es una secuencia bien formada, o 0 si no.
una secuencia bien formada de paréntesis implica que a cada paréntesis izquierdo le corresponde uno derecho.

View File

@ -8,7 +8,7 @@ a digital pet with hand-powered logic.
# description
norpet is a digital pet with hand-powered logic.
norpet is a digital pet with hand-powered logic.
its board (or non-electronic digital screen) consists in a grid of logical operations, one per cell, that you have to follow to bring your pet across its different states of life.

View File

@ -1,4 +1,4 @@
# now
# now
what are we up to approximately now.
@ -8,6 +8,6 @@ uploading our corrections to our {introduction to uxn programming book} and {int
creating {la sala}, experimental online-but-offline-first community summoned by compudanzas, based on exploring ssb.
preparing for {running} a marathon in some weeks.
preparing for {running} a marathon in some weeks.
you can find previous updates in our {log}.

View File

@ -59,7 +59,7 @@ en cada tiempo de transmisión, la persona calculadora ha de actuar de la siguie
al concluir la transmisión, la persona calculadora habrá terminado:
* en el movimiento alto si la cantidad de movimientos altos transmitidos fue impar.
* en el movimiento alto si la cantidad de movimientos altos transmitidos fue impar.
* en el movimiento bajo si la cantidad de movimientos altos transmitidos fue par
comprobemos que sí sea así, con secuencias de diferente longitud y paridad.
@ -96,6 +96,6 @@ al terminar la transmisión de la secuencia completa, revisamos el estado de la
probemos con secuencias de diferente longitud, a diferentes velocidades, y también a diferentes distancias.
¿llega a suceder que detectamos un error?
¿llega a suceder que detectamos un error?
¿qué pasa cuando hay dos errores en la comunicación? ¿es posible que el sistema no lo detecte?

View File

@ -10,11 +10,11 @@ none for the moment
# past
## 12019
## 12019
{la consagración de la computadora} was presented in two different events that year:
### june 21,22
### june 21,22
=> https://www.collab-orators.com/events/itp-residents-show itp residents show 2019, collab, brooklyn, ny

View File

@ -68,7 +68,7 @@ more projects and resources related with permacomputing:
salvage computing refers to utilizing only already available computational resources, , accepting that "genuine sustainability actually calls for an urgent halt to the manufacture of new electronic devices"
> how we get the most and best use out of existing hardware once we know nothing newer will ever come along.
> how we get the most and best use out of existing hardware once we know nothing newer will ever come along.
> Within a community of sufficient population density, existing hardware and software is already perfectly capable of implementing WiFi and/or Bluetooth mesh networks with zero dependency on any infrastructure external to the computer themselves - no cables, no cell towers or antenna masts, no satellites, no datacentres, nothing - so networking need not disappear entirely. But communication *between* such communities, across expanses of insufficient population density for meshes, is another question entirely.

View File

@ -2,7 +2,7 @@
an accepted application written in the beginning of 12016 for the itp-nyu masters degree, with some minor edits for formatting purposes.
shared for reference purposes: the four stages in the text are the precedents for the compudanzas project.
shared for reference purposes: the four stages in the text are the precedents for the compudanzas project.
for the record: i don't agree now with all that is stated :)
@ -14,9 +14,9 @@ for the record: i don't agree now with all that is stated :)
It is difficult to write this text.
I like to think of myself as a creator. I create choreographies, I create software, I create classes, and in general I create ideas that I have to make come true. In my experience, creativity and curiosity are two aspects of humanity that can enlighten, empower and free whoever is willing to see beyond the conventions. In order to foster them, changes and challenges are needed. My application into the ITP is based in the search for a different and stimulating environment, where things will not be easy, where my assumptions will be challenged, and where I will be surrounded by more people looking for more. I want to break free from my own mental barriers so that I can grow as a creator. This will allow me to have a broader impact inviting others to try living in the non conventional and authentic paths.
I like to think of myself as a creator. I create choreographies, I create software, I create classes, and in general I create ideas that I have to make come true. In my experience, creativity and curiosity are two aspects of humanity that can enlighten, empower and free whoever is willing to see beyond the conventions. In order to foster them, changes and challenges are needed. My application into the ITP is based in the search for a different and stimulating environment, where things will not be easy, where my assumptions will be challenged, and where I will be surrounded by more people looking for more. I want to break free from my own mental barriers so that I can grow as a creator. This will allow me to have a broader impact inviting others to try living in the non conventional and authentic paths.
Computing has been present in most of my life. I have enjoyed algorithmic thinking since the moment I was introduced to a programming language in my middle school days. An exciting journey of self-directed learning about computers, programming languages and operating systems started, and I got motivated writing my own scripts for automating diverse tasks, ranging from file management to simulations web applications. During my Electrical Engineering studies I was introduced to Digital Systems, and then computing began to make sense as a whole. However, although I liked those topics a lot, I felt that something was missing. My curiosity started to show me some funny ways of creating using that knowledge.
Computing has been present in most of my life. I have enjoyed algorithmic thinking since the moment I was introduced to a programming language in my middle school days. An exciting journey of self-directed learning about computers, programming languages and operating systems started, and I got motivated writing my own scripts for automating diverse tasks, ranging from file management to simulations web applications. During my Electrical Engineering studies I was introduced to Digital Systems, and then computing began to make sense as a whole. However, although I liked those topics a lot, I felt that something was missing. My curiosity started to show me some funny ways of creating using that knowledge.
For example, we had a course about Microcontrollers, where the main difficulty was that we also had to learn and code in the corresponding assembly language. I decided to have a humorous challenge as a final project, so I developed an “8051 Assembler: Assembler for the 8051 assembly language, written in the 8051 assembly language”. On one hand the project could be seen as completely useless because it had no social impact other than impressing people with the feat and its name, but on the other hand it helped me think about the expressive possibilities of technology beyond an utilitarian point of view.
@ -24,19 +24,19 @@ During the same college years, I started to practice and learn about an art that
A fortunate event was having a change in the director of the company: the new leader [redacted] showed us the advantages of hard work and encouraged us to find our own paths. I started to think about other ways of doing dance and I began exploring choreographic possibilities. I got braver and authentic, and as a choreographer I guided two different teams into contests where we had great national results. I founded Escenaconsejo, performing arts and interactive digital media company, and I decided to study Choreography. In those different contexts I enjoyed working with people that I admire and that find value in my ideas.
Since then, I have had an interesting evolution of my way of thinking and creating dance in relation to computing and digital technology. This process can be divided in four main stages.
Since then, I have had an interesting evolution of my way of thinking and creating dance in relation to computing and digital technology. This process can be divided in four main stages.
The first one consisted in thinking that digital technology had only a decorative role in dance. I experimented with a variety of motion tracking techniques to enable the real-time generation of multimedia content.
The first one consisted in thinking that digital technology had only a decorative role in dance. I experimented with a variety of motion tracking techniques to enable the real-time generation of multimedia content.
The second stage consisted in understanding that research and educative challenges could be tackled with the creation of specific and personalized tools that I could made and that I actually constructed. Some some examples include visualizations of the meanings of dance notation symbols, or a computer vision aid for measuring joints angles in dancers.
The second stage consisted in understanding that research and educative challenges could be tackled with the creation of specific and personalized tools that I could made and that I actually constructed. Some some examples include visualizations of the meanings of dance notation symbols, or a computer vision aid for measuring joints angles in dancers.
The third stage in this evolution process consisted in realizing that I could apply the computational, mathematical and structured vision that I developed as an engineer, as a source for composition methods that greatly differed from the commonly used ones. For example, I created a choreographic palindrome, a fractalic micro-macro cosmic choreographic structure, and finally I created Desfases (Phase shifts).
The third stage in this evolution process consisted in realizing that I could apply the computational, mathematical and structured vision that I developed as an engineer, as a source for composition methods that greatly differed from the commonly used ones. For example, I created a choreographic palindrome, a fractalic micro-macro cosmic choreographic structure, and finally I created Desfases (Phase shifts).
Desfases was the work with which I decided to get into the entrepreneurial path of Escenaconsejo along with my partner [redacted]. It is a collection of strict structural games based on shifting time, space and/or points of view. We decided to work full-time in it, and we launched a crowdfunding campaign that was a success after several months of hard work. We set an example in our dance community, as many people have tried since then to achieve a crowdfunding goal with the magnitude of ours. We work in Escenaconsejo because we are convinced about the value of our creations, and that is why we are pursuing the dream of living from them.
Desfases was the work with which I decided to get into the entrepreneurial path of Escenaconsejo along with my partner [redacted]. It is a collection of strict structural games based on shifting time, space and/or points of view. We decided to work full-time in it, and we launched a crowdfunding campaign that was a success after several months of hard work. We set an example in our dance community, as many people have tried since then to achieve a crowdfunding goal with the magnitude of ours. We work in Escenaconsejo because we are convinced about the value of our creations, and that is why we are pursuing the dream of living from them.
Finally, the fourth and current stage in this thinking evolution has consisted in getting to know about the concept of generative art. It starts to be clear how to create organic-like works using artificial means, either in choreography or in software. After more than ten years learning about programming and computers, I think that now it is the perfect time to unlearn those topics in order to cultivate a new perspective.
Finally, the fourth and current stage in this thinking evolution has consisted in getting to know about the concept of generative art. It starts to be clear how to create organic-like works using artificial means, either in choreography or in software. After more than ten years learning about programming and computers, I think that now it is the perfect time to unlearn those topics in order to cultivate a new perspective.
For example, this year I wrote a project to create a choreography based in the Little Man Computer model. The idea is to devise the architecture and machine instruction cycle that a person should execute so that she/he could become a computer. Choreographic repetition could acquire a new meaning if each iteration were part of a program. An important question that I had kept unanswered was about which programs should I write in order to run them in a live performance. Now, after reading and coding generative art, I think that this choreographic work would be complete if the strict rules of the computer architecture and its corresponding machine instruction cycle controlling the human performer were complemented by the execution of an algorithm with a chaotic outcome.
For example, this year I wrote a project to create a choreography based in the Little Man Computer model. The idea is to devise the architecture and machine instruction cycle that a person should execute so that she/he could become a computer. Choreographic repetition could acquire a new meaning if each iteration were part of a program. An important question that I had kept unanswered was about which programs should I write in order to run them in a live performance. Now, after reading and coding generative art, I think that this choreographic work would be complete if the strict rules of the computer architecture and its corresponding machine instruction cycle controlling the human performer were complemented by the execution of an algorithm with a chaotic outcome.
In some way, the description of that choreography would summarize the creative processes that I want to live and the works that I want to create: Worlds that mix the human spirit with a computational context that involves great challenges, and that reveal different ways of thinking, learning and doing. I am convinced that in this graduate program I will have the needed stimuli for being under constant difficulties. These will probably transform my way of working so that I will have a broader range of action and influence. My goal is that then I will be able to help more people find their own personal ways through creativity, curiosity, and hard work. Changes and challenges will come, and new choreography and interactive digital media will arise.
jvc

View File

@ -8,10 +8,10 @@ por ejemplo, para sumar dos números:
3 4 +
```
leyendo de izquierda a derecha:
leyendo de izquierda a derecha:
* primero se hace "push" al 3
* luego se hace "push" al 4
* primero se hace "push" al 3
* luego se hace "push" al 4
* el operador + hace "pop" dos veces, suma los valores, y hace "push" al resultado
tres números:
@ -49,7 +49,7 @@ el operador . imprime el estado de la pila
convierte (minutos, segundos) a una cantidad de segundos. en el ejemplo, son 8 minutos, 49 segundos:
```
8 49
8 49
swp 60 * + .
resultado: 529
@ -58,7 +58,7 @@ resultado: 529
convierte (minutos, segundos) correspondientes a un "paso" min/km, a una velocidad km/hr:
```
4 30
4 30
swp 60 * + 3600 swp / .
resultado en modo dec: 13.3333 (km/hr)

View File

@ -1,6 +1,6 @@
# El Computador: Coreografía estructurada como microprocesador (Propuesta)
El siguiente texto fue parte de mi aplicación a la convocatoria de jóvenes creadores (1)2015 en la disciplina de danza.
El siguiente texto fue parte de mi aplicación a la convocatoria de jóvenes creadores (1)2015 en la disciplina de danza.
Probablemente es el primer precedente escrito del proyecto de compudanzas.
@ -126,7 +126,7 @@ El objetivo de esta etapa es desarrollar materiales multimedia para describir o
# Referencias
=> http://www.alanturing.net/turing_archive/pages/Reference%20Articles/BriefHistofComp.html A Brief History of Computing.
=> http://www.alanturing.net/turing_archive/pages/Reference%20Articles/BriefHistofComp.html A Brief History of Computing.
=> http://www.yorku.ca/sychen/research/LMC/ Little Man Computer.
=> https://xkcd.com/505 Munroe, R. A bunch of rocks.

View File

@ -10,7 +10,7 @@ had a great time today talking about our microresidency in the last public event
we are glad that the phrase "joy in nerdy dances" resonated with many people!
there a couple of great questions for us.
there a couple of great questions for us.
one had to do with comparing the possibilities of these "social computers" with those of sillicon-based ones: could there be a way that the former would be better? answered that it was a great way of starting a reflection on values: probably these social computers wouldn't be better when thinking about speed, efficacy, replicability, control, etc., but they could be from the perspective of community, fun, leisure, simplicity, transparency, and so on.
@ -28,11 +28,11 @@ today we had our fourth and last (for the moment) miniworkshop! this concludes o
there were four of us, and the workshop happened in english.
we repeated the use of the "slides" from the previous session, but now we made sure we actually went and performed all the movements and sequences that are shown in there.
we repeated the use of the "slides" from the previous session, but now we made sure we actually went and performed all the movements and sequences that are shown in there.
a crucial question came up: why do operations and movements have the same name? it was interesting to discuss this before actually doing the "guide and tape" activity: this allows the operations to be danced using the same materials! (and it also allows any sequence to be read as potential set of instructions!)
it was noted how it was challenging to not follow the verbal instructions as the sequence of movements to perform, but instead as a set of operations to apply to the sequence before performing it.
it was noted how it was challenging to not follow the verbal instructions as the sequence of movements to perform, but instead as a set of operations to apply to the sequence before performing it.
in the previous workshop i realized that hurdle existed when doing the first activity of tape and guide but with voice, and today i tried to pre-emptively warn about it. however, i feel-think it's important for that "mistake" to happen, because it reveals an important aspect of the technique: part of the fun comes from having to do these translations with the materials.
@ -52,7 +52,7 @@ we had our third miniworkshop and we had a lot of fun! there were five of us, an
from the technical standpoint, everything happened smoothly from our side. this time we prepared a set of "slides" to share the outline and keep some notes on the screen. this was better than writing/drawing at the moment.
these images worked alright, but it seems to be important to actually perform everything that is shown there, especifically the examples of the operations and how they transform the sequences. otherwise the operations are not very clear until practicing them.
these images worked alright, but it seems to be important to actually perform everything that is shown there, especifically the examples of the operations and how they transform the sequences. otherwise the operations are not very clear until practicing them.
as we were more people, the conversation activity happened first with all five of us, and then divided in two groups (two and three people), dancing in parallel. it's great to have these conversations happening via movement; they don't saturate the communication channels or interfere between each other.
@ -60,7 +60,7 @@ there were some interesting reflections regarding the concepts of memory, body/m
at first people seemed to think they couldn't do the dances, but at the end they realized they had internalized to some extent the rules and therefore they could be actually dancing, not only moving mechanically to follow the instructions. i'd say that was also a source of joy and pride :)
it was also discussed how this can set many possibilities for dialog(s) and games between people.
it was also discussed how this can set many possibilities for dialog(s) and games between people.
in short, we all had a lot of fun!
@ -106,7 +106,7 @@ i think i'll work on these materials for the checkin on friday. also, i keep won
on another note, this week we are doing an #ArtistTakeover to the SloMoCo ig account:
=> https://instagram.com/slo.moco @slo.moco
not a fan of the platform, but it might allow us to reach more people. (and known people that are not in the fediverse yet :)
not a fan of the platform, but it might allow us to reach more people. (and known people that are not in the fediverse yet :)
it has been a fun experience so far!
@ -124,10 +124,10 @@ we were three spanish-speaking people, so the workshops happened in that languag
in terms of the workshop guidance, we tried:
* using movement and voice only, without visual aids / notation
* having a little bit of background music (by dominic loretti)
* having a little bit of background music (by dominic loretti)
* jumping almost right into the activity, without giving a lot of context
regarding the first point, even though we could learn and practice the technique without the notation, it was discussed that it might be a good idea to have it there.
regarding the first point, even though we could learn and practice the technique without the notation, it was discussed that it might be a good idea to have it there.
it seems a good idea at least in order to introduce the sequence transformations: some times there was some confusion about where in the sequence (head or tail) we had to apply the transformation, and having a visual/memory aid for them could probably work to reduce it.

View File

@ -16,7 +16,7 @@ there will be some guided activities to get acquainted with these rules, but the
# bounce
the idea here is to have fun and connect with movement-based joy. it gets more interesting with the computational aspects, but the moving aspect is the most important one!
the idea here is to have fun and connect with movement-based joy. it gets more interesting with the computational aspects, but the moving aspect is the most important one!
throughout all the following activites and games, i invite you to keep a continuous bounce.
@ -54,7 +54,7 @@ we will normally use square brackets to indicate a movement sequence. for exampl
[ + - - + - ]
```
# operations
# operations
the three names of the movements we just covered, IN, DEH and SHOW, are also the names of three different actions to take regarding our movement sequence.
@ -62,7 +62,7 @@ we can think of them as instructions.
## transformations
IN and DEH indicate what we will call "transformations" of the movement sequence.
IN and DEH indicate what we will call "transformations" of the movement sequence.
DEH (-) indicates that we should REMOVE the HEAD movement from our sequence.
@ -81,13 +81,13 @@ in mode 1, IN can be accompanied either by DEH or by another IN:
## helper
SHOW (.) indicates that we should perform our complete movement sequence.
SHOW (.) indicates that we should perform our complete movement sequence.
```
.
```
it is also used as a way to yield the turn to another person, or to indicate the end of the sequence.
it is also used as a way to yield the turn to another person, or to indicate the end of the sequence.
# creating and transforming a first sequence
@ -221,7 +221,7 @@ and this is the same list of instructions, but accompanied with the state of the
- . [ ]
```
this is getting interesting, isn't it?
this is getting interesting, isn't it?
even though our sequence was never longer than three movements, the sequence of sequences (or meta-sequence) started to be somewhat complex and fun to perform :)
@ -254,7 +254,7 @@ supposing that the pair of people consists of X and Y, the following illustrates
```
X: [ + ] .
Y: [ + - ] .
Y: [ + - ] .
X: [ + - - ] .
Y: [ - - ] .
X: [ - - - ] .
@ -279,7 +279,7 @@ in a first level of complexity, the guide can only perform one of the following
.
```
the tape should always finish their sequence with a SHOW that indicates that they are ready to receive a new instruction.
the tape should always finish their sequence with a SHOW that indicates that they are ready to receive a new instruction.
## a small example
@ -295,7 +295,7 @@ T: [ - - ] .
G: ++ .
T: [ - - + ] .
G: .
G: .
T: [ - - + ] .
G: - .

View File

@ -41,7 +41,7 @@ these transformations can be represented with the corresponding movements of the
* DEH: remove movement from the head
* IN x: append movement x as a new tail
these transformations are enough to perform tag systems, cyclic or not.
these transformations are enough to perform tag systems, cyclic or not.
see also {danzasistemas-tag}.

View File

@ -47,7 +47,7 @@ sirve con frutos rojos, moras, platano, mermeladas, mantequilla de cacahuate y/o
preparar "leche" de soya resulta en restos llamados "okara", que puede usarse entre otras cosas para preparar un "queso"
~60 min
~1 lt de leche y
~1 lt de leche y
un queso de ~120 gr
## ingredientes

View File

@ -4,7 +4,7 @@ a list of external resources that inspire and/or inform our work.
see also our {bookmarks} for friends' sites and capsules.
# computing within limits
# computing within limits
references related to {permacomputing}
@ -35,7 +35,7 @@ texts by solderpunk in the {gemini} protocol
## art projects
=> https://www.youtube.com/watch?v=YMKJ7S7fKOk Rare Earthenware - Unknown Fields
=> https://www.youtube.com/watch?v=YMKJ7S7fKOk Rare Earthenware - Unknown Fields
=> https://web.archive.org/web/20210415134117/http://www.unknownfieldsdivision.com/summer2014china-aworldadriftpart02.html Unknown Fields Division - Summer 2014 China Cargo ship expedition
# non-electronic computers
@ -49,13 +49,13 @@ texts by solderpunk in the {gemini} protocol
=> https://yip.pe/analog.html analogue computing
=> https://www.turingtumble.com/ turing tumble
=> https://www.youtube.com/watch?v=rA5qnZUXcqo The Stilwell Brain - Vsauce (youtube)
=> https://esoteric.codes/blog/escher-circuits-using-vision-to-perform-computation Escher Circuits: Using Vision to Perform Computation
=> https://esoteric.codes/blog/escher-circuits-using-vision-to-perform-computation Escher Circuits: Using Vision to Perform Computation
=> ./fluidics.gmi {fluidics}
# computer science
=> https://archive.org/details/computationfinit0000mins/ Computation: finite and infinite machines (1967) Minsky
=> https://archive.org/details/computationfinit0000mins/ Computation: finite and infinite machines (1967) Minsky
=> https://dspace.mit.edu/bitstream/1721.1/6107/2/AIM-052.pdf Universality of Tag Systems with P = 2 (1964) Cocke and Minsky
=> https://wpmedia.wolfram.com/uploads/sites/13/2018/02/15-1-1.pdf Cook, Matthew (2004). "Universality in Elementary Cellular Automata" (PDF). Complex Systems. 15: 140.
=> https://www.youtube.com/watch?v=xP5-iIeKXE8 A video of Conway's Game of Life, emulated in Conway's Game of Life.
@ -79,7 +79,7 @@ perspectives on living under {collapse} awareness
=> https://jembendell.com/2019/05/15/deep-adaptation-versions/ versions of the deep adaptation paper - jem bendell
=> https://www.opendemocracy.net/en/oureconomy/deep-adaptation-opens-necessary-conversation-about-breakdown-civilisation/ Deep Adaptation opens up a necessary conversation about the breakdown of civilisation
=> http://birdsbeforethestorm.net/2019/12/how-to-live-like-the-world-is-ending/ how to live like the world is ending - margaret killjoy
=> https://theanarchistlibrary.org/library/margaret-killjoy-take-what-you-need-and-compost-the-rest-an-introduction-to-post-civilized-theo take what you need and compost the rest: an introduction to post-civilized theory - margaret killjoy
=> https://theanarchistlibrary.org/library/margaret-killjoy-take-what-you-need-and-compost-the-rest-an-introduction-to-post-civilized-theo take what you need and compost the rest: an introduction to post-civilized theory - margaret killjoy
=> https://gendread.substack.com/p/it-is-time-to-step-into-the-role it is time to step into the role of the "prospective survivor" - britt wray
=> https://www.resilience.org/stories/2019-05-10/loving-a-vanishing-world/ loving a vanishing world - emily johnston
=> http://gaianism.org/living-with-collapse/ Living with Collapse By Erik Assadourian

View File

@ -30,7 +30,7 @@ cada conjunto de tres símbolos representa el estado de cada quien (centro) y su
=> ./img/dibujo_rule90.png dibujo que ilustra las transiciones de la regla 90
podemos leer la regla de esta otra forma:
podemos leer la regla de esta otra forma:
* si les dos vecines están en la misma pose, tu siguiente estado es implosivo
* si les dos vecines tienen una pose distinta, tu siguiente estado es expansivo

View File

@ -11,7 +11,7 @@ update 12021-10-19: it got accepted for the slomoco fall phase! :)
# application fields
## Project Title
## Project Title
{qiudanz technique}
@ -35,17 +35,17 @@ our plan for a micro-residency in slomoco is to develop activities for learning
> Why do you think your project is a good fit for SloMoCo? How does your project resonate with the SloMoCo mission and experimental format? How do you envision situating it as a part of SloMoCo? Expand on your "type of submission" selection. (no more than 250 words)
the qiudanz technique is a potential way to explore and (re)discover computing via movement, and/or movement via computing.
the qiudanz technique is a potential way to explore and (re)discover computing via movement, and/or movement via computing.
it is based on the belief that computer science can be engaging and has a place in human worlds even when happening beyond electronic computers. however, it also acknowledges that electronics-based communications can be a great way to disseminate the practice and to connect with an attuned audience and set of participants.
it is based on the belief that computer science can be engaging and has a place in human worlds even when happening beyond electronic computers. however, it also acknowledges that electronics-based communications can be a great way to disseminate the practice and to connect with an attuned audience and set of participants.
the qiudanz technique can be practiced in groups or alone, co-presently or telematically. it is resilient to, and possibly improved by, delays and errors in telecommunications. we love the paradox of using electronic computers to share about non-electronic computing practices.
the project identifies with the slomoco experiment and its micro-residency format in at least a couple of ways:
the project identifies with the slomoco experiment and its micro-residency format in at least a couple of ways:
on one front, the qiudanz technique is mainly a speculative practice that tries to develop and suggest alternative paths for engaging with and/or preserving computation. these are definitely impractical and could seem useless from a technocratic and techno-utopianist point of view. we perceive that slomoco doesn't necessarily share this point of view; and instead instigates a pace, level of attention and open-endedness that would be compatible with the project.
on another front, we feel-think that the micro-residency is perfect for developing the qiudanz technique: the format is accepting of works in progress, workshops, and engagement with the community. it lends itself for sharing and getting feedback, and for continuous iteration that might deviate from its originally intended form.
on another front, we feel-think that the micro-residency is perfect for developing the qiudanz technique: the format is accepting of works in progress, workshops, and engagement with the community. it lends itself for sharing and getting feedback, and for continuous iteration that might deviate from its originally intended form.
## Documentation/Archiving *
@ -53,13 +53,13 @@ on another front, we feel-think that the micro-residency is perfect for developi
i foresee using this virtual space in two ways: on one hand as a development log with text, images (and possibly videos) of the proposed activities and the decisions behind them; and on the other as a repository of the in-progress descriptions, diagrams (and possibly videos) of the activities to learn and practice the technique.
## Link to any supporting media and documentation here (preferably Google Drive)
## Link to any supporting media and documentation here (preferably Google Drive)
=> ./qiudanz_technique.gmi {qiudanz technique}
## Please indicate what stage this project is in and when you would be ready to present it. This is just to help us make programming decisions.
the qiudanz technique is a new development based on previous work of the compudanzas project.
the qiudanz technique is a new development based on previous work of the compudanzas project.
for the moment it is just a planned framework, but it can be ready soon to start prototyping and testing it.

View File

@ -6,7 +6,7 @@ en español: {apoyo}
=> ./img/foto_laconsagracion_04.jpg photo of pieces of wood in the floor, with some hands manipulating them
i have decided to transition towards giving the project my full attention and energy.
i have decided to transition towards giving the project my full attention and energy.
to achieve that, i need your financial support!

View File

@ -56,7 +56,7 @@ video recordings of the event in fb:
=> https://www.facebook.com/MediosInteractivosUSFQ/videos/447688293067070/ coloring computers workshop from the beginning
=> http://pcdquito.com/ pcd quito 2021
## 12019
## 12019
### pcd nyc

View File

@ -12,7 +12,7 @@ el taller de compudanzas materializa ciencias computacionales en cuerpxs humanxs
en este taller nos insertaremos entre el mundo abstracto de las ciencias computacionales y el mundo de su materialización industrial, para darle cuerpo humano, social, coreográfico, a algunos de sus conceptos fundamentales: máquinas de turing, compuertas lógicas, autómatas celulares, arquitectura von neumann, y más.
lo que queremos es construir y programar computadoras relativamente lentas, grandes e ineficientes, a partir de personas en movimiento siguiendo/jugando instrucciones. así, nos podremos reapropiar de las maneras computacionales de entender el mundo, para usarlas a nuestro gusto con el fin de proponer otras posibles computadoras, danzas, y/o vidas.
lo que queremos es construir y programar computadoras relativamente lentas, grandes e ineficientes, a partir de personas en movimiento siguiendo/jugando instrucciones. así, nos podremos reapropiar de las maneras computacionales de entender el mundo, para usarlas a nuestro gusto con el fin de proponer otras posibles computadoras, danzas, y/o vidas.
# justificación
@ -26,7 +26,7 @@ es por esto que el taller busca experimentar con otros acercamientos y estrategi
partimos de que todo el cuerpo de conocimientos sobre la computación fue desarrollado por personas con pasiones así como cualquier otra, por lo que las nociones de lo "frío" y "cuadrado" de lo "maquínico" y digital pueden ser entendidas desde una perspectiva que las acerca a lo orgánico, lo fluido, y a nosotras como personas vivas.
dadas las crisis climáticas, ecológicas y sociales actuales, consideramos que el taller es un importante ejercicio de imaginación donde nos preguntamos: ¿qué pasaría si las computadoras fueran bailes y no cajas de metal y semiconductor?
dadas las crisis climáticas, ecológicas y sociales actuales, consideramos que el taller es un importante ejercicio de imaginación donde nos preguntamos: ¿qué pasaría si las computadoras fueran bailes y no cajas de metal y semiconductor?
# objetivos

View File

@ -21,7 +21,7 @@ the following are some of our notes, thoughts, conversations, actions…
how bad you think the fall will be?
how long will the internet live once the humans are gone?
# u
# u
the person is given a ruleset
a table
@ -57,7 +57,7 @@ who moves and sweats
losing (but not really) breath
the iteration is complete
# w
# w
can we talk about rewilding computers?
were they wild to start with?
@ -226,7 +226,7 @@ no need to channel the earth
if simple models acquire complexity so quickly…
yes, say hi to the chaos of nature
# p
# p
has lightning been captured twice, so far?
fire, electricity, what are they?

View File

@ -38,7 +38,7 @@ como ejemplo se puede consultar el archivo fuente de la página de {running}.
=> https://codeberg.org/sejo/compudanzas/src/branch/main/src/running.gmo running.gmo
existen algunas de estas tablas en el {uxn tutorial}.
existen algunas de estas tablas en el {uxn tutorial}.
como sea, funciona suficientemente bien tener los archivos en gemtext puro, sin estos tipos de líneas extra.
@ -152,7 +152,7 @@ primero que nada, crea tu cuenta :)
con la sesión iniciada, ve al repositorio de compudanzas, y presiona el botón de "Fork" arriba a la derecha.
esto va a crear una copia del repositorio en tu cuenta:
esto va a crear una copia del repositorio en tu cuenta:
```
https://codeberg.org/TU_USERNAME/compudanzas
@ -166,7 +166,7 @@ configura las llaves SSH de tu cuenta en codeberg de acuerdo a estas instruccion
### clon local
ahora puedes clonar tu repositorio a un directorio local propio.
ahora puedes clonar tu repositorio a un directorio local propio.
este directorio ha de ser diferente del que hayas clonado del repositorio original (ese clon ya lo puedes eliminar y solo trabajar con este nuevo que es el de tu cuenta :)
@ -189,7 +189,7 @@ $ cd compudanzas/
por último, esto que sigue es necesario para que puedas obtener las actualizaciones que sucedan en el repositorio original (llamado "upstream" en estos contextos); más adelante lo comentamos pero por el momento solo hay que configurarlo:
```
$ git remote add upstream git@codeberg.org:sejo/compudanzas.git
$ git remote add upstream git@codeberg.org:sejo/compudanzas.git
```
## trabajo local
@ -255,7 +255,7 @@ recuerda no hacer "wikilinks" a páginas que no existen: usa la <[notación prov
### crea PR
en el sitio web de codeberg, entra a la dirección correspondiente a tu fork:
en el sitio web de codeberg, entra a la dirección correspondiente a tu fork:
```
https://codeberg.org/TU_USERNAME/compudanzas

View File

@ -20,7 +20,7 @@ here, we don't discuss this machine in its original abstract sense. we don't use
we don't even talk about the universal version of these machines, and their possibility of simulating any other one.
we just get together and dance according to a simple set of choreographic rules.
we just get together and dance according to a simple set of choreographic rules.
a person handles a row of symbols constructed with a series of found objects, one of them a a time; dancing to communicate what's in front of them. another person moves and signals a specific machine-body configuration. the third one tries to make sense of it all, reading movements and performing some others, guiding the group in traversing different "states".

View File

@ -75,7 +75,7 @@ int main(int argc, char *argv[]){
printf("%s\n",m.tape);
/* get symbol at head position */
m.symbol = m.tape[ m.head ];
m.symbol = m.tape[ m.head ];
/* search for corresponding rule */
irules = -1;

View File

@ -58,7 +58,7 @@ también discutimos posibles estructuras para crear bucles y programas más comp
aquí hablamos de cómo podemos integrar todo lo que hemos cubierto para crear subrutinas y programas más complejos para el ordenador varvara.
basamos nuestra discusión en una recreación del clásico juego pong.
basamos nuestra discusión en una recreación del clásico juego pong.
además de utilizar estrategias y fragmentos de código anteriores, cubrimos estrategias para dibujar y controlar sprites de varios tiles y para comprobar las colisiones.
@ -145,7 +145,7 @@ instrucciones nuevas: LTH, GTH, STZ, STR, STA, LDZ, LDR, LDA
* práctica: sprite como puntero
* práctica: herramienta de dibujo simple
instrucciones nuevas: STH, JSR
instrucciones nuevas: STH, JSR
modo nuevo: modo de retorno

View File

@ -8,7 +8,7 @@ aquí generalizaremos un procedimiento similar en una subrutina dibuja-tiles que
@dibuja-tiles ( x^ y^ ancho^ alto^ direc* -- )
```
un recordatorio de que estamos utilizando la convención de añadir un signo de intercalación (^) después del nombre de un valor para indicar que es un corto y un asterisco (*) para indicar que es un corto que funciona como un puntero (es decir, una dirección en la memoria del programa)
un recordatorio de que estamos utilizando la convención de añadir un signo de intercalación (^) después del nombre de un valor para indicar que es un corto y un asterisco (*) para indicar que es un corto que funciona como un puntero (es decir, una dirección en la memoria del programa)
vamos a detallar cómo llegar a dos versiones de esta subrutina, una que se basa en una fuerte manipulación de la pila, y otra que utiliza variables. esto con el fin de comparar ambos enfoques y darnos una visión más amplia de las posibilidades dentro de uxntal.
@ -33,7 +33,7 @@ comencemos con el siguiente programa como plantilla. incluye los datos para un s
#2ce9 .Sistema/r DEO2
#01c0 .Sistema/g DEO2
#2ce5 .Sistema/b DEO2
BRK
@tile-fondo 1122 4488 1122 4488
@ -76,7 +76,7 @@ añadiendo 8 a x, ya sabemos:
comprobar si x es menor que el límite, saltando si lo es, sería algo así:
```
.Pantalla/x DEI2
.Pantalla/x DEI2
#0108 ( el límite )
LTH2 ,&bucle JCN ( saltar si x es menor que el límite )
```
@ -216,7 +216,7 @@ siguiendo la misma estrategia, podríamos hacer:
### versión concreta
utilicemos los mismos números que antes, suponiendo que nuestra `y` inicial es 0008, nuestra altura es 0100, y por tanto, nuestro límite siendo 0108.
utilicemos los mismos números que antes, suponiendo que nuestra `y` inicial es 0008, nuestra altura es 0100, y por tanto, nuestro límite siendo 0108.
en el caso de x, comencemos en 0000 y tengamos un ancho correspondiente al ancho de la pantalla.
@ -255,7 +255,7 @@ esta debería ser la firma de nuestra subrutina:
podemos abordar este problema bien con alguna "manipulación de la pila ", o bien con "variables ".
también hay que tener en cuenta que lo haremos porque estamos tratando de llegar a una subrutina generalizada.
también hay que tener en cuenta que lo haremos porque estamos tratando de llegar a una subrutina generalizada.
si solo quisiéramos cubrir toda la pantalla con un sprite, ya tenemos todo el código necesario: solo tendríamos que adaptar el límite vertical del bucle para que se corresponda con la altura de la pantalla, ¡y ya está!
@ -438,7 +438,7 @@ podemos entonces llamarlo de la siguiente manera para obtener un cuadrado de 256
```
#0008 #0008 ( `x` y `y` )
#0100 #0100 ( ancho y alto )
;tile-fondo
;tile-fondo
;dibuja-tiles JSR2
```
@ -446,7 +446,7 @@ podemos entonces llamarlo de la siguiente manera para obtener un cuadrado de 256
### usando variables
comparemos el enfoque anterior con el uso de variables relativas.
comparemos el enfoque anterior con el uso de variables relativas.
iremos "con todo" de una manera relativamente derrochadora, sin optimizar los procedimientos que podrían beneficiarse de la manipulación de la pila.
@ -473,9 +473,9 @@ entonces, simplemente almacenamos los siguientes valores en direcciones relativa
&x STR2
```
nótese que vamos en orden inverso.
nótese que vamos en orden inverso.
después de estas operaciones las pilas están vacías.
después de estas operaciones las pilas están vacías.
entonces podemos fijar la `y` inicial y calcular el límite vertical, utilizando los valores almacenados en las variables:
@ -495,10 +495,10 @@ nuestro bucle ahora tendría el siguiente aspecto:
```
&bucle-y
( recuperar `x` y ancho )
,&x LDR2
,&x LDR2
&ancho LDR2
( dibujar fila )
;dibuja-tiles-en-fila JSR2
;dibuja-tiles-en-fila JSR2
.Pantalla/y DEI2 #0008 ADD2 DUP2 ( añade 8 a y )
.Pantalla/y DEO2 ( almacenar la nueva y )
@ -509,7 +509,7 @@ nuestro bucle ahora tendría el siguiente aspecto:
LTH2 ,&bucle-y JCN ( saltar si x es menor que el límite )
```
¡y eso es todo!
¡y eso es todo!
compara esto con la versión "concreta" que desarrollamos anteriormente, ¡es muy similar en su estructura!
@ -525,7 +525,7 @@ la subrutina completa tendría el siguiente aspecto:
,&ancho STR2
&y STR2
,&x STR2
( establecer `y` inicial )
,&y LDR2 DUP2 ( ptra: y^ y^ )
.Pantalla/y DEO2 ( ptra: y^ )
@ -534,20 +534,20 @@ la subrutina completa tendría el siguiente aspecto:
,&alto LDR2 ( ptra: y^ alto^ )
ADD2 ( ptra: limite-y^ )
,&limite-y STR2 ( ptra: )
&bucle-y
( recuperar `x` y ancho )
,&x LDR2
,&x LDR2
,&ancho LDR2
( dibujar fila )
;dibuja-tiles-en-fila JSR2
;dibuja-tiles-en-fila JSR2
.Pantalla/y DEI2 #0008 ADD2 DUP2 ( añade 8 a y )
.Pantalla/y DEO2 ( almacenar la nueva y )
( recuperar el límite vertical )
,&limite-y LDR2
LTH2 ,&bucle-y JCN ( saltar si x es menor que el límite )
RTN
@ -555,7 +555,7 @@ RTN
&alto $2 &ancho $2 &y $2 &x $2 &limite-y $2
```
como he dicho antes, podemos encontrar aquí algunas oportunidades de optimización.
como he dicho antes, podemos encontrar aquí algunas oportunidades de optimización.
tal vez el límite vertical puede ser escondido en la pila de retorno como en el bucle dibuja-tiles-en-fila, o tal vez la variable para la altura y para la `y` inicial no son necesarios.
@ -576,7 +576,7 @@ por ejemplo:
#0000 #0010 ( x e `y` iniciales )
.Pantalla/ancho DEI2
.Pantalla/alto DEI2 #0010 SUB2
;tile-fondo
;tile-fondo
;dibuja-tiles JSR2
RTN
```

View File

@ -46,7 +46,7 @@ en uxntal, indicamos que queremos poner esta bandera añadiendo el dígito '2' a
en primer lugar, recapitulemos. el siguiente código empujará el número 02 hacia abajo en la pila, luego empujará el número 30 (hexadecimal) hacia abajo en la pila y finalmente los sumará, dejando el número 32 en la pila:
```
```
#02 #30 ADD
```
@ -58,13 +58,13 @@ este sería el estado final de la pila:
en el día anterior mencionamos que la runa hexadecimal literal (#) es una abreviatura de la instrucción LIT. por lo tanto, podríamos haber escrito nuestro código de la siguiente manera:
```
```
LIT 02 LIT 30 ADD ( código ensamblado: 80 02 80 30 18 )
```
ahora, si añadimos el sufijo '2' a la instrucción LIT, podríamos escribir en su lugar:
```
```
LIT2 02 30 ADD ( código ensamblado: a0 02 30 18 )
```
@ -92,7 +92,7 @@ ahora veamos que pasa con la instrucción ADD cuando usamos el modo corto.
00 04 08 <- arriba
```
ahora, comparemos con lo que ocurre con el ADD2:
ahora, comparemos con lo que ocurre con el ADD2:
```
#0004 #0008 ADD2
@ -128,7 +128,7 @@ la instrucción DEO necesita un valor (1 byte) para salir y una dirección entra
DEO ( valor dirección -- )
```
esta instrucción tiene una contrapartida: DEI ("device in" o entrada de dispositivo).
esta instrucción tiene una contrapartida: DEI ("device in" o entrada de dispositivo).
la instrucción DEI toma una dirección de entrada/salida (1 byte) de la pila y va a empujar hacia abajo en la pila el valor (1 byte) que corresponde a la lectura de esa entrada.
@ -381,7 +381,7 @@ podemos definir una macro para que este proceso sea más fácil de escribir:
todavía no cubriremos las estructuras repetitivas, pero esta es una buena oportunidad para empezar a alinear nuestro código hacia eso.
aunque las coordenadas x e `y` del dispositivo de pantalla están pensadas como salidas, también podemos leerlas como entradas.
aunque las coordenadas x e `y` del dispositivo de pantalla están pensadas como salidas, también podemos leerlas como entradas.
por ejemplo, para leer la coordenada x, empujando su valor hacia abajo en la pila, podemos escribir:
@ -392,8 +392,8 @@ por ejemplo, para leer la coordenada x, empujando su valor hacia abajo en la pil
teniendo en cuenta esto, ¿se puede saber qué haría este código?
```
.Pantalla/x DEI2
#0001 ADD2
.Pantalla/x DEI2
#0001 ADD2
.Pantalla/x DEO2
```
@ -425,7 +425,7 @@ añadir 1 al valor de la parte superior de la pila es tan común que hay una ins
INC ( a -- a+1 )
```
INC toma el valor de la parte superior de la pila, lo incrementa por uno y lo empuja de vuelta.
INC toma el valor de la parte superior de la pila, lo incrementa por uno y lo empuja de vuelta.
en el caso del modo corto, INC2 hace lo mismo pero incrementando un corto en lugar de un byte.
@ -481,7 +481,7 @@ agradable, ¿no? ¡las operaciones ahora se ven más claras! y si quisiéramos t
¡ahora, veremos cómo aprovechar el soporte incorporado para "sprites" en el dispositivo de pantalla varvara para dibujar muchos píxeles a la vez!
el dispositivo de pantalla varvara nos permite utilizar y dibujar tiles de 8x8 píxeles, también llamados sprites.
el dispositivo de pantalla varvara nos permite utilizar y dibujar tiles de 8x8 píxeles, también llamados sprites.
hay dos modos posibles: 1bpp (1 bit por píxel) y 2bpp (2 bits por píxel).
@ -493,13 +493,13 @@ almacenaremos y accederemos a estos tiles desde la memoria principal.
## dibujando sprites de 1bpp
un tile de 1bpp consiste en un conjunto de 8 bytes que codifican el estado de sus 8x8 píxeles.
un tile de 1bpp consiste en un conjunto de 8 bytes que codifican el estado de sus 8x8 píxeles.
cada byte corresponde a una fila del tile y cada bit de una fila corresponde al estado de un píxel de izquierda a derecha: puede estar "encendido" (1) o "apagado" (0).
## codificando un sprite de 1bpp
por ejemplo, podríamos diseñar un azulejo que corresponda al contorno de un cuadrado de 8x8, activando o desactivando sus píxeles en consecuencia.
por ejemplo, podríamos diseñar un azulejo que corresponda al contorno de un cuadrado de 8x8, activando o desactivando sus píxeles en consecuencia.
``` el contorno de un cuadrado marcado con 1s y su interior marcado con 0s
11111111
@ -639,21 +639,21 @@ el nibble bajo del byte 'sprite' determinará los colores que se utilizan para d
+ <tr><td class="num">f</td><td>3</td><td>nada</td></tr>
+ </table>
& * 0: borrar tile
& * 1: "encendido" con el color 1, "apagado" con el color 0
& * 2: "encendido" con el color 2, "apagado" con el color 0
& * 3: "encendido" con el color 3, "apagado" con el color 0
& * 4: "encendido" con el color 0, "apagado" con el color 1
& * 5: "encendido" con el color 1, "apagado" sin color
& * 6: "encendido" con el color 2, "apagado" con el color 1
& * 7: "encendido" con el color 3, "apagado" con el color 1
& * 8: "encendido" con el color 0, "apagado" con el color 2
& * 9: "encendido" con el color 1, "apagado" con el color 2
& * a: "encendido" con color 2, "apagado" sin color
& * b: "encendido" con el color 3, "apagado" con el color 2
& * c: "encendido" con color 0, "apagado" con color 3
& * d: "encendido" con el color 1, "apagado" con el color 3
& * e: "encendido" con el color 2, "apagado" con el color 3
& * f: "encendido" con el color 3, "apagado" sin color
& * 1: "encendido" con el color 1, "apagado" con el color 0
& * 2: "encendido" con el color 2, "apagado" con el color 0
& * 3: "encendido" con el color 3, "apagado" con el color 0
& * 4: "encendido" con el color 0, "apagado" con el color 1
& * 5: "encendido" con el color 1, "apagado" sin color
& * 6: "encendido" con el color 2, "apagado" con el color 1
& * 7: "encendido" con el color 3, "apagado" con el color 1
& * 8: "encendido" con el color 0, "apagado" con el color 2
& * 9: "encendido" con el color 1, "apagado" con el color 2
& * a: "encendido" con color 2, "apagado" sin color
& * b: "encendido" con el color 3, "apagado" con el color 2
& * c: "encendido" con color 0, "apagado" con color 3
& * d: "encendido" con el color 1, "apagado" con el color 3
& * e: "encendido" con el color 2, "apagado" con el color 3
& * f: "encendido" con el color 3, "apagado" sin color
por ejemplo, esto significa que si establecemos el nibble bajo de 'sprite' con el valor de 6, varvara dibujará el sprite utilizando el color 2 para los pixeles "encendidos" y el color 1 para los pixeles "apagados".
@ -701,7 +701,7 @@ BRK
=> ./img/screenshot_uxn-tiles.png captura de pantalla del resultado del programa, mostrando 16 cuadrados coloreados con diferentes combinaciones de contorno y relleno.
el siguiente código dibujará nuestro sprite cuadrado con las 16 combinaciones de color:
el siguiente código dibujará nuestro sprite cuadrado con las 16 combinaciones de color:
```
( hola-sprites.tal )
@ -750,7 +750,7 @@ el siguiente código dibujará nuestro sprite cuadrado con las 16 combinaciones
#0c .Pantalla/sprite DEO 8ADD-X
#0d .Pantalla/sprite DEO 8ADD-X
#0e .Pantalla/sprite DEO 8ADD-X
#0f .Pantalla/sprite DEO
#0f .Pantalla/sprite DEO
BRK
@ -761,20 +761,20 @@ observemos que en este caso, tenemos un par de macros 8ADD-X y 8ADD-Y para incre
## experimentos de inversión
como el sprite cuadrado es simétrico, no podemos ver el efecto de invertirlo.
como el sprite cuadrado es simétrico, no podemos ver el efecto de invertirlo.
aquí están los sprites de la roca y del personaje de {darena}:
```
@piedra 3c4e 9ffd f962 3c00
@personaje 3c7e 5a7f 1b3c 5a18
@piedra 3c4e 9ffd f962 3c00
@personaje 3c7e 5a7f 1b3c 5a18
```
te invito a que intentes usar estos sprites para explorar cómo dibujarlos invertidos en diferentes direcciones.
## dibujando sprites de 2bpp
en los sprites de 2bpp cada píxel puede tener uno de los cuatro colores posibles.
en los sprites de 2bpp cada píxel puede tener uno de los cuatro colores posibles.
podemos pensar que, para asignar estos colores, codificaremos uno de los cuatro estados en cada uno de los píxeles del sprite.
@ -784,7 +784,7 @@ un solo tile de 2bpp de 8x8 píxeles necesita 16 bytes para ser codificada. esto
## codificando un sprite de 2bpp
para demostrar esta codificación, vamos a remezclar nuestro cuadrado de 8x8, asignando uno de los cuatro estados posibles (0, 1, 2, 3) a cada uno de los píxeles:
para demostrar esta codificación, vamos a remezclar nuestro cuadrado de 8x8, asignando uno de los cuatro estados posibles (0, 1, 2, 3) a cada uno de los píxeles:
``` un cuadrado de 8x8 construido con los dígitos 0 y 1 en el borde y 2 y 3 en el interior
00000001
@ -802,17 +802,17 @@ podemos pensar en cada uno de estos dígitos como un par de bits: 0 es 00, 1 es
de esta manera, podríamos pensar en nuestro sprite de la siguiente manera:
``` un cuadrado de 8x8 construido con un par de bits entre paréntesis, correspondientes a la representación binaria de cada uno de los estados
(00) (00) (00) (00) (00) (00) (00) (01)
(00) (11) (11) (11) (11) (11) (01) (01)
(00) (11) (11) (11) (11) (10) (01) (01)
(00) (11) (11) (11) (10) (10) (01) (01)
(00) (11) (11) (10) (10) (10) (01) (01)
(00) (11) (10) (10) (10) (10) (01) (01)
(00) (01) (01) (01) (01) (01) (01) (01)
(01) (01) (01) (01) (01) (01) (01) (01)
(00) (00) (00) (00) (00) (00) (00) (01)
(00) (11) (11) (11) (11) (11) (01) (01)
(00) (11) (11) (11) (11) (10) (01) (01)
(00) (11) (11) (11) (10) (10) (01) (01)
(00) (11) (11) (10) (10) (10) (01) (01)
(00) (11) (10) (10) (10) (10) (01) (01)
(00) (01) (01) (01) (01) (01) (01) (01)
(01) (01) (01) (01) (01) (01) (01) (01)
```
la codificación chr requiere una interesante manipulación de esos bits: podemos pensar que cada par de bits tiene un bit alto en la izquierda y un bit bajo en la derecha.
la codificación chr requiere una interesante manipulación de esos bits: podemos pensar que cada par de bits tiene un bit alto en la izquierda y un bit bajo en la derecha.
separamos nuestro tile en dos cuadrados diferentes, uno para los bits altos y otro para los bits bajos:
@ -984,7 +984,7 @@ el siguiente código mostrará nuestro sprite en las 16 diferentes combinaciones
#8c .Pantalla/sprite DEO cADD-X
#8d .Pantalla/sprite DEO cADD-X
#8e .Pantalla/sprite DEO cADD-X
#8f .Pantalla/sprite DEO
#8f .Pantalla/sprite DEO
BRK
@ -1023,7 +1023,7 @@ $ hexdump -C sprites.chr
# tamaño de la pantalla y capacidad de respuesta
lo último que cubriremos hoy tiene que ver con las suposiciones que hace varvara sobre el tamaño de su pantalla y algunas estrategias de código que podemos usar para lidiar con ellas.
lo último que cubriremos hoy tiene que ver con las suposiciones que hace varvara sobre el tamaño de su pantalla y algunas estrategias de código que podemos usar para lidiar con ellas.
en resumen, ¡no hay un tamaño de pantalla estándar!
@ -1059,7 +1059,7 @@ si te has descargado el repositorio con el código fuente, verás que dentro del
#define HEIGHT 40 * 8
```
esos dos números, 64 y 40 (ancho y alto), son el tamaño de pantalla por defecto en tiles, como mencionamos anteriormente.
esos dos números, 64 y 40 (ancho y alto), son el tamaño de pantalla por defecto en tiles, como mencionamos anteriormente.
puedes cambiarlos, guardar el archivo y volver a ejecutar el script build.sh para que uxnemu funcione con esta nueva resolución.
@ -1103,7 +1103,7 @@ por ejemplo, dividir 10 (en decimal) entre 2 podría expresarse de la siguiente
```
#0a #01 SFT ( resultado: 05 )
```
```
0a es 0000 1010 en binario y 05 es 0000 0101 en binario: los bits de 0a se desplazaron una posición a la derecha y se introdujo un cero como bit más a la izquierda.
@ -1176,7 +1176,7 @@ también cubrimos el modo corto, que le indica a la cpu que debe operar con pala
# día 3
¡en el {tutorial de uxn día 3} empezamos a trabajar con la interactividad usando el teclado y cubrimos en profundidad varias instrucciones uxntales!
¡en el {tutorial de uxn día 3} empezamos a trabajar con la interactividad usando el teclado y cubrimos en profundidad varias instrucciones uxntales!
sin embargo, ¡te invito a que te tomes un descanso y a que sigas explorando el dibujo en la pantalla de uxn a través del código antes de continuar!

View File

@ -97,7 +97,7 @@ este utiliza el procedimiento de dibujo de sprites que probamos el día anterior
|80 @Controlador [ &vector $2 &botón $1 &tecla $1 ]
( programa principal )
|0100
|0100
( establecer los colores del sistema )
#2ce9 .Sistema/r DEO2
#01c0 .Sistema/g DEO2
@ -108,7 +108,7 @@ este utiliza el procedimiento de dibujo de sprites que probamos el día anterior
BRK
( ejecutar este código cada vez que se pulse o suelte una tecla )
@en-controlador ( -> )
@en-controlador ( -> )
( establecer coordenadas x,y )
#0008 .Pantalla/x DEO2
#0008 .Pantalla/y DEO2
@ -127,9 +127,9 @@ BRK
bonito, ¿no?
ahora, ¿cómo podemos realizar diferentes acciones dependiendo de la tecla que se haya pulsado?
ahora, ¿cómo podemos realizar diferentes acciones dependiendo de la tecla que se haya pulsado?
en primer lugar, tenemos que hacer que nuestro programa sepa qué tecla se ha pulsado para que pueda actuar en consecuencia.
en primer lugar, tenemos que hacer que nuestro programa sepa qué tecla se ha pulsado para que pueda actuar en consecuencia.
para ello, veamos algunas instrucciones uxntal nuevas.
@ -158,7 +158,7 @@ EQU2, NEQ2, GTH2 y LTH2 funcionarán de la misma manera, pero comparando cortos
## instrucciones lógicas
uxntal tiene tres instrucciones lógicas a nivel de bit.
uxntal tiene tres instrucciones lógicas a nivel de bit.
pueden funcionar como operadores lógicos que utilizan como operandos las banderas dadas por las instrucciones de comparación que hemos comentado anteriormente:
@ -180,7 +180,7 @@ Controlador/tecla DEI ( lee la tecla y la introduce en la pila )
AND ( aplica un AND a las banderas de la pila y empuja el resultado a la pila )
```
que la instrucción sea a nivel de bit (o "bitwise") significa que aplica la operación AND a cada uno de los bits de los operandos.
que la instrucción sea a nivel de bit (o "bitwise") significa que aplica la operación AND a cada uno de los bits de los operandos.
si ambas banderas fueran "verdaderas":
@ -202,7 +202,7 @@ AND 0000 0000 ( falso )
como estos indicadores solo utilizan el bit menos significativo (el bit más a la derecha) para codificar su valor, un AND a nivel de bits es equivalente a un AND lógico convencional.
### OR
### OR
el siguiente código empujará una bandera hacia abajo en la pila si el byte tecla es '1' o 'a':
@ -265,7 +265,7 @@ observe que la máscara es la misma y el resultado es el valor opuesto de la ban
ok, ahora nuestros programas pueden identificar y almacenar en banderas si un valor (como la tecla de teclado leída) es un valor específico, o dentro de algún rango.
¿cómo podemos usar estas banderas para tener comportamientos condicionales en nuestros programas, donde se toman diferentes acciones dependiendo de los resultados?
¿cómo podemos usar estas banderas para tener comportamientos condicionales en nuestros programas, donde se toman diferentes acciones dependiendo de los resultados?
¡introduzcamos otro conjunto de nuevas instrucciones para que uxn rompa su flujo lineal!
@ -274,7 +274,7 @@ ok, ahora nuestros programas pueden identificar y almacenar en banderas si un va
* JMP: "jump" o salto incondicional a la dirección de la pila ( direc -- )
* JCN: "conditional jump" o salto condicional: toma una dirección y un valor de la pila, y si el valor no es 00, salta a la dirección; en caso contrario continúa con la siguiente instrucción ( valor direc -- )
en modo byte, las direcciones que utilizan estas instrucciones son de un byte.
en modo byte, las direcciones que utilizan estas instrucciones son de un byte.
estas direcciones de un byte son relativas y pueden considerarse positivas y negativas: indican cuántos bytes hay que saltar en la memoria principal desde la posición actual del contador de programa, ya sea hacia delante (positivo) o hacia atrás (negativo). el rango de estas direcciones relativas es de -128 a 127 inclusive.
@ -314,7 +314,7 @@ la siguiente subrutina en-controlador ilustra el uso de los saltos, dibujando nu
LIT '1 EQU ( ¿es '1'? )
( salta a dibuja-sprite si es el caso )
,&dibuja-sprite JCN
,&dibuja-sprite JCN
,&fin JMP ( si no, salta al final )
@ -334,7 +334,7 @@ la siguiente subrutina en-controlador ilustra el uso de los saltos, dibujando nu
BRK
```
nótese el uso de sub-etiquetas "dentro" (después) de en-controlador.
nótese el uso de sub-etiquetas "dentro" (después) de en-controlador.
también note como la expresión ,&subetiqueta corresponde a la dirección relativa (,) que se necesita para saltar a esa ubicación en el código nombrado con una sub-etiqueta local (&).
@ -410,7 +410,7 @@ en modo corto, POP2, DUP2, SWP2, NIP2, OVR2 y ROT2 realizan las mismas acciones
## ejemplos
vamos a utilizar estas instrucciones de muchas maneras diferentes durante los próximos días.
vamos a utilizar estas instrucciones de muchas maneras diferentes durante los próximos días.
los siguientes son algunos ejemplos basados en fragmentos de código que ya hemos discutido.
@ -452,7 +452,7 @@ después de esto, la pila se vería como:
tecla bandera1 <- arriba
```
para realizar la segunda comparación, necesitamos tener la tecla en la parte superior, no la bandera.
para realizar la segunda comparación, necesitamos tener la tecla en la parte superior, no la bandera.
¿cómo lo conseguimos? así es, utilizando un SWP:
@ -561,7 +561,7 @@ podríamos reescribirlo usando varios DUPs y POPs:
BRK
```
¿puedes decir por qué necesitamos todos esos POPs?
¿puedes decir por qué necesitamos todos esos POPs?
pista: compara el estado final de la pila con y sin las instrucciones POP.
@ -571,7 +571,7 @@ pista: compara el estado final de la pila con y sin las instrucciones POP.
la última cosa que discutiremos hoy es el uso del byte del botón del controlador en la computadora varvara.
como ya hemos mencionado, la principal diferencia aquí es que este byte mantiene el estado de 8 botones en cada uno de sus bits.
como ya hemos mencionado, la principal diferencia aquí es que este byte mantiene el estado de 8 botones en cada uno de sus bits.
dependiendo de nuestra aplicación, podríamos necesitar permitir que algunos de estos botones sean presionados al mismo tiempo.
@ -646,7 +646,7 @@ observa el uso de las máscaras AND, los saltos condicionales y algunas operacio
|80 @Controlador [ &vector $2 &botón $1 &tecla $1 ]
( programa principal )
|0100
|0100
( establecer los colores del sistema )
#2ce9 .Sistema/r DEO2
#01c0 .Sistema/g DEO2
@ -673,7 +673,7 @@ BRK
&relleno
#04 .Pantalla/sprite DEO ( dibujar relleno )
&comprobar-flechas
( usar el byte del botón de la pila )
DUP #10 AND ( aislar el bit 4, correspondiente a Arriba )
@ -686,7 +686,7 @@ BRK
&derecha JCN ( salta si no es 0 )
POP BRK
&arriba
.Pantalla/y DEI2 #0008 SUB2 .Pantalla/y DEO2 ( disminuye y )
POP
@ -729,7 +729,7 @@ recuerde que .Pantalla/x es una dirección literal en la página cero, es decir,
* dibujar un personaje que cambie su estado según la tecla que se haya pulsado. ¿tal vez utilizar múltiples tiles para dibujarlo?
* crea un simple tablero de tres-en-raya para dos jugadores: una tecla dibuja una X, otra dibuja una O y las flechas permiten elegir la casilla a dibujar.
¡ten en cuenta que para un suave movimiento interactivo puede ser mejor utilizar el vector de pantalla que se llama 60 veces por segundo!
¡ten en cuenta que para un suave movimiento interactivo puede ser mejor utilizar el vector de pantalla que se llama 60 veces por segundo!
¡lo cubriremos en profundidad en el próximo día del tutorial!

View File

@ -111,15 +111,15 @@ BRK
.Ratón/y DEI2 .Pantalla/y DEO2
( salta si se presiona algún botón )
.Ratón/estado DEI ,&presionado JCN
.Ratón/estado DEI ,&presionado JCN
( dibujar sprite usando el color 2 y 0 en el fondo )
#02 .Pantalla/sprite DEO
#02 .Pantalla/sprite DEO
BRK
&presionado
( dibujar sprite usando el color 1 y 0 en el fondo )
#01 .Pantalla/sprite DEO
#01 .Pantalla/sprite DEO
BRK
@cuadrado [ ff81 8181 8181 81ff ]
@ -184,7 +184,7 @@ BRK
.puntero/y LDZ2 .Pantalla/y DEO2
( borrar el sprite del primer plano )
#40 .Pantalla/sprite DEO
#40 .Pantalla/sprite DEO
( actualizar la posición del puntero )
.Ratón/x DEI2 .puntero/x STZ2
@ -195,7 +195,7 @@ BRK
.puntero/y LDZ2 .Pantalla/y DEO2
( dibujar sprite con color 2 en primer plano )
#4a .Pantalla/sprite DEO
#4a .Pantalla/sprite DEO
BRK
@puntero_icn [ 80c0 e0f0 f8e0 1000 ]
@ -205,7 +205,7 @@ nótese que dibuja el puntero en primer plano y que utiliza 'a' en el nibble baj
este modo de mezcla te permitiría dibujar cosas en el plano de fondo y que el puntero las cubra solo con su forma, y no con todo el cuadrado del tile.
¡te invito a que lo pruebes!
¡te invito a que lo pruebes!
¡dibuja algunas cosas en el fondo y ve cómo se ve el puntero, tal y como está ahora. luego reemplaza el byte del sprite del puntero con, por ejemplo, 42 para ver la diferencia!
@ -223,7 +223,7 @@ de hecho, eso es casi lo que haremos, pero con un elemento adicional de uxn: ¡s
# la pila de retorno
hasta ahora, "la pila" que hemos estado utilizando es lo que se suele llamar "la pila de trabajo".
hasta ahora, "la pila" que hemos estado utilizando es lo que se suele llamar "la pila de trabajo".
uxn, al igual que otros sistemas tipo forth, tiene otra pila del mismo tamaño, "la pila de retorno".
@ -244,7 +244,7 @@ en primer lugar, vamos a mover nuestra subrutina de dibujo de punteros a otra et
.puntero/y LDZ2 .Pantalla/y DEO2
( borrar el sprite del primer plano )
#40 .Pantalla/sprite DEO
#40 .Pantalla/sprite DEO
( actualizar la posición del puntero )
.Ratón/x DEI2 .puntero/x STZ2
@ -255,7 +255,7 @@ en primer lugar, vamos a mover nuestra subrutina de dibujo de punteros a otra et
.puntero/y LDZ2 .Pantalla/y DEO2
( dibujar sprite con color 2 en primer plano )
#4a .Pantalla/sprite DEO
#4a .Pantalla/sprite DEO
BRK
```
@ -293,7 +293,7 @@ o un salto absoluto:
```
@en-ratón ( -> )
;dibuja-puntero JMP2
&retorno
( algo más aquí )
BRK
@ -304,7 +304,7 @@ el detalle esta en que si queremos que ocurra algo más después de dibujar el p
al final de nuestra subrutina dibuja-puntero, necesitaríamos "saltar hacia atrás" así:
```
;en-ratón/retornar JMP2
;en-ratón/retornar JMP2
```
funcionaría, pero no es la mejor forma.
@ -387,9 +387,9 @@ JSR o JSR2 empujan hacia abajo en la pila de retorno la dirección absoluta de l
¿cómo podemos saltar incondicionalmente a esa dirección absoluta que está presente en la pila de retorno?
¡exactamente!
¡exactamente!
¡activando el modo de retorno en la instrucción JMP!
¡activando el modo de retorno en la instrucción JMP!
adicionalmente, como las direcciones empujadas por JSR son cortos, necesitamos activar el modo corto también:
@ -451,7 +451,7 @@ BRK
.puntero/y LDZ2 .Pantalla/y DEO2
( borrar el sprite del primer plano )
#40 .Pantalla/sprite DEO
#40 .Pantalla/sprite DEO
( actualizar la posición del puntero )
.Ratón/x DEI2 .puntero/x STZ2
@ -462,7 +462,7 @@ BRK
.puntero/y LDZ2 .Pantalla/y DEO2
( dibujar sprite con color 2 en primer plano )
#4a .Pantalla/sprite DEO
#4a .Pantalla/sprite DEO
RTN
@puntero_icn [ 80c0 e0f0 f8e0 1000 ]
@ -474,9 +474,9 @@ también note como esta subrutina termina con un RTN (JMP2r) que indica que el f
## notas sobre subrutinas como "funciones"
tengamos en cuenta que una posible forma de enviar "argumentos" a una subrutina sería empujarlos hacia abajo en la pila de trabajo antes de llamarla.
tengamos en cuenta que una posible forma de enviar "argumentos" a una subrutina sería empujarlos hacia abajo en la pila de trabajo antes de llamarla.
además, una posible forma de que una subrutina "devuelva" sus resultados sería que los empujara hacia abajo en la pila de trabajo.
además, una posible forma de que una subrutina "devuelva" sus resultados sería que los empujara hacia abajo en la pila de trabajo.
estos elementos pueden entonces ser consumidos desde la pila de trabajo después de regresar de la subrutina.
@ -531,14 +531,14 @@ un signo de intercalación (^) después de un nombre de valor indica que corresp
( iniciar el conteo )
#00 ( pt: longitud 00 / pr: )
&bucle
( almacenar la longitud y el conteo )
STH2 ( pt: / pr: longitud conteo )
( dibujar píxel con color 2 )
#02 .Pantalla/píxel DEO
( incrementar x )
.Pantalla/x DEI2 INC2 .Pantalla/x DEO2
@ -584,7 +584,7 @@ sin embargo, muestra cómo podemos usar estas instrucciones para tener una pila
el último elemento básico de uxntal que nos queda por cubrir es su tercer modo para las instrucciones: el modo mantener o "keep".
el modo mantener se codifica en el 8vo bit de un byte de instrucción, contando de derecha a izquierda.
el modo mantener se codifica en el 8vo bit de un byte de instrucción, contando de derecha a izquierda.
en uxntal, indicamos que queremos activar esta bandera añadiendo la letra 'k' al final de un mnemónico de instrucción.
@ -655,7 +655,7 @@ si te fijas bien, verás que el DUP2 está ahí para no perder los valores origi
pero entonces, ¿cómo podemos realizar la división sin perder sus operandos y sin usar DUP2?
¡así es!
¡así es!
DUP2 DIV es equivalente a... ¡DIVk! ¡una división que no pierde sus operandos!
@ -726,7 +726,7 @@ STHkr ( recuperar una copia de la pila de retorno )
se siguen encontrando nuevos e interesantes usos para el modo mantener :)
¡no dudes en compartirlos con nosotres!
¡no dudes en compartirlos con nosotres!
# más ejercicios
@ -773,11 +773,11 @@ puedes ir poco a poco, paso a paso, practicando tu manejo de la pila y ejercitan
en el {tutorial de uxn día 6} hablamos de cómo podemos integrar todo lo que hemos cubierto para crear subrutinas y programas aún más complejos para el ordenador varvara.
¡basamos nuestra discusión en una recreación del clásico juego pong!
¡basamos nuestra discusión en una recreación del clásico juego pong!
además de utilizar estrategias y fragmentos de código anteriores, cubrimos estrategias para dibujar y controlar los sprites de varios tiles y para comprobar las colisiones.
primero, te invito a tomar un descanso!
primero, te invito a tomar un descanso!
después, ¡sigue explorando y comparte tus descubrimientos!

View File

@ -1,8 +1,8 @@
# tutorial uxn: día 6, hacia el pong
# tutorial uxn: día 6, hacia el pong
esta es la sexta sección del {tutorial de uxn}! aquí hablamos de cómo podemos integrar todo lo que hemos cubierto para crear subrutinas y programas más complejos para el ordenador varvara.
basamos nuestra discusión en una recreación del clásico juego pong.
basamos nuestra discusión en una recreación del clásico juego pong.
además de utilizar estrategias y fragmentos de código anteriores, cubrimos estrategias para dibujar y controlar sprites de varios tiles y para comprobar las colisiones.
@ -44,7 +44,7 @@ empecemos con el siguiente programa como plantilla. incluye los datos para un sp
#2ce9 .Sistema/r DEO2
#01c0 .Sistema/g DEO2
#2ce5 .Sistema/b DEO2
BRK
@tile-fondo 1122 4488 1122 4488
@ -121,7 +121,7 @@ después de establecer la dirección del tile, podemos empujar nuestro límite (
usaremos ese valor en la parte superior de la pila como coordenada x.
dentro del bucle, podemos duplicarlo para establecerlo como la x de la pantalla, e incrementarlo.
dentro del bucle, podemos duplicarlo para establecerlo como la x de la pantalla, e incrementarlo.
entremedio, podemos enviar nuestro byte de sprite para dibujar el tile.
@ -153,7 +153,7 @@ usando esta estrategia, obtendríamos el siguiente bucle:
DUP2 .Pantalla/x DEO2 ( establecer coordenada x )
#03 .Pantalla/sprite DEO ( dibujar sprite de 1bpp con color 3 y 0 )
#0008 ADD2 ( incrementar x )
GTH2k ( ¿es ese ancho mayor que x? o también, ¿es x menor que el ancho? )
,&bucle-x JCN ( salta si x es menor que el límite )
@ -188,7 +188,7 @@ lo siguiente muestra nuestro programa en contexto, llenando completamente la pri
#2ce9 .Sistema/r DEO2
#01c0 .Sistema/g DEO2
#2ce5 .Sistema/b DEO2
( dibujar fondo )
;tile-fondo .Pantalla/direc DEO2 ( establecer la dirección del tile )
@ -262,8 +262,8 @@ MARGEN-PARED ( establecer `y` inicial )
DUP2 .Pantalla/x DEO2 ( fijar coordenada x )
( dibujar sprite de 1bpp con color 3 y 0 )
#03 .Pantalla/sprite DEO
#03 .Pantalla/sprite DEO
#0008 ADD2 ( incrementar x )
GTH2k ( ¿es ese ancho mayor que x? o también, ¿es x menor que el ancho? )
,&bucle-x JCN ( salta si x es menor que el límite )
@ -284,25 +284,25 @@ ahora podemos envolver estos bucles anidados dentro de una subrutina:
```
@dibuja-fondo ( -- )
;tile-fondo .Pantalla/direc DEO2 ( establecer la dirección del tile )
.Pantalla/alto DEI2 MARGEN-PARED SUB2 ( establecer límite )
MARGEN-PARED ( establecer `y` inicial )
&bucle-y
DUP2 .Pantalla/y DEO2 ( establecer coordenada y )
( dibujar fila )
.Pantalla/ancho DEI2 #0000 ( establecer límite y `x` inicial )
&bucle-x
DUP2 .Pantalla/x DEO2 ( establecer coordenada x )
( dibujar sprite de 1bpp con color 3 y 0 )
#03 .Pantalla/sprite DEO
#03 .Pantalla/sprite DEO
#0008 ADD2 ( incrementar x )
GTH2k ( ¿es ese ancho mayor que x? o también, ¿es x menor que el ancho? )
,&bucle-x JCN ( salta si x es menor que el límite )
POP2 POP2 ( eliminar x y el límite )
#0008 ADD2 ( incrementar y )
GTH2k ( ¿es ese límite mayor que `y`? o también, ¿es `y` menor que el límite? )
,&bucle-y JCN ( salta si `y` es menor que el límite )
@ -318,9 +318,9 @@ que podemos llamar simplemente desde nuestra subrutina de iniciación:
=> ./img/screenshot_uxn-background-full.png captura de pantalla que muestra la pantalla varvara cubierta de líneas diagonales excepto por un margen en la parte superior e inferior.
¡lindo!
¡lindo!
en el {tutorial de uxn apéndice a} puedes encontrar una discusión detallada de cómo generalizar un procedimiento como este en una subrutina dibuja-tiles que dibuje un rectángulo arbitrario rellenado con un tile dado.
en el {tutorial de uxn apéndice a} puedes encontrar una discusión detallada de cómo generalizar un procedimiento como este en una subrutina dibuja-tiles que dibuje un rectángulo arbitrario rellenado con un tile dado.
se habla de varias posibilidades para usar uxntal de esa manera abstracta: yo diría que es muy interesante, pero está definitivamente fuera del alcance para hacer el juego :)
@ -370,7 +370,7 @@ he dibujado el sprite usando el modo de mezcla 85 como indica nasu, pero lo camb
### subrutina de dibujo de la pala
construyamos una subrutina que dibuje las 6 fichas de la pala en el orden correspondiente.
construyamos una subrutina que dibuje las 6 fichas de la pala en el orden correspondiente.
podríamos escribir la subrutina recibiendo como argumentos la posición x e `y` de su esquina superior izquierda:
@ -378,13 +378,13 @@ podríamos escribir la subrutina recibiendo como argumentos la posición x e `y`
@dibuja-pala ( x^ y^ -- )
```
pero añadamos también un byte de color para el byte del sprite:
pero añadamos también un byte de color para el byte del sprite:
```
@dibuja-pala ( x^ y^ color -- )
```
recordemos que estamos utilizando la convención de añadir un signo de intercalación (^) después del nombre de un valor para indicar que es un corto y un asterisco (*) para indicar que es un corto que funciona como un puntero (es decir, una dirección en la memoria del programa)
recordemos que estamos utilizando la convención de añadir un signo de intercalación (^) después del nombre de un valor para indicar que es un corto y un asterisco (*) para indicar que es un corto que funciona como un puntero (es decir, una dirección en la memoria del programa)
por un lado esta segunda versión nos permitiría cambiar de color cuando, por ejemplo, le demos a la pelota, pero lo más importante es que esto nos permitirá borrar la pala antes de moverla, como hemos hecho en días anteriores.
@ -414,7 +414,7 @@ en lugar de restar podríamos recuperar x de la pila de retorno, o de una variab
una posible ventaja de ir en orden es que podemos incrementar la dirección del sprite por 10 (16 en decimal) para llegar a la dirección del siguiente tile. para esto, o para los cambios de coordenadas, podemos aprovechar el byte auto de la pantalla.
sin embargo, en este caso voy a ir por la primera opción y voy a establecer manualmente la dirección para cada tile.
sin embargo, en este caso voy a ir por la primera opción y voy a establecer manualmente la dirección para cada tile.
adicionalmente, guardaré el color en la pila de retorno:
@ -424,8 +424,8 @@ adicionalmente, guardaré el color en la pila de retorno:
STH
( establecer `y` y x iniciales )
.Pantalla/y DEO2
.Pantalla/x DEO2
.Pantalla/y DEO2
.Pantalla/x DEO2
( dibujar tile 0 )
;pala/tile0 .Pantalla/direc DEO2
@ -470,7 +470,7 @@ adicionalmente, guardaré el color en la pila de retorno:
RTN
```
¡eso es todo!
¡eso es todo!
ahora podemos llamarlo, por ejemplo, de la siguiente manera y obtener nuestra pala dibujada:
@ -508,7 +508,7 @@ podemos tener un par de macros para mantener las dimensiones y el color de las p
```
%ANCHO-PALA { #0010 } ( 2 tiles )
%ALTO-PALA { #0018 } ( 3 tiles )
%COLOR-PALA { #c5 }
%COLOR-PALA { #c5 }
```
un margen para separar las palas de los bordes podría ser agradable también:
@ -576,12 +576,12 @@ omitiendo la definición de las subrutinas dibuja-fondo y dibuja-pala y como for
( macros )
%RTN { JMP2r }
%MITAD2 { #01 SFT2 } ( corto -- corto/2 )
%MITAD2 { #01 SFT2 } ( corto -- corto/2 )
( constantes )
%ANCHO-PALA { #0010 } ( 2 tiles )
%ALTO-PALA { #0018 } ( 3 tiles )
%COLOR-PALA { #c5 }
%COLOR-PALA { #c5 }
%MARGEN { #0010 }
%MARGEN-PARED { #0010 } ( margen en la parte superior e inferior )
@ -602,7 +602,7 @@ omitiendo la definición de las subrutinas dibuja-fondo y dibuja-pala y como for
;en-cuadro .Pantalla/vector DEO2
( dibujar fondo )
;dibuja-fondo JSR2
;dibuja-fondo JSR2
( iniciar palas )
MARGEN .izquierda/x STZ2
@ -679,32 +679,32 @@ todo esto puede ir dentro de su propia subrutina para facilitar la lectura:
.Controlador/botón DEI
DUP #10 AND ( comprobar bit para arriba )
,&izquierda-arriba JCN
DUP #20 AND ( comprobar bit para abajo )
DUP #20 AND ( comprobar bit para abajo )
&izquierda-abajo JCN
&derecha JMP ( salta si no se ha presionado ninguno de los dos )
&izquierda-arriba
.izquierda/y LDZ2 VEL-PALA SUB2 .izquierda/y STZ2
,&derecha JMP
.izquierda/y LDZ2 VEL-PALA SUB2 .izquierda/y STZ2
,&derecha JMP
&izquierda-abajo
.izquierda/y LDZ2 VEL-PALA ADD2 .izquierda/y STZ2
,&derecha JMP
.izquierda/y LDZ2 VEL-PALA ADD2 .izquierda/y STZ2
,&derecha JMP
&derecha
( pala derecha: botones ctrl/A y alt/B )
DUP #01 AND ( comprobar bit para A )
,&derecha-arriba JCN
DUP #02 AND ( comprobar bit para B )
DUP #02 AND ( comprobar bit para B )
&derecha-abajo JCN
&fin JMP ( salta si no se ha presionado ninguno de los dos )
&derecha-arriba
.derecha/y LDZ2 VEL-PALA SUB2 .derecha/y STZ2
,&fin JMP
.derecha/y LDZ2 VEL-PALA SUB2 .derecha/y STZ2
,&fin JMP
&derecha-abajo
.derecha/y LDZ2 VEL-PALA ADD2 .derecha/y STZ2
.derecha/y LDZ2 VEL-PALA ADD2 .derecha/y STZ2
&fin
POP ( hacer POP al valor duplicado del botón )
@ -713,7 +713,7 @@ RTN
### procedimiento completo
integrando todo, nuestra subrutina en-cuadro se vería como lo siguiente.
integrando todo, nuestra subrutina en-cuadro se vería como lo siguiente.
¡ahora somos capaces de mover nuestras palas!
@ -724,7 +724,7 @@ integrando todo, nuestra subrutina en-cuadro se vería como lo siguiente.
.derecha/x LDZ2 .derecha/y LDZ2 COLOR-BORRAR ;dibuja-pala JSR2
( actualizar palas )
;actualiza-palas JSR2
;actualiza-palas JSR2
( dibujar palas )
.izquierda/x LDZ2 .izquierda/y LDZ2 COLOR-PALA ;dibuja-pala JSR2
@ -732,7 +732,7 @@ integrando todo, nuestra subrutina en-cuadro se vería como lo siguiente.
BRK
```
nota que somos capaces de mover las palas más allá de los límites de la pantalla.
nota que somos capaces de mover las palas más allá de los límites de la pantalla.
te invito a que modifiques la subrutina actualiza-palas para que haya un límite en el movimiento de las palas. en el {tutorial de uxn día 4} discutimos algunas posibles estrategias para lograrlo :)
@ -767,7 +767,7 @@ podemos definir un par de macros para referirse a sus parámetros:
```
%TAM-PELOTA { #0010 } ( tamaño: 2 tiles por lado )
%COLOR-PELOTA { #c5 }
%COLOR-PELOTA { #c5 }
```
### subrutina para dibujar la pelota
@ -790,7 +790,7 @@ MITAD2
.pelota/x STZ2
.Pantalla/alto DEI2 TAM-PELOTA SUB2
MITAD2
MITAD2
.pelota/y STZ2
```
@ -807,28 +807,28 @@ hagamos que la subrutina reciba el color como argumento, para poder borrar la pe
( dibujar tile 0 )
;pelota-sprite/tile0 .Pantalla/direc DEO2
( el byte de color ya estaba en la pila )
DUP .Pantalla/sprite DEO
DUP .Pantalla/sprite DEO
( mover a la derecha )
.Pantalla/x DEI2 #0008 ADD2 .Pantalla/x DEO2
( dibujar tile 1 )
;pelota-sprite/tile1 .Pantalla/direc DEO2
DUP .Pantalla/sprite DEO
DUP .Pantalla/sprite DEO
( mover hacia abajo )
.Pantalla/y DEI2 #0008 ADD2 .Pantalla/y DEO2
( dibujar tile 3 )
;pelota-sprite/tile3 .Pantalla/direc DEO2
DUP .Pantalla/sprite DEO
DUP .Pantalla/sprite DEO
( mover a la izquierda )
.Pantalla/x DEI2 #0008 SUB2 .Pantalla/x DEO2
( dibujar tile 2 )
;pelota-sprite/tile2 .Pantalla/direc DEO2
.Pantalla/sprite DEO
.Pantalla/sprite DEO
RTN
```
@ -841,7 +841,7 @@ COLOR-PELOTA ;dibuja-pelota JSR2
=> ./img/screenshot_uxn-pong-paddles-and-ball.png captura de la pantalla mostrando las palas en su posición horizontal pero a diferentes alturas y la pelota completamente centrada en la pantalla.
## movimiento de la pelota
## movimiento de la pelota
para el movimiento de la pelota, seguiremos la misma estructura que antes:
@ -849,7 +849,7 @@ para el movimiento de la pelota, seguiremos la misma estructura que antes:
* actualizar su posición
* dibujar la pelota en la nueva posición
se vería algo como lo siguiente y podría situarse a lo largo de los procedimientos equivalentes para las palas dentro de la subrutina en-cuadro:`
se vería algo como lo siguiente y podría situarse a lo largo de los procedimientos equivalentes para las palas dentro de la subrutina en-cuadro:`
```
( dentro de en-cuadro )
@ -857,7 +857,7 @@ se vería algo como lo siguiente y podría situarse a lo largo de los procedimie
COLOR-BORRAR ;dibuja-pelota JSR2
( actualizar pelota )
;actualiza-pelota JSR2
;actualiza-pelota JSR2
( dibujar pelota )
COLOR-PELOTA ;dibuja-pelota JSR2
@ -903,7 +903,7 @@ para moverse hacia la izquierda, podríamos pensar que deberíamos sustituir ADD
pero, dejando nuestro código como está ahora: ¿hay algún valor de velocidad-x que haga que x se haga más pequeño al sumarlos?
en otros contextos, uno podría decir, ¡"-1"!
en otros contextos, uno podría decir, ¡"-1"!
pero no hemos utilizado signos negativos en uxn; ¡no podemos!
@ -952,7 +952,7 @@ para obtener otros "números negativos", observemos lo siguiente: si restamos 1
1 0000 0000 0000 0000: 0000
```
¡obtenemos 0! ¡fffe funciona efectivamente como "-2"!
¡obtenemos 0! ¡fffe funciona efectivamente como "-2"!
podríamos continuar así obteniendo más y más números "negativos" que funcionan gracias al tamaño restringido de la memoria del ordenador.
@ -1067,7 +1067,7 @@ considerando que hay un margen en la parte superior, podemos hacer esta comproba
### pared inferior
aquí el procedimiento sería similar, pero considerando el tamaño de la pelota.
aquí el procedimiento sería similar, pero considerando el tamaño de la pelota.
queremos saber si la coordenada `y`, más el tamaño de la pelota, es mayor que la coordenada `y` de la pared inferior.
@ -1077,13 +1077,13 @@ la coordenada `y` de la pared inferior sería la altura de la pantalla, menos el
(dentro de actualiza-pelota )
&verif-pared-inf
.pelota/y LDZ2 TAM-PELOTA ADD2 ( y + tamaño de la pelota )
.Pantalla/alto DEI2
.Pantalla/alto DEI2
MARGEN-PARED SUB2 ( altura - margen )
GTH2 ( ¿es la pelota-y mayor que la pared-y? )
,&establecer-vel-neg JCN
&continuar JMP
&establecer-vel-neg
&establecer-vel-neg
PELOTA-VEL-NEG .pelota/vel-y STZ2
&continuar
```
@ -1113,19 +1113,19 @@ nuestra subrutina actualiza-pelota tiene el siguiente aspecto hasta el momento:
LTH2 ( ¿es la pelota-y menor que el margen? )
,&establecer-vel-pos JCN
,&verif-pared-inf JMP
&establecer-vel-pos
PELOTA-VEL-POS .pelota/vel-y STZ2
&continuar JMP
&verif-pared-inf
.pelota/y LDZ2 TAM-PELOTA ADD2 ( y + tamaño de la pelota )
.Pantalla/alto DEI2
.Pantalla/alto DEI2
MARGEN-PARED SUB2 ( altura - margen )
GTH2 ( ¿es la pelota-y mayor que la pared-y? )
,&establecer-vel-neg JCN
&continuar JMP
&establecer-vel-neg
PELOTA-VEL-NEG .pelota/vel-y STZ2
&continuar
@ -1163,7 +1163,7 @@ una vez que sabemos que eso es cierto, podemos ver si la pelota está dentro del
en especifico, si queremos que la pelota pueda rebotar cuando cualquier parte de la pelota golpee cualquier parte de la pala, la coordenada `y` de la pelota tiene que ser:
* mayor que la coordenada `y` de la pala menos la altura AND de la pelota
* mayor que la coordenada `y` de la pala menos la altura AND de la pelota
* menor que la coordenada `y` de la pala más la altura de la pala
si esas dos condiciones se cumplen, entonces podemos establecer una velocidad positiva para x:
@ -1171,10 +1171,10 @@ si esas dos condiciones se cumplen, entonces podemos establecer una velocidad po
```
( dentro de actualiza-pelota )
&x-en-izquierda
.pelota/y LDZ2 DUP2
.pelota/y LDZ2 DUP2
.izquierda/y LDZ2 TAM-PELOTA SUB2 GTH2 ( primera bandera ) STH
.izquierda/y LDZ2 ALTO-PALA ADD2 LTH2 ( segunda bandera )
STHr ( recupera la primera bandera )
.izquierda/y LDZ2 ALTO-PALA ADD2 LTH2 ( segunda bandera )
STHr ( recupera la primera bandera )
AND ( hacer AND en ambas banderas )
&rebote-izquierda JCN
```
@ -1196,10 +1196,10 @@ todo el código x-en-izquierda terminaría pareciendo:
```
( dentro de actualiza-pelota )
&x-en-izquierda
.pelota/y LDZ2 DUP2
.pelota/y LDZ2 DUP2
.izquierda/y LDZ2 TAM-PELOTA SUB2 GTH2 ( primera bandera ) STH
.izquierda/y LDZ2 ALTO-PALA ADD2 LTH2 ( segunda bandera )
STHr ( recupera la primera bandera )
.izquierda/y LDZ2 ALTO-PALA ADD2 LTH2 ( segunda bandera )
STHr ( recupera la primera bandera )
AND ( hacer AND en ambas banderas )
,&rebote-izquierda JCN
@ -1223,7 +1223,7 @@ todo el código x-en-izquierda terminaría pareciendo:
esta aproximación de comparar con 0000 es la más fácil, pero ten en cuenta que podría no funcionar si cambias la velocidad de la pelota: podría ocurrir que cruzara la pared pero con una coordenada x que nunca fuera igual a 0.
realmente no podemos comprobar si la coordenada x es menor que 0, porque como hemos comentado anteriormente, eso sería en realidad un número cercano a ffff.
realmente no podemos comprobar si la coordenada x es menor que 0, porque como hemos comentado anteriormente, eso sería en realidad un número cercano a ffff.
si comprobáramos que la coordenada x es menor que ffff, ¡entonces cada valor posible activaría la bandera de comparación!
@ -1243,19 +1243,19 @@ para la pala derecha haremos lo mismo que arriba, pero cambiando las comparacion
&fin JMP
&x-en-derecha
.pelota/y LDZ2 DUP2
.pelota/y LDZ2 DUP2
.derecha/y LDZ2 TAM-PELOTA SUB2 GTH2 ( primera bandera ) STH
.derecha/y LDZ2 ALTO-PALA ADD2 LTH2 ( segunda bandera )
STHr ( recupera la primera bandera )
.derecha/y LDZ2 ALTO-PALA ADD2 LTH2 ( segunda bandera )
STHr ( recupera la primera bandera )
AND ( hacer AND en ambas banderas )
,&rebote-derecha JCN
.pelota/x LDZ2
.pelota/x LDZ2
.Pantalla/ancho DEI2 NEQ2 ( ¿ha llegado a la pared? )
,&fin JCN
,&fin JCN
&reset-derecha
( aquí puedes aumentar la puntuación
( aquí puedes aumentar la puntuación
de la pala izquierda )
;reset JSR2
,&fin JMP
@ -1301,7 +1301,7 @@ aquí está todo el código que hemos escrito hoy:
( dispositivos )
|00 @Sistema [ &vector $2 &pad $6 &r $2 &g $2 &b $2 ]
|20 @Pantalla [ &vector $2 &ancho $2 &alto $2 &auto $1 &pad $1
|20 @Pantalla [ &vector $2 &ancho $2 &alto $2 &auto $1 &pad $1
&x $2 &y $2 &direc $2 &píxel $1 &sprite $1 ]
|80 @Controlador [ &vector $2 &botón $1 &tecla $1 ]
@ -1313,10 +1313,10 @@ aquí está todo el código que hemos escrito hoy:
( constantes )
%ANCHO-PALA { #0010 } ( 2 tiles )
%ALTO-PALA { #0018 } ( 3 tiles )
%COLOR-PALA { #c5 }
%COLOR-PALA { #c5 }
%VEL-PALA { #0001 }
%TAM-PELOTA { #0010 } ( 2 tiles )
%COLOR-PALA { #c5 }
%COLOR-PALA { #c5 }
%PELOTA-VEL-POS { #0001 }
%PELOTA-VEL-NEG { #ffff }
%COLOR-BORRAR { #40 }
@ -1341,7 +1341,7 @@ aquí está todo el código que hemos escrito hoy:
;en-cuadro .Pantalla/vector DEO2
( dibujar fondo )
;dibuja-fondo JSR2
;dibuja-fondo JSR2
( iniciar palas )
MARGEN .izquierda/x STZ2
@ -1376,10 +1376,10 @@ BRK
COLOR-BORRAR ;dibuja-pelota JSR2
( actualizar palas )
;actualiza-palas JSR2
;actualiza-palas JSR2
( actualizar pelota )
;actualiza-pelota JSR2
;actualiza-pelota JSR2
( dibujar palas )
.izquierda/x LDZ2 .izquierda/y LDZ2 COLOR-PALA ;dibuja-pala JSR2
@ -1425,19 +1425,19 @@ RTN
LTH2 ( ¿es la pelota-y menor que el margen? )
,&establecer-vel-pos JCN
,&verif-pared-inf JMP
&establecer-vel-pos
PELOTA-VEL-POS .pelota/vel-y STZ2
,&continuar JMP
&verif-pared-inf
.pelota/y LDZ2 TAM-PELOTA ADD2 ( y + tamaño-pelota )
.Pantalla/alto DEI2 MARGEN-PARED SUB2 ( altura - margen )
GTH2
,&establecer-vel-neg JCN
,&continuar JMP
&establecer-vel-neg
&establecer-vel-neg
PELOTA-VEL-NEG .pelota/vel-y STZ2
&continuar
@ -1448,17 +1448,17 @@ RTN
LTH2 ( ¿es la pelota-x menor que el margen + ancho-pala? )
,&x-en-izquierda JCN
,&verif-pala-der JMP
&x-en-izquierda
.pelota/y LDZ2 DUP2
.pelota/y LDZ2 DUP2
.izquierda/y LDZ2 TAM-PELOTA SUB2 GTH2 ( primera bandera ) STH
.izquierda/y LDZ2 ALTO-PALA ADD2 LTH2 ( segunda bandera )
STHr ( recuperar la primera bandera )
.izquierda/y LDZ2 ALTO-PALA ADD2 LTH2 ( segunda bandera )
STHr ( recuperar la primera bandera )
AND ( hacer AND en ambas banderas )
,&rebote-izquierda JCN
.pelota/x LDZ2 #0000 NEQ2 ( ¿ha llegado a la pared? )
,&fin JCN
,&fin JCN
&reset-izquierda
( aquí puedes añadir un punto a la pala derecha )
@ -1476,18 +1476,18 @@ RTN
GTH2
,&x-en-derecha JCN
,&fin JMP
&x-en-derecha
.pelota/y LDZ2 DUP2
.pelota/y LDZ2 DUP2
.derecha/y LDZ2 TAM-PELOTA SUB2 GTH2 ( primera bandera ) STH
.derecha/y LDZ2 ALTO-PALA ADD2 LTH2 ( segunda bandera )
STHr ( recuperar la primera bandera )
.derecha/y LDZ2 ALTO-PALA ADD2 LTH2 ( segunda bandera )
STHr ( recuperar la primera bandera )
AND ( hacer AND en ambas banderas )
,&rebote-derecha JCN
.pelota/x LDZ2
.pelota/x LDZ2
.Pantalla/ancho DEI2 NEQ2 ( ¿ha llegado a la pared? )
,&fin JCN
,&fin JCN
&reset-derecha
( aquí puedes añadir un punto a la pala izquierda )
@ -1513,28 +1513,28 @@ RTN
( dibujar tile 0 )
;pelota/sprite0 .Pantalla/direc DEO2
( el byte de color ya estaba en la pila )
DUP .Pantalla/sprite DEO
DUP .Pantalla/sprite DEO
( mover a la derecha )
.Pantalla/x DEI2 #0008 ADD2 .Pantalla/x DEO2
( dibujar tile 1 )
;pelota-sprite/sprite1 .Pantalla/direc DEO2
DUP .Pantalla/sprite DEO
DUP .Pantalla/sprite DEO
( mover hacia abajo )
.Pantalla/y DEI2 #0008 ADD2 .Pantalla/y DEO2
( dibujar tile 3 )
;pelota-sprite/tile3 .Pantalla/direc DEO2
DUP .Pantalla/sprite DEO
DUP .Pantalla/sprite DEO
( mover a la izquierda )
.Pantalla/x DEI2 #0008 SUB2 .Pantalla/x DEO2
( dibujar tile 2 )
;pelota-sprite/tile2 .Pantalla/direc DEO2
.Pantalla/sprite DEO
.Pantalla/sprite DEO
RTN
```
@ -1549,32 +1549,32 @@ RTN
.Controlador/botón DEI
DUP #10 AND ( comprobar bit para arriba )
,&izquierda-arriba JCN
DUP #20 AND ( comprobar bit para abajo )
DUP #20 AND ( comprobar bit para abajo )
,&izquierda-abajo JCN
,&derecha JMP ( salta si no se ha presionado ninguno de los dos )
&izquierda-arriba
.izquierda/y LDZ2 VEL-PALA SUB2 .izquierda/y STZ2
,&derecha JMP
.izquierda/y LDZ2 VEL-PALA SUB2 .izquierda/y STZ2
,&derecha JMP
&izquierda-abajo
.izquierda/y LDZ2 VEL-PALA ADD2 .izquierda/y STZ2
,&derecha JMP
.izquierda/y LDZ2 VEL-PALA ADD2 .izquierda/y STZ2
,&derecha JMP
&derecha
( pala derecha: botones ctrl/A 01 y alt/B 02 )
DUP #01 AND ( comprobar bit para A )
,&derecha-arriba JCN
DUP #02 AND ( comprobar bit para B )
DUP #02 AND ( comprobar bit para B )
,&derecha-abajo JCN
,&fin JMP ( salta si no se ha presionado ninguno de los dos )
&derecha-arriba
.derecha/y LDZ2 VEL-PALA SUB2 .derecha/y STZ2
,&fin JMP
.derecha/y LDZ2 VEL-PALA SUB2 .derecha/y STZ2
,&fin JMP
&derecha-abajo
.derecha/y LDZ2 VEL-PALA ADD2 .derecha/y STZ2
.derecha/y LDZ2 VEL-PALA ADD2 .derecha/y STZ2
&fin
POP ( hacer POP al valor duplicado del botón )
@ -1589,8 +1589,8 @@ RTN
STH
( establecer `y` y x iniciales )
.Pantalla/y DEO2
.Pantalla/x DEO2
.Pantalla/y DEO2
.Pantalla/x DEO2
( dibujar tile 0 )
;pala-sprite/tile0 .Pantalla/direc DEO2
@ -1610,7 +1610,7 @@ RTN
( dibujar tile 3 )
;pala-sprite/tile3 .Pantalla/direc DEO2
STHkr .Pantalla/sprite DEO
( restar 8 a x: )
.Pantalla/x DEI2 #0008 SUB2 .Pantalla/x DEO2
@ -1635,17 +1635,17 @@ RTN
RTN
```
## dibuja-fondo
## dibuja-fondo
```
@dibuja-fondo ( -- )
;tile-fondo .Pantalla/direc DEO2 ( establecer la dirección del tile )
.Pantalla/alto DEI2 MARGEN-PARED SUB2 ( establecer límite )
MARGEN-PARED ( establecer `y` inicial )
&bucle-y
DUP2 .Pantalla/y DEO2 ( establecer coordenada `y` )
( dibujar fila )
.Pantalla/ancho DEI2 #0000 ( establecer límite y `x` inicial )
&bucle-x
@ -1655,7 +1655,7 @@ RTN
GTH2k ( ¿es la anchura mayor que x? o también, ¿es x menor que la anchura? )
,&bucle-x JCN ( salta si x es menor que el límite )
POP2 POP2 ( eliminar `x` y el límite )
#0008 ADD2 ( incrementar y )
GTH2k ( ¿es el límite mayor que `y`? o también, ¿es `y` menor que el límite? )
,&bucle-y JCN ( salta si `y` es menor que el límite )
@ -1705,7 +1705,7 @@ en el {tutorial de uxn día 7} hablamos de los dispositivos del ordenador varvar
este debería ser un final ligero y tranquilo de nuestro recorrido, ya que tiene que ver menos con la lógica de programación y más con las convenciones de entrada y salida en estos dispositivos.
¡primero, te invito a tomar un descanso!
¡primero, te invito a tomar un descanso!
después, ¡sigue explorando y comparte tus descubrimientos!

View File

@ -48,10 +48,10 @@ podemos usar una estructura como la siguiente, donde el nombre del archivo y la
#00ff .Archivo/largo DEO2 ( intentará leer 255 bytes )
( establecer la dirección de los datos a leer y hacer lectura )
;archivo/datos .Archivo/lectura DEO2
;archivo/datos .Archivo/lectura DEO2
( comprobar el byte éxito y saltar según corresponda )
Archivo/éxito DEI2 #0000 EQU2 ,&fallo JCN
Archivo/éxito DEI2 #0000 EQU2 ,&fallo JCN
&éxito
LIT 'Y .Consola/escribir DEO
@ -61,7 +61,7 @@ podemos usar una estructura como la siguiente, donde el nombre del archivo y la
LIT 'N .Consola/escritura DEO
RTN
@archivo
@archivo
&nombre "prueba.txt 00
&datos $ff ( reservando 255 bytes para los datos )
```
@ -72,7 +72,7 @@ en este ejemplo estamos escribiendo un carácter en la consola en función de qu
además, en este ejemplo no nos preocupa realmente cuántos bytes se han leído realmente: ¡tenga en cuenta que esta información se almacena en Archivo/éxito hasta que se produzca otra lectura o escritura!
es importante recordar que, como siempre en este contexto, estamos tratando con bytes crudos.
es importante recordar que, como siempre en este contexto, estamos tratando con bytes crudos.
¡no solo podemos elegir tratar estos bytes como caracteres de texto, sino que también podemos elegir usarlos como sprites, coordenadas, dimensiones, colores, etc!
@ -94,7 +94,7 @@ el siguiente programa escribirá "hola" y una nueva línea (0a) en un archivo ll
#0006 .Archivo/largo DEO2 ( intentará escribir 6 bytes )
( establecer la dirección de inicio de los datos y hacer la escritura )
;archivo/datos .Archivo/escribir DEO2
;archivo/datos .Archivo/escribir DEO2
( leer y evaluar el byte éxito )
.Archivo/éxito DEI2 #0006 NEQ2 ,&fallo JCN
@ -107,7 +107,7 @@ el siguiente programa escribirá "hola" y una nueva línea (0a) en un archivo ll
LIT 'N .Consola/escribir DEO
RTN
@archivo
@archivo
&nombre "prueba.txt 00
&datos "hola 0a
```
@ -136,10 +136,10 @@ podríamos adaptar nuestra subrutina anterior para cargar el archivo de temas y
#0006 .Archivo/largo DEO2 ( intentará leer 6 bytes )
( establecer la dirección de los datos a leer y hacer lectura )
;tema/datos .Archivo/cargar DEO2
;tema/datos .Archivo/cargar DEO2
( comprobar el byte éxito y saltar según corresponda )
.Archivo/éxito DEI2 #0006 NEQ2 ,&fallo JCN
.Archivo/éxito DEI2 #0006 NEQ2 ,&fallo JCN
&éxito
( establecer los colores del sistema a partir de los datos leídos )
@ -172,12 +172,12 @@ y para hacer la operación contraria, podemos leer los colores del sistema en nu
;tema/nombre .Archivo/nombre DEO2 ( establecer la dirección de la ruta del archivo )
#0006 .Archivo/leer DEO2 ( intentará escribir 6 bytes )
( establecer la dirección de los datos y hacer la escritura )
;tema/datos .Archivo/guardar DEO2
;tema/datos .Archivo/guardar DEO2
( comprobar el byte de éxito y saltar según corresponda )
.Archivo/éxito DEI2 #0006 NEQ2 ,&fallo JCN
.Archivo/éxito DEI2 #0006 NEQ2 ,&fallo JCN
&éxito
( ¿informar el éxito? )
@ -223,7 +223,7 @@ tal vez puedas usar estos valores como coordenadas para algunos sprites, o tal v
o ¿qué tal dibujar sprites condicionalmente o cambiar los colores del sistema dependiendo de la hora? :)
¡también puedes utilizar los valores de la fecha y la hora como semillas para generar algo de pseudo-aleatoriedad!
¡también puedes utilizar los valores de la fecha y la hora como semillas para generar algo de pseudo-aleatoriedad!
por último, recuerda que para cronometrar eventos con más precisión que segundos puedes contar las veces que se ha disparado el vector pantalla.
@ -350,11 +350,11 @@ el ejemplo piano.tal en el repositorio uxn, tiene varios de ellos, todos de 256
¿y qué significan estos números?
en el contexto de varvara, podemos entenderlos como múltiples bytes sin signo (u8) que corresponden a las amplitudes de la onda sonora que componen la muestra.
en el contexto de varvara, podemos entenderlos como múltiples bytes sin signo (u8) que corresponden a las amplitudes de la onda sonora que componen la muestra.
un "cabezal de reproducción" visita cada uno de estos números durante un tiempo determinado y los utiliza para establecer la amplitud de la onda sonora.
las siguientes imágenes muestran la forma de la onda (o "waveform") de cada una de estas muestras.
las siguientes imágenes muestran la forma de la onda (o "waveform") de cada una de estas muestras.
cuando hacemos un bucle con estas formas de onda, ¡obtenemos un tono basado en su forma!
@ -386,7 +386,7 @@ la frecuencia a la que se reproduce esta muestra (es decir, a la que la amplitud
el byte tono hace que la muestra comience a reproducirse cada vez que le escribimos, de forma similar a como el byte de sprite realiza el dibujo del sprite cuando le escribimos.
los primeros 7 bits (de derecha a izquierda) del byte corresponden a una nota midi, y por tanto, a la frecuencia a la que se reproducirá la muestra.
los primeros 7 bits (de derecha a izquierda) del byte corresponden a una nota midi, y por tanto, a la frecuencia a la que se reproducirá la muestra.
el octavo bit es una bandera: cuando es 0 la muestra se reproducirá en bucle y cuando es 1 la muestra se reproducirá solo una vez.
@ -452,7 +452,7 @@ cada una de estas transiciones se realiza de forma lineal.
en el corto ADSR del dispositivo de audio, hay un nibble para cada uno de los componentes: por lo tanto, cada uno puede tener una duración de 0 a f.
las unidades para estas duraciones son 15vos de segundo.
las unidades para estas duraciones son 15vos de segundo.
como ejemplo, si la duración del componente de ataque es 'f', entonces durará un segundo (15/15 de segundo, en decimal).
@ -488,7 +488,7 @@ BRK
nota (!) que solo se reproducirá el sonido una vez y lo hace cuando se inicia el programa.
### algunos experimentos sugeridos
te invito a que experimentes modificando los valores del ADSR: ¿cómo cambia el sonido cuando solo hay uno de ellos? ¿o cuando todos son números pequeños o con diferentes combinaciones de duraciones?
también, prueba a cambiar el byte tono: ¿corresponden con tus oídos los valores midi que esperas?
@ -536,11 +536,11 @@ el byte de salida nos permite leer la amplitud de la envolvente. devuelve 0 cuan
la idea de tener cuatro dispositivos de audio es que podemos tenerlos todos sonando a la vez y cada uno puede tener una muestra, envolvente ADSR, volumen y tono diferentes.
esto nos da muchas más posibilidades:
esto nos da muchas más posibilidades:
¿quizás en un juego podría haber una melodía sonando de fondo junto con sonidos incidentales relacionados con la jugabilidad?
¿quizás en un juego podría haber una melodía sonando de fondo junto con sonidos incidentales relacionados con la jugabilidad?
¿tal vez se pueda construir un secuenciador en el que se puedan controlar los cuatro dispositivos como pistas diferentes?
¿tal vez se pueda construir un secuenciador en el que se puedan controlar los cuatro dispositivos como pistas diferentes?
¿o tal vez crear una plataforma de livecoding para tener un diálogo con cada uno de los cuatro instrumentos?
@ -550,7 +550,7 @@ en cualquier caso, ¡no dudes en compartir lo que crees! :)
aunque no lo creas, ¡este es el final!
¡has llegado al final de este tutorial! ¡felicidades!
¡has llegado al final de este tutorial! ¡felicidades!
¡espero que lo hayas disfrutado y que lo veas como el comienzo de tu viaje uxn!

View File

@ -2,7 +2,7 @@
a group of people commited to preserve computer science as a potential way of knowing and understanding emergent complexity in the universe.
they are proficient in the {qiudanz technique} and use it to create folk and post-collapse dances. these dances are nomad-friendly because they don't need material props, and can be performed by small groups of people.
they are proficient in the {qiudanz technique} and use it to create folk and post-collapse dances. these dances are nomad-friendly because they don't need material props, and can be performed by small groups of people.
whenever many of them gather, they dance performing and becoming elementary cellular automata, {reglas de wolfram}.

View File

@ -1,6 +1,6 @@
# uxn tutorial
welcome to this beginner's, slow-paced and comprehensive guide for programming the varvara computer based on the {uxn} core.
welcome to this beginner's, slow-paced and comprehensive guide for programming the varvara computer based on the {uxn} core.
you can get an offline version of this guide as the {introduction to uxn programming book}!
@ -10,15 +10,15 @@ there's a translation to spanish: {tutorial de uxn}
# day 1
in this first section of the tutorial we talk about the basics of the uxn computer called varvara, its programming paradigm in a language called uxntal, its architecture, and why you would want to learn to program it.
in this first section of the tutorial we talk about the basics of the uxn computer called varvara, its programming paradigm in a language called uxntal, its architecture, and why you would want to learn to program it.
we also jump right in into our first simple programs to demonstrate fundamental concepts that we will develop further in the following days.
we also jump right in into our first simple programs to demonstrate fundamental concepts that we will develop further in the following days.
=> ./uxn_tutorial_day_1.gmi {uxn tutorial day 1}
# day 2
in this section we start exploring the visual aspects of the varvara computer: we talk about the fundamentals of the screen device so that we can start drawing on it!
in this section we start exploring the visual aspects of the varvara computer: we talk about the fundamentals of the screen device so that we can start drawing on it!
we also discuss working with shorts (2-bytes) besides single bytes in uxntal.
@ -58,7 +58,7 @@ we also discuss possible structures to create loops and more complex programs us
here we talk about how we can integrate everything that we have covered in order to create even more complex subroutines and programs for the varvara computer.
we base our discussion in a recreation of the classic pong game!
we base our discussion in a recreation of the classic pong game!
besides using previous strategies and snippets of code, we cover strategies for drawing and controlling multi-tile sprites, and for checking collisions.
@ -66,7 +66,7 @@ besides using previous strategies and snippets of code, we cover strategies for
=> ./img/screenshot_uxn-pong-paddles-and-ball.png screenshot showing the stage of the pong game: a couple of paddles at the sides, and a ball at the center
# day 7
# day 7
here we talk about the devices in the varvara computer that we haven't covered yet: audio, file, and datetime.
@ -78,7 +78,7 @@ this should be a light and calm end of our journey, as it has to do less with pr
## appendix a: generalized rectangular tiles drawing
in this appendix we generalize the background drawing procedure discussed on day 6, into a draw-tiles subroutine that draws an arbitrary rectangle filled with a given tile.
in this appendix we generalize the background drawing procedure discussed on day 6, into a draw-tiles subroutine that draws an arbitrary rectangle filled with a given tile.
we detail how to get to two versions of this subroutine, one that relies on heavy stack wrangling, and other one that uses variables. this in order to compare both approaches and give us a broader view of the possibilities within uxntal.
@ -125,7 +125,7 @@ you can find a more detailed reference of all the opcodes in the uxntal opcode m
* BRK: break the flow of the program, in order to close subroutines
* MUL: take the top two elements from the stack, multiply them, and push down the result ( a b -- a*b )
* DIV: take the top two elements from the stack, divide them, and push down the result ( a b -- a/b )
* SFT: take a shift value and a number to shift with that value, and shift it. the low nibble of the shift value indicates the shift to the right, and the high nibble the shift to the left ( number shift -- shiftednumber )
* SFT: take a shift value and a number to shift with that value, and shift it. the low nibble of the shift value indicates the shift to the right, and the high nibble the shift to the left ( number shift -- shiftednumber )
## day 3

View File

@ -8,7 +8,7 @@ here we will generalize a similar procedure into a draw-tiles subroutine that dr
@draw-tiles ( x^ y^ width^ height^ addr* -- )
```
a reminder that we are using the convention of adding a caret (^) after the name of a value to indicate it's a short, and an asterisk (*) to indicate it's a short working as a pointer (i.e. an address in program memory)
a reminder that we are using the convention of adding a caret (^) after the name of a value to indicate it's a short, and an asterisk (*) to indicate it's a short working as a pointer (i.e. an address in program memory)
we will detail how to get to two versions of this subroutine, one that relies on heavy stack wrangling, and other one that uses variables. this in order to compare both approaches and give us a broader view of the possibilities within uxntal.
@ -76,7 +76,7 @@ adding 8 to x, we know already:
checking if x is less than the limit, jumping if it is, would be something like:
```
.Screen/x DEI2
.Screen/x DEI2
#0108 ( the limit )
LTH2 ,&loop JCN ( jump if x is less than the limit )
```
@ -216,7 +216,7 @@ following the same strategy, we could do:
### concrete version
let's use the same numbers as before, assuming that our initial y is 0008, our height is 0100, and therefore our limit would be 0108.
let's use the same numbers as before, assuming that our initial y is 0008, our height is 0100, and therefore our limit would be 0108.
in the case of x, let's start at 0000 and have a width corresponding to the screen width.
@ -255,7 +255,7 @@ this should be the signature for our subroutine:
we can approach this problem either with some "stack wrangling", or with "variables".
also note that we will do that because we are trying to get to a generalized subroutine.
also note that we will do that because we are trying to get to a generalized subroutine.
if we just wanted to cover all the screen with a sprite, we have all the required code already: we would only need to adapt the vertical limit of the loop to correspond to the height of the screen, and that would be it!
@ -438,7 +438,7 @@ we can then call it like the following in order to get a 256x256 square filled w
```
#0008 #0008 ( x and y )
#0100 #0100 ( width and height )
;tile-background
;tile-background
;draw-tiles JSR2
```
@ -446,7 +446,7 @@ we can then call it like the following in order to get a 256x256 square filled w
### using variables
let's compare the previous approach with the use of relative variables.
let's compare the previous approach with the use of relative variables.
we will go "all in" in a relatively wasteful way, without optimizing for procedures that could benefit from stack manipulation.
@ -473,9 +473,9 @@ then, we just store the next values in relative addresses:
,&x STR2
```
note that we go in reverse order.
note that we go in reverse order.
after these operations the stacks are empty.
after these operations the stacks are empty.
we can then set the initial y and calculate the vertical limit, using the values stored in the variables:
@ -495,10 +495,10 @@ our loop now would look as follows:
```
&loop-y
( retrieve x and width )
,&x LDR2
,&x LDR2
,&width LDR2
( draw row )
;draw-tiles-in-a-row JSR2
;draw-tiles-in-a-row JSR2
.Screen/y DEI2 #0008 ADD2 DUP2 ( add 8 to y )
.Screen/y DEO2 ( store new y )
@ -509,7 +509,7 @@ our loop now would look as follows:
LTH2 ,&loop-y JCN ( jump if x is less than the limit )
```
and that's it!
and that's it!
compare this with the "concrete" version we developed above, it's very similar in its structure!
@ -525,7 +525,7 @@ the complete subroutine would look like the following:
,&width STR2
,&y STR2
,&x STR2
( set initial y )
,&y LDR2 DUP2 ( ws: y^ y^ )
.Screen/y DEO2 ( ws: y^ )
@ -534,20 +534,20 @@ the complete subroutine would look like the following:
,&height LDR2 ( ws: y^ height^ )
ADD2 ( ws: limit-y^ )
,&limit-y STR2 ( ws: )
&loop-y
( retrieve x and width )
,&x LDR2
,&x LDR2
,&width LDR2
( draw row )
;draw-tiles-in-a-row JSR2
;draw-tiles-in-a-row JSR2
.Screen/y DEI2 #0008 ADD2 DUP2 ( add 8 to y )
.Screen/y DEO2 ( store new y )
( retrieve vertical limit )
,&limit-y LDR2
LTH2 ,&loop-y JCN ( jump if x is less than the limit )
RTN
@ -555,7 +555,7 @@ RTN
&height $2 &width $2 &y $2 &x $2 &limit-y $2
```
as i said before, we can find here some opportunities for optimization.
as i said before, we can find here some opportunities for optimization.
maybe the vertical limit can be stashed in the return stack like in the draw-tiles-in-a-row loop, or maybe the variable for the height and for the initial y are not needed.
@ -576,7 +576,7 @@ for example:
#0000 #0010 ( initial x and y )
.Screen/width DEI2
.Screen/height DEI2 #0010 SUB2
;tile-background
;tile-background
;draw-tiles JSR2
RTN
```

View File

@ -1,6 +1,6 @@
# uxn tutorial: day 1, the basics
hello! in this first section of the {uxn tutorial} we talk about the basics of the uxn computer called varvara, its programming paradigm in a language called uxntal, its architecture, and why you would want to learn to program it.
hello! in this first section of the {uxn tutorial} we talk about the basics of the uxn computer called varvara, its programming paradigm in a language called uxntal, its architecture, and why you would want to learn to program it.
we also jump right in into our first simple programs to demonstrate fundamental concepts that we will develop further in the following days.
@ -9,12 +9,12 @@ we also jump right in into our first simple programs to demonstrate fundamental
or first of all... what is uxn?
> The Uxn ecosystem is a personal computing playground, created to host small tools and games, programmable in its own unique assembly language.
=> https://100r.co/site/uxn.html 100R - uxn
i invite you to read "why create a smol virtual computer" from that 100R site, as well.
uxn is the core of the varvara virtual computer. it is simple enough to be emulated by many old and new computing platforms, and to be followed by hand.
uxn is the core of the varvara virtual computer. it is simple enough to be emulated by many old and new computing platforms, and to be followed by hand.
personally, i see in it the following features:
@ -25,7 +25,7 @@ personally, i see in it the following features:
* practice and experimentation ground for computing within limits
* ported already to several years old and modern computing platforms
all these concepts sound great to me, and hopefully to you too!
all these concepts sound great to me, and hopefully to you too!
however, i see in it a couple of aspects that may make it seem not too very approachable:
@ -36,7 +36,7 @@ the idea of this tutorial is to explore these two aspects and reveal how they pl
# postfix notation (and the stack)
the uxn core is inspired by forth-machines in that it uses the recombination of simple components to achieve appropriate solutions, and in that it is a stack-based machine.
the uxn core is inspired by forth-machines in that it uses the recombination of simple components to achieve appropriate solutions, and in that it is a stack-based machine.
this implies that it is primarily based on interactions with a "push down stack", where operations are indicated using what is called postfix notation.
@ -87,7 +87,7 @@ we can also write it in many other ways, for example:
make sure these expressions work and are equivalent! you just have to follow these rules, reading from left to right:
* if it's a number, push it down onto the stack
* if it's an operator, take two elements from the top of the stack, apply the operation, and push the result back onto the stack.
* if it's an operator, take two elements from the top of the stack, apply the operation, and push the result back onto the stack.
note: in the case of the division, the operands follow the same left-to-right order. 3/2 would be written as:
@ -103,7 +103,7 @@ we'll come back to postfix notation and the stack very soon!
one of the perks of programming a computer at a low-level of abstraction, as we will be doing with uxn, is that we have to know and be aware of its internal workings.
## 8-bits and hexadecimal
## 8-bits and hexadecimal
binary words of 8-bits, also known as bytes, are the basic elements of data encoding and manipulation in uxn.
@ -144,11 +144,11 @@ the stacks cannot be accessed randomly; the uxn machine takes care of them.
## instruction cycle
the uxn cpu reads one byte at a time from the main memory.
the uxn cpu reads one byte at a time from the main memory.
the program counter is a word of 16-bits that indicates the address of the byte to read next. its initial value is the address 0100 in hexadecimal.
once the cpu reads a byte, it decodes it as an instruction and performs it.
once the cpu reads a byte, it decodes it as an instruction and performs it.
the instruction will normally imply a change in the stack(s), and sometimes it may imply a change of the normal flow of the program counter: instead of pointing to the next byte in memory, it can be made to point elsewhere, "jumping" from a place in memory to another.
@ -162,7 +162,7 @@ in order to run varvara locally and off the grid, we'd have to get the uxn assem
you can either build these tools from source, or download pre-compiled binaries for multiple platforms.
you can find the installation instructions in the repository.
you can find the installation instructions in the repository.
if you need a hand, find us in #uxn on irc.esper.net :)
@ -258,7 +258,7 @@ Loaded hello.rom
h
```
the last 'h' we see is the output of our program.
the last 'h' we see is the output of our program.
edit the code changing the 68 to, for example, 65, and now you'll see an 'e'.
@ -313,19 +313,19 @@ in uxntal we can only write numbers that are 2 or 4 hexadecimal digits long. if,
## assembled rom
when we assembled our program, we saw that it was 5 bytes in size.
when we assembled our program, we saw that it was 5 bytes in size.
we can confirm it using the wc (word count) program:
```
$ wc --bytes hello.rom
$ wc --bytes hello.rom
5 hello.rom
```
for the curious (like you!), we could use a tool like hexdump to see its contents:
```
$ hexdump -C hello.rom
$ hexdump -C hello.rom
00000000 80 68 80 18 17 |.h...|
00000005
```
@ -380,7 +380,7 @@ if the address is 2-bytes long, it is assumed to be an address for the main memo
## literal hex rune
let's talk about another one: #.
let's talk about another one: #.
this character defines a "literal hex": it is basically a shorthand for the LIT instruction.
@ -391,7 +391,7 @@ using this rune, we could re-write our first program as:
|0100 #68 #18 DEO
```
the following would have the same behavior as the program above, but using one less byte (in the next day of the tutorial we'll see why)
the following would have the same behavior as the program above, but using one less byte (in the next day of the tutorial we'll see why)
```
( hello.tal )
@ -400,7 +400,7 @@ the following would have the same behavior as the program above, but using one l
note that you can only use this rune to write the contents of either one or two bytes, i.e. two or four nibbles.
important: remember that this rune (and the others with the word "literal" in their names) is a shorthand for the LIT instruction. this implies that uxn will push these values down into the stack.
important: remember that this rune (and the others with the word "literal" in their names) is a shorthand for the LIT instruction. this implies that uxn will push these values down into the stack.
if we just want to have a specific number in the main memory, without pushing it into the stack, we would just write the number as is, "raw". this is the way we did it in our first programs above.
@ -414,11 +414,11 @@ using this rune, our "hello program" would look like the following:
```
( hello.tal )
|0100 LIT 'h #18 DEO
LIT 'e #18 DEO
LIT 'l #18 DEO
LIT 'l #18 DEO
LIT 'o #18 DEO
|0100 LIT 'h #18 DEO
LIT 'e #18 DEO
LIT 'l #18 DEO
LIT 'l #18 DEO
LIT 'o #18 DEO
#0a #18 DEO ( newline )
```
@ -471,11 +471,11 @@ we could re-write our "hello program" as follows:
|10 @Console [ &vector $2 &read $1 &pad $5 &write $1 &error $1 ]
( main program )
|0100 LIT 'h .Console/write DEO
LIT 'e .Console/write DEO
LIT 'l .Console/write DEO
LIT 'l .Console/write DEO
LIT 'o .Console/write DEO
|0100 LIT 'h .Console/write DEO
LIT 'e .Console/write DEO
LIT 'l .Console/write DEO
LIT 'l .Console/write DEO
LIT 'o .Console/write DEO
#0a .Console/write DEO ( newline )
```
@ -493,9 +493,9 @@ for example, we can see that the following piece of code is repeated many times
.Console/write DEO ( equivalent to #18 DEO, or LIT 18 DEO )
```
we could define a macro called EMIT that will take from the stack a byte corresponding to a character, and print it to standard output.
we could define a macro called EMIT that will take from the stack a byte corresponding to a character, and print it to standard output.
for this, we need the % rune, and curly brackets for the definition.
for this, we need the % rune, and curly brackets for the definition.
don't forget the spaces!
@ -508,7 +508,7 @@ in order to call a macro, we just write its name:
```
( print character h )
LIT 'h EMIT
LIT 'h EMIT
```
we can call macros inside macros, for example:
@ -535,7 +535,7 @@ using all these macros and runes, our program could end up looking like the foll
( main program )
|0100 LIT 'h EMIT
LIT 'e EMIT
LIT 'e EMIT
LIT 'l EMIT
LIT 'l EMIT
LIT 'o EMIT
@ -587,7 +587,7 @@ these are the instructions we covered today:
well done! hope you had a great start today!
in {uxn tutorial day 2} we start exploring the visual aspects of the varvara computer: we talk about the fundamentals of the screen device so that we can start drawing on it!
in {uxn tutorial day 2} we start exploring the visual aspects of the varvara computer: we talk about the fundamentals of the screen device so that we can start drawing on it!
however, i invite you to take a little break before continuing! :)

View File

@ -1,8 +1,8 @@
# uxn tutorial: day 2, the screen
this is the second section of the {uxn tutorial}!
this is the second section of the {uxn tutorial}!
in this section we start exploring the visual aspects of the varvara computer: we talk about the fundamentals of its screen device so that we can start drawing on it!
in this section we start exploring the visual aspects of the varvara computer: we talk about the fundamentals of its screen device so that we can start drawing on it!
we also discuss working with shorts (2-bytes) besides single bytes in uxntal.
@ -46,7 +46,7 @@ let's see some examples!
first of all, let's recap. the following code will push number 02 down onto the stack, then it will push number 30 (hexadecimal) down onto the stack, and finally add them together, leaving number 32 in the stack:
```
```
#02 #30 ADD
```
@ -58,13 +58,13 @@ this would be the final state of the stack:
in the previous day we mentioned that the literal hex rune (#) is a shorthand for the LIT instruction. therefore we could have written our code as follows:
```
```
LIT 02 LIT 30 ADD ( assembled code: 80 02 80 30 18 )
```
now, if we add the '2' suffix to the LIT instruction, we could write instead:
```
```
LIT2 02 30 ADD ( assembled code: a0 02 30 18 )
```
@ -106,7 +106,7 @@ in this case we are pushing the same 4 bytes down onto the stack, but ADD2 is do
* take the new top element of the stack (00), and store it as the high byte of the second short, that is now 0004
* add the two shorts (0004 + 0008), getting a result of 000c
* push the high byte of the result (00) down onto the stack
* push the low byte of the result (0c) down onto the stack
* push the low byte of the result (0c) down onto the stack
the stack ends up looking as follows:
@ -128,7 +128,7 @@ the DEO instruction needs a value (1 byte) to output, and an i/o address (1 byte
DEO ( value address -- )
```
this instuction has a counterpart: DEI (device in).
this instuction has a counterpart: DEI (device in).
the DEI instruction takes an i/o address (1 byte) from the stack, and it will push down onto the stack the value (1 byte) that corresponds to reading that input.
@ -142,13 +142,13 @@ in the case of the short mode of DEO and DEI, the short aspect applies to the va
remember that the 256 i/o addresses are covered using one byte only already, so using one short for them would be redundant: the high byte would be always 00.
considering this, the following are the behaviors that we can expect:
considering this, the following are the behaviors that we can expect:
the DEO2 instruction needs a value (1 short) to output, and an i/o address (1 byte) in the stack, in order to output that value to that address. therefore it needs a total of 3 bytes in the stack to operate.
on the other hand, the DEI2 instruction needs an i/o address (1 byte) in the stack, and it will push down onto the stack the value (1 short) that corresponds to that input.
on the other hand, the DEI2 instruction needs an i/o address (1 byte) in the stack, and it will push down onto the stack the value (1 short) that corresponds to that input.
in the following section we will see some examples where we'll be able to use these instructions.
in the following section we will see some examples where we'll be able to use these instructions.
the 'write' port of the console device that we used last time has a size of 1 byte, so we can't really use these new instructions in a meaningful way with it.
@ -168,7 +168,7 @@ we will ignore the first elements for the moment, and focus on the color compone
the varvara screen device can only show a maximum of four colors at a time.
these four colors are called color 0, color 1, color 2 and color 3.
these four colors are called color 0, color 1, color 2 and color 3.
each color has a total depth of 12 bits: 4 bits for the red component, 4 bits for the green component, and 4 bits for the blue component.
@ -247,10 +247,10 @@ in order to do this we need to set a pair of x,y coordinates where we want the p
## setting the coordinates
the x,y coordinates follow conventions that are common to other computer graphics software:
the x,y coordinates follow conventions that are common to other computer graphics software:
* x starts in 0 at the left, and increases towards the right of the screen
* y starts in 0 at the top, and increases towards the bottom of the screen
* y starts in 0 at the top, and increases towards the bottom of the screen
if we wanted to draw a pixel in coordinates ( 8, 8 ), we'd set its coordinates in this way:
@ -296,7 +296,7 @@ the 8 possible combinations of the 'pixel' byte that we have for drawing a pixel
& * 01: draw pixel with color 1
& * 02: draw pixel with color 2
& * 03: draw pixel with color 3
&
&
& foreground layer:
& * 40: draw pixel with color 0
& * 41: draw pixel with color 1
@ -305,7 +305,7 @@ the 8 possible combinations of the 'pixel' byte that we have for drawing a pixel
## hello pixel
let's try it all together! the following code will draw a pixel with color 1 in the foreground layer, at coordinates (8,8)
let's try it all together! the following code will draw a pixel with color 1 in the foreground layer, at coordinates (8,8)
```
#0008 .Screen/x DEO2
@ -381,19 +381,19 @@ we can define a macro to make this process easier to write:
we will not cover repetitive structures yet, but this is a good opportunity to start aligning our code towards that.
even though the x and y coordinates of the screen device are intended as outputs, we can also read them as inputs.
even though the x and y coordinates of the screen device are intended as outputs, we can also read them as inputs.
for example, in order to read the x coordinate, pushing its value down onto the stack, we can write:
```
.Screen/x DEI2
```
```
taking that into account, can you tell what would this code do?
```
.Screen/x DEI2
#0001 ADD2
.Screen/x DEI2
#0001 ADD2
.Screen/x DEO2
```
@ -425,7 +425,7 @@ adding 1 to the value at the top of the stack is so common that there's an instr
INC ( a -- a+1 )
```
INC takes the value from the top of the stack, increments it by one, and pushes it back.
INC takes the value from the top of the stack, increments it by one, and pushes it back.
in the case of the short mode, INC2 does the same but incrementing a short instead of a byte.
@ -466,7 +466,7 @@ using these macros we defined above, our code could end up looking as following:
DRAW-PIXEL INC-X
DRAW-PIXEL INC-X
DRAW-PIXEL INC-X
DRAW-PIXEL
DRAW-PIXEL
```
nice, isn't it? the operations now look clearer! and if we wanted to have this line available for use in other positions, we could define a macro for it:
@ -481,7 +481,7 @@ try writing the macro and using it in different positions of the screen!
now, we'll see now how to leverage the built-in support for "sprites" in the varvara screen device in order to draw many pixels at once!
the varvara screen device allows us to use and draw tiles of 8x8 pixels, also called sprites.
the varvara screen device allows us to use and draw tiles of 8x8 pixels, also called sprites.
there are two posible modes: 1bpp (1 bit per pixel), and 2bpp (2 bits per pixel).
@ -493,13 +493,13 @@ we will be storing and accessing these tiles from the main memory.
# drawing 1bpp sprites
a 1bpp tile consists in a set of 8 bytes that encode the state of its 8x8 pixels.
a 1bpp tile consists in a set of 8 bytes that encode the state of its 8x8 pixels.
each byte corresponds to a row of the tile, and each bit in a row corresponds to the state of a pixel from left to right: it can be either "on" (1) or "off" (0).
## encoding a 1bpp sprite
for example, we could design a tile that corresponds to the outline of an 8x8 square, turning on or off its pixels accordingly.
for example, we could design a tile that corresponds to the outline of an 8x8 square, turning on or off its pixels accordingly.
``` the outline of a square marked with 1s, and its insides marked with 0s
11111111
@ -553,7 +553,7 @@ to achieve the former, we write the following:
;square .Screen/addr DEO2
```
a new rune is here! the literal absolute address rune (;) lets us push down onto the stack the absolute address of the given label in main memory.
a new rune is here! the literal absolute address rune (;) lets us push down onto the stack the absolute address of the given label in main memory.
an absolute address would be 2-bytes long, and is pushed down onto the stack with LIT2, included by the assembler when using this rune.
@ -587,7 +587,7 @@ the eight possible values of the sprite high nibble, used for drawing a 1bpp spr
& * 1: draw a 1bpp sprite, flipped horizontally
& * 2: draw a 1bpp sprite, flipped vertically
& * 3: draw a 1bpp sprite, flipped horizontally and vertically
&
&
& foreground:
& * 4: draw a 1bpp sprite, original orientation
& * 5: draw a 1bpp sprite, flipped horizontally
@ -639,25 +639,25 @@ the low nibble of the 'sprite' byte will determine the colors that are used to d
+ <tr><td class="num">f</td><td>3</td><td>none</td></tr>
+ </table>
& * 0: clear tile
& * 1: "on" with color 1, "off" with color 0
& * 2: "on" with color 2, "off" with color 0
& * 3: "on" with color 3, "off" with color 0
& * 4: "on" with color 0, "off" with color 1
& * 5: "on" with color 1, "off" with no color
& * 6: "on" with color 2, "off" with color 1
& * 7: "on" with color 3, "off" with color 1
& * 8: "on" with color 0, "off" with color 2
& * 9: "on" with color 1, "off" with color 2
& * a: "on" with color 2, "off" with no color
& * b: "on" with color 3, "off" with color 2
& * c: "on" with color 0, "off" with color 3
& * d: "on" with color 1, "off" with color 3
& * e: "on" with color 2, "off" with color 3
& * f: "on" with color 3, "off" with no color
& * 1: "on" with color 1, "off" with color 0
& * 2: "on" with color 2, "off" with color 0
& * 3: "on" with color 3, "off" with color 0
& * 4: "on" with color 0, "off" with color 1
& * 5: "on" with color 1, "off" with no color
& * 6: "on" with color 2, "off" with color 1
& * 7: "on" with color 3, "off" with color 1
& * 8: "on" with color 0, "off" with color 2
& * 9: "on" with color 1, "off" with color 2
& * a: "on" with color 2, "off" with no color
& * b: "on" with color 3, "off" with color 2
& * c: "on" with color 0, "off" with color 3
& * d: "on" with color 1, "off" with color 3
& * e: "on" with color 2, "off" with color 3
& * f: "on" with color 3, "off" with no color
as an example, this means that setting the sprite low nibble to 6 will draw the sprite with color 2 in the "on" pixels, and color 1 in the "off" pixels.
note that 0 in the low nibble will clear the tile.
note that 0 in the low nibble will clear the tile.
additionally, 5, 'a' and 'f' in the low nibble will draw the pixels that are "on" but will leave the ones that are "off" as is: this will allow you to draw over something that has been drawn before, without erasing it completely.
@ -701,7 +701,7 @@ BRK
=> ./img/screenshot_uxn-tiles.png screenshot of the output of the program, showing 16 squares colored with different combinations of outline and fill.
the following code will draw our square sprite with all 16 combinations of color:
the following code will draw our square sprite with all 16 combinations of color:
```
( hello-sprites.tal )
@ -750,7 +750,7 @@ the following code will draw our square sprite with all 16 combinations of color
#0c .Screen/sprite DEO 8ADD-X
#0d .Screen/sprite DEO 8ADD-X
#0e .Screen/sprite DEO 8ADD-X
#0f .Screen/sprite DEO
#0f .Screen/sprite DEO
BRK
@ -761,20 +761,20 @@ note that in this case, we have a couple of 8ADD-X and 8ADD-Y macros to incremen
## flipping experiments
because the square sprite is symmetric, we can't really see the effect of flipping it.
because the square sprite is symmetric, we can't really see the effect of flipping it.
here are the sprites of the boulder/rock and the character of {darena}:
```
@rock 3c4e 9ffd f962 3c00
@character 3c7e 5a7f 1b3c 5a18
@rock 3c4e 9ffd f962 3c00
@character 3c7e 5a7f 1b3c 5a18
```
i invite you to try using these sprites instead to explore how to draw them flipped in the different directions.
# drawing 2bpp sprites
in 2bpp sprites each pixel can have one of four possible colors.
in 2bpp sprites each pixel can have one of four possible colors.
we can think that, in order to assign these colors, we will encode one out of four states in each of the pixels of the sprite.
@ -784,7 +784,7 @@ a single 2bpp tile of 8x8 pixels needs 16 bytes to be encoded. these bytes are o
## encoding a 2bpp sprite
to demonstrate this encoding, we are going to remix our 8x8 square, assigning one of four possible states (0, 1, 2, 3) to each of the pixels:
to demonstrate this encoding, we are going to remix our 8x8 square, assigning one of four possible states (0, 1, 2, 3) to each of the pixels:
``` an 8x8 square built with the digits 0 and 1 in the border, and 2 and 3 in the inside
00000001
@ -802,17 +802,17 @@ we can think of each these digits as a pair of bits: 0 is 00, 1 is 01, 2 is 10,
in this way, we could think of our sprite as follows:
``` an 8x8 square built with pair of bits between parenthesis, corresponding to the binary representation of each of the states
(00) (00) (00) (00) (00) (00) (00) (01)
(00) (11) (11) (11) (11) (11) (01) (01)
(00) (11) (11) (11) (11) (10) (01) (01)
(00) (11) (11) (11) (10) (10) (01) (01)
(00) (11) (11) (10) (10) (10) (01) (01)
(00) (11) (10) (10) (10) (10) (01) (01)
(00) (01) (01) (01) (01) (01) (01) (01)
(01) (01) (01) (01) (01) (01) (01) (01)
(00) (00) (00) (00) (00) (00) (00) (01)
(00) (11) (11) (11) (11) (11) (01) (01)
(00) (11) (11) (11) (11) (10) (01) (01)
(00) (11) (11) (11) (10) (10) (01) (01)
(00) (11) (11) (10) (10) (10) (01) (01)
(00) (11) (10) (10) (10) (10) (01) (01)
(00) (01) (01) (01) (01) (01) (01) (01)
(01) (01) (01) (01) (01) (01) (01) (01)
```
the chr encoding requires some interesting manipulation of those bits: we can think of each pair of bits as having a high bit in the left and a low bit in the right.
the chr encoding requires some interesting manipulation of those bits: we can think of each pair of bits as having a high bit in the left and a low bit in the right.
we separate our tile into two different squares, one for the high bits and the other for the low bits:
@ -862,7 +862,7 @@ let's see how to use the sprite byte in order to draw 2bpp tiles!
### sprite high nibble for 2bpp
the high nibble for 2bpp sprites will allow us to choose the layer we want it to be drawn, and the flip direction.
the high nibble for 2bpp sprites will allow us to choose the layer we want it to be drawn, and the flip direction.
the eight possible values for this nibble are:
@ -986,7 +986,7 @@ the following code will show our sprite in the 16 different combinations of colo
#8c .Screen/sprite DEO cADD-X
#8d .Screen/sprite DEO cADD-X
#8e .Screen/sprite DEO cADD-X
#8f .Screen/sprite DEO
#8f .Screen/sprite DEO
BRK
@ -997,7 +997,7 @@ try flipping the tiles!
## screen.tal and the combinations of the sprite byte
the screen.tal example in the uxn repo consists of a table showing all possible (256!) combinations of high and low nibbles in the sprite byte.
the screen.tal example in the uxn repo consists of a table showing all possible (256!) combinations of high and low nibbles in the sprite byte.
=> ./img/screenshot_uxn-screen.png screenshot of the screen.tal example, that shows a sprite colored and flipped in different ways.
@ -1025,7 +1025,7 @@ i recommend you give nasu a try!
# screen size and responsiveness
the last thing we'll cover today has to do with the assumptions varvara makes about its screen size, and some code strategies we can use to deal with them.
the last thing we'll cover today has to do with the assumptions varvara makes about its screen size, and some code strategies we can use to deal with them.
in short, there's not a standard screen size!
@ -1099,13 +1099,13 @@ this instruction takes a number and a "shift value" that indicates the amount of
the low nibble of the shift value tells uxn how many positions to shift to the right, and the high nibble expresses how many bits to shift to the left.
in order to divide a number over 2, we'd need to shift its bits one space to the right.
in order to divide a number over 2, we'd need to shift its bits one space to the right.
for example, dividing 10 (in decimal) over 2 could be expressed as follows:
```
#0a #01 SFT ( result: 05 )
```
```
0a is 0000 1010 in binary, and 05 is 0000 0101 in binary: the bits from 0a were shifted one position to the right, and a zero was brought in as the leftmost bit.
@ -1130,7 +1130,7 @@ for example, the following will divide the screen width over two, by using bitwi
in order to keep illustrating the use of macros, we could define a HALF and HALF2 macros, either using DIV or SFT.
using DIV:
using DIV:
```
%HALF { #02 DIV } ( number -- number/2 )
@ -1172,15 +1172,15 @@ besides covering the basics of the screen device today, we discussed these new i
* BRK: break the flow of the program, in order to close subroutines
* MUL: take the top two elements from the stack, multiply them, and push down the result ( a b -- a*b )
* DIV: take the top two elements from the stack, divide them, and push down the result ( a b -- a/b )
* SFT: take a shift value and a number to shift with that value, and shift it. the low nibble of the shift value indicates the shift to the right, and the high nibble the shift to the left ( number shift -- shiftednumber )
* SFT: take a shift value and a number to shift with that value, and shift it. the low nibble of the shift value indicates the shift to the right, and the high nibble the shift to the left ( number shift -- shiftednumber )
we also covered the short mode, that indicates the cpu that it should operate with words that are 2 bytes long.
# day 3
in {uxn tutorial day 3} we start working with interactivity using the keyboard, and we cover in depth several uxntal instructions!
in {uxn tutorial day 3} we start working with interactivity using the keyboard, and we cover in depth several uxntal instructions!
however, i invite you to take a break, and maybe keep exploring drawing in the uxn screen via code, before continuing!
however, i invite you to take a break, and maybe keep exploring drawing in the uxn screen via code, before continuing!
# support

View File

@ -1,6 +1,6 @@
# uxn tutorial: day 3, conditional jumps and the keyboard/controller
this is the third section of the {uxn tutorial}!
this is the third section of the {uxn tutorial}!
here we introduce the use of the controller device in the varvara uxn computer: this will allow us to add interactivity to our programs, and to start discussing control flow in uxntal.
@ -97,7 +97,7 @@ it uses the sprite drawing procedure we tried in the previous day, but has it ha
|80 @Controller [ &vector $2 &button $1 &key $1 ]
( main program )
|0100
|0100
( set system colors )
#2ce9 .System/r DEO2
#01c0 .System/g DEO2
@ -108,7 +108,7 @@ it uses the sprite drawing procedure we tried in the previous day, but has it ha
BRK
( run this code whenever a key is pressed or released )
@on-controller ( -> )
@on-controller ( -> )
( set x,y coordinates )
#0008 .Screen/x DEO2
#0008 .Screen/y DEO2
@ -127,9 +127,9 @@ BRK
nice, isn't it?
now, how can we take different actions depending on the key that was pressed?
now, how can we take different actions depending on the key that was pressed?
first of all, we have to let our program know which key was pressed so that it can act accordingly.
first of all, we have to let our program know which key was pressed so that it can act accordingly.
in order to achieve that, let's take a look at some new uxntal instructions!
@ -158,7 +158,7 @@ EQU2, NEQ2, GTH2 and LTH2 will work in the same way, but comparing shorts instea
## logic instructions
uxntal has three bitwise logic instructions.
uxntal has three bitwise logic instructions.
they can work as logic operators that use as operands the flags given by the comparison instructions we discussed above:
@ -180,7 +180,7 @@ the following will push down into the stack a flag that indicates if the key byt
AND ( apply an AND to the flags in the stack, and push the result into the stack )
```
that the instruction is bitwise means that it applies the AND operation to each of the bits of the operands.
that the instruction is bitwise means that it applies the AND operation to each of the bits of the operands.
if both flags were "true":
@ -202,7 +202,7 @@ AND 0000 0000 ( false )
as these flags only use the least significant bit (the rightmost bit) to encode their value, a bitwise AND is equivalent to a conventional logic AND.
### OR
### OR
the following code will push a flag down into the stack if the key byte is either '1' or 'a':
@ -265,7 +265,7 @@ note that the mask is the same, and the result is the opposite value of the flag
ok, so now our programs can identify and store in flags if a value (like the read keyboard key) is a specific value, or within some range.
how can we use these flags in order to have conditional behaviors in our programs, where different actions are taken depending on the results?
how can we use these flags in order to have conditional behaviors in our programs, where different actions are taken depending on the results?
let's introduce another set of new instructions to have uxn break its linear flow!
@ -274,7 +274,7 @@ let's introduce another set of new instructions to have uxn break its linear flo
* JMP: unconditionally jump to the address in the stack ( addr -- )
* JCN: conditional jump: take an address and a value from the stack, and if the value is not 00, jump to the address; otherwise continue with the next instruction ( value addr -- )
in byte mode, the addresses that these instructions use are one byte long.
in byte mode, the addresses that these instructions use are one byte long.
these byte-long addresses are relative and signed: they indicate how many bytes have to be skipped in main memory from the current position of the program counter, either forward (positive) or backwards (negative). the range for these relative addresses is from -128 to 127 inclusive.
@ -314,7 +314,7 @@ the following on-controller subroutine illustrates the use of jumps, drawing our
LIT '1 EQU ( is it '1'? )
( jump to draw-sprite if that's the case )
,&draw-sprite JCN
,&draw-sprite JCN
,&end JMP ( otherwise, jump to the end )
@ -334,7 +334,7 @@ the following on-controller subroutine illustrates the use of jumps, drawing our
BRK
```
note the use of sublabels "inside" (after) on-controller.
note the use of sublabels "inside" (after) on-controller.
also note how the expression ,&sublabel corresponds to the relative address (,) that is needed in order to jump to that location in the code named with a local sublabel (&).
@ -410,7 +410,7 @@ in short mode, POP2, DUP2, SWP2, NIP2, OVR2 and ROT2 perform the same actions bu
## examples
we'll be using these instructions in many different ways during the following days.
we'll be using these instructions in many different ways during the following days.
the following are some examples based on snippets of code that we discussed already.
@ -452,7 +452,7 @@ after this, the stack would look like:
key flag1 <- top
```
in order to perform the second comparison, we need to have the key at the top, not the flag.
in order to perform the second comparison, we need to have the key at the top, not the flag.
how do we achieve that? that's right, using a SWP:
@ -491,7 +491,7 @@ AND ( apply an AND to the flags in the stack, and push the result in the stack )
the first code is assembled as 13 bytes, and this one is assembled as 12 bytes. maybe not too much of a difference on that front.
however, a more meaningful advantage is that this new routine now needs its input pushed down into the stack only at the beginning.
however, a more meaningful advantage is that this new routine now needs its input pushed down into the stack only at the beginning.
in the case we just discussed the input is the key that is pressed, but we could easily have as an input any other value from the stack.
@ -561,7 +561,7 @@ we could rewrite it using several DUPs and POPs:
BRK
```
can you tell why we need all those POPs?
can you tell why we need all those POPs?
hint: compare the final state of the stack with and without the POP instructions.
@ -571,7 +571,7 @@ in the following days we'll see more uses and examples of stack manipulation!
the last thing we'll discuss today is the use of the controller button byte in the varvara computer.
as we mentioned already, the main difference here is that this byte holds the state of 8 buttons in each of its bits.
as we mentioned already, the main difference here is that this byte holds the state of 8 buttons in each of its bits.
depending on our application, we might need to be able to allow for some of these buttons to be pressed at the same time.
@ -646,7 +646,7 @@ note the use of AND masks, conditional jumps, and some stack operations!
|80 @Controller [ &vector $2 &button $1 &key $1 ]
( main program )
|0100
|0100
( set system colors )
#2ce9 .System/r DEO2
#01c0 .System/g DEO2
@ -673,7 +673,7 @@ BRK
&fill
#04 .Screen/sprite DEO ( draw filled )
&check-arrows
( use button byte from the stack )
DUP #10 AND ( isolate bit 4, corresponding to Up )
@ -686,7 +686,7 @@ BRK
,&right JCN ( jump if not 0 )
POP BRK
&up
.Screen/y DEI2 #0008 SUB2 .Screen/y DEO2 ( decrement y )
POP
@ -729,7 +729,7 @@ here are some other ideas for you to practice with what we covered today!
* draw a character that changes its state according to the key you pressed. maybe use multiple tiles to draw it?
* create a simple tic-tac-toe board for two players: one key draws a X, another draws a O, and the arrows allow you to choose the cell to draw.
note that for smooth interactive movement it might be better to use the screen vector that is called 60 times per second!
note that for smooth interactive movement it might be better to use the screen vector that is called 60 times per second!
we'll cover that in depth in the next day of the tutorial!
@ -767,7 +767,7 @@ these are all the uxntal instructions that we discussed today!
# day 4
in {uxn tutorial day 4} we cover the use of the screen vector in order to create animation, either interactive or not!
in {uxn tutorial day 4} we cover the use of the screen vector in order to create animation, either interactive or not!
we also explore possibilities for using "variables" in uxntal than can help us creating more elaborate programs!

View File

@ -1,6 +1,6 @@
# uxn tutorial: day 4, variables and animation loop
this is the fourth section of the {uxn tutorial}!
this is the fourth section of the {uxn tutorial}!
here we discuss the animation loop of the varvara computer, via its screen device vector.
@ -8,7 +8,7 @@ we also talk about using the program memory as a space for data using "variables
# the screen vector
we discussed the varvara screen device on day 2, but we skipped its vector port in order to focus in how to draw with it:
we discussed the varvara screen device on day 2, but we skipped its vector port in order to focus in how to draw with it:
```
|20 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 ]
@ -61,7 +61,7 @@ BRK
BRK
```
note that the code is very similar to the one we wrote on day 2 for drawing a line.
note that the code is very similar to the one we wrote on day 2 for drawing a line.
in that one, we manually incremented the value of Screen/x in order to draw 6 pixels.
@ -79,11 +79,11 @@ these are some changes for you to try and practice:
# variables
the varvara screen vector opens up a whole world of possibilities!
the varvara screen vector opens up a whole world of possibilities!
it's worth noting that many of these possibilities require ways of storing and retrieving data between frames.
in the previous example, we are using the screen ports for the x and y coordinates as a way of storing the coordinates for the pixel.
in the previous example, we are using the screen ports for the x and y coordinates as a way of storing the coordinates for the pixel.
but what happens when we want to draw different objects, each with its own set of coordinates and other characteristics that can change over time?
@ -134,7 +134,7 @@ here are the two instructions that would help us:
* LDA: load and push down into the stack the value at the given absolute address ( address -- value )
* STA: store into the given absolute address the given value ( value address -- )
as we have discussed already, an absolute address will always be two bytes long.
as we have discussed already, an absolute address will always be two bytes long.
in the short mode, LDA2 will load a short from the given address, and STA2 will store a short into the given address.
@ -168,7 +168,7 @@ BRK
@pixel [ &x $2 &y $2 ]
```
note that we could have achieved the same result by storing the result, and then re-loading it and sending it as an output.
note that we could have achieved the same result by storing the result, and then re-loading it and sending it as an output.
here we can see how a DUP2 can make that operation easier, as long as we keep a mental (or tangible!) model of what is happening on the stack.
@ -245,7 +245,7 @@ in this case the program is longer, but it could be seen as a nice template for
( set initial x,y coordinates )
#0008 .pixel/x STZ2
#0008 .pixel/y STZ2
( set screen vector )
;on-frame .Screen/vector DEO2
BRK
@ -263,7 +263,7 @@ BRK
BRK
```
note the use of the literal zero page address rune (.) to refer to the .pixel label.
note the use of the literal zero page address rune (.) to refer to the .pixel label.
also, note that in the case of .pixel the address is referring to the zero page, accessed with LDZ/STZ, and in the case of .Screen the address is referring to the i/o address space, accessed with DEI/DEO.
@ -277,7 +277,7 @@ note that the following instructions would also increment .pixel/x, but setting
i recommend you to follow how the stack contents change in each of the steps: keep in mind that some of the instructions are in short mode :)
this line of code contains the same amount of bytes than the previous one.
this line of code contains the same amount of bytes than the previous one.
a possible disadvantage is that it might be less readable. but a possible advantage is that it could get converted into a macro:
@ -292,7 +292,7 @@ another possibility that we have in uxn that might be more appropriate for "loca
similar to variables in the zero page, in order to address these variables we only need one byte.
however, as these addresses are given as relative and signed offsets, they can only be reached if they are within the 256 bytes surrounding the instruction that loads or stores them.
however, as these addresses are given as relative and signed offsets, they can only be reached if they are within the 256 bytes surrounding the instruction that loads or stores them.
### instructions: LDR, STR
@ -319,7 +319,7 @@ the following is the on-frame subroutine that draws the growing line, but storin
#01 .Screen/pixel DEO
( increment pixel/x )
,pixel/x LDR2 INC2 ,pixel/x STR2
,pixel/x LDR2 INC2 ,pixel/x STR2
BRK
@pixel [ &x $2 &y $2 ]
@ -341,10 +341,10 @@ if we declared these variables as sublabels of on-frame, the code would look as
#01 .Screen/pixel DEO
( increment pixel/x )
,&pixel-x LDR2 INC2 ,&pixel-x STR2
,&pixel-x LDR2 INC2 ,&pixel-x STR2
BRK
( on-frame local variables )
&pixel-x $2 &pixel-y $2
&pixel-x $2 &pixel-y $2
```
note that in this case, the comma (,) rune is accompanied by the sublabel (&) rune.
@ -357,11 +357,11 @@ the use of "variables" will help us now in discussing three different ways of an
* autonomous change of position
* interactive change of position (with keyboard)
* autonomous change of drawn tile
* autonomous change of drawn tile
we will review them separately in order to keep the examples relatively simple and readable.
note that these examples also serve as a way of discussing more uxntal programming possibilities, and they might be a litle bit overwhelming.
note that these examples also serve as a way of discussing more uxntal programming possibilities, and they might be a litle bit overwhelming.
i recommend you to review and experiment with one at a time, patiently :)
@ -431,7 +431,7 @@ BRK
( 2: change position )
( increment sprite/pos-x )
.sprite/pos-x LDZ2 INC2 .sprite/pos-x STZ2
.sprite/pos-x LDZ2 INC2 .sprite/pos-x STZ2
( 3 : draw sprite )
( load x coordinate from zero page and send to screen )
@ -478,7 +478,7 @@ when we use the controller vector, we are acting based on a change in the button
but, how can we deal with doing a continuous action when a key is kept pressed?
in some operating systems, if we keep a key pressed, it fires the controller vector several times, but not necessarily at the same rate as the screen vector!
in some operating systems, if we keep a key pressed, it fires the controller vector several times, but not necessarily at the same rate as the screen vector!
this repetition might not allow for a smooth movement like what we can get if we check for the state of the controller inside the on-frame subroutine!
@ -539,16 +539,16 @@ BRK
,&right JCN ( jump if not 0 )
( if none of those keys were pressed, draw without changes )
,&draw JMP
,&draw JMP
&left
( decrement sprite/pos-x )
.sprite/pos-x LDZ2 #0001 SUB2 .sprite/pos-x STZ2
.sprite/pos-x LDZ2 #0001 SUB2 .sprite/pos-x STZ2
,&draw JMP
&right
( increment sprite/pos-x )
.sprite/pos-x LDZ2 INC2 .sprite/pos-x STZ2
.sprite/pos-x LDZ2 INC2 .sprite/pos-x STZ2
( 3 : draw sprite )
&draw
@ -577,7 +577,7 @@ for example, instead of having an unconditional increment in the x coordinate:
```
( increment sprite/pos-x )
.sprite/pos-x LDZ2 INC2 .sprite/pos-x STZ2
.sprite/pos-x LDZ2 INC2 .sprite/pos-x STZ2
```
we could check first if it has reached a specific amount, like the width of the screen, and not increment if that's the case:
@ -590,7 +590,7 @@ EQU2 ( is x equal to screen width - 8 ? )
&increment
( increment sprite/pos-x )
.sprite/pos-x LDZ2 INC2 .sprite/pos-x STZ2
.sprite/pos-x LDZ2 INC2 .sprite/pos-x STZ2
&continue
```
@ -612,7 +612,7 @@ we can apply those macros after incrementing or decrementing. for example:
```
( increment sprite/pos-x )
.sprite/pos-x LDZ2 INC2
.sprite/pos-x LDZ2 INC2
.Screen/width DEI2 MOD2 ( apply modulo screen width )
.sprite/pos-x STZ2 ( store result )
```
@ -684,7 +684,7 @@ in order to have that framecount constrained to a range corresponding to our num
when we have a number of frames corresponding to a power of two, as recommended above, we can use an "AND mask" to perform this modulo operation faster than if we were using the MOD macros suggested previously.
for example, if we have 8 frames numbered from 0 to 7, we can notice that those numbers only require three bits to be represented.
for example, if we have 8 frames numbered from 0 to 7, we can notice that those numbers only require three bits to be represented.
to build our AND mask, we set as 1 those three bits, and 0 the others:
@ -749,7 +749,7 @@ after applying the modulo 8 to our framecount, we can multiply it times 8 to get
note that so far we have been working with bytes, and everything has been fine.
however, absolute addresses are shorts!
however, absolute addresses are shorts!
this means we need to convert our offset to a short so that we can add it to the address of the animation data.
@ -929,7 +929,7 @@ note that if you want to divide the frequency to numbers that are not powers of
this might also happen if you have an animation consisting of a number of frames that is not a power of 2, and you use a normal MOD operation to calculate the offset to the corresponding frame.
the easiest workaround for these issues would be to use a short-sized framecount that would only cause those overflow glitches at approximately every 18 minutes.
the easiest workaround for these issues would be to use a short-sized framecount that would only cause those overflow glitches at approximately every 18 minutes.
you'd have to adapt the program to work with that size of framecount - nice exercise, i feel and think!
@ -954,7 +954,7 @@ in {uxn tutorial day 5} we introduce the varvara mouse device to explore more po
we also discuss possible structures to create loops and more complex programs using these resources!
first, i invite you to take a break!
first, i invite you to take a break!
then, keep exploring, and share your findings!

View File

@ -111,15 +111,15 @@ BRK
.Mouse/y DEI2 .Screen/y DEO2
( jump if any button is pressed )
.Mouse/state DEI ,&pressed JCN
.Mouse/state DEI ,&pressed JCN
( draw sprite using color 2 and 0 in background )
#02 .Screen/sprite DEO
#02 .Screen/sprite DEO
BRK
&pressed
( draw sprite using color 1 and 0 in background )
#01 .Screen/sprite DEO
#01 .Screen/sprite DEO
BRK
@square [ ff81 8181 8181 81ff ]
@ -184,7 +184,7 @@ BRK
.pointer/y LDZ2 .Screen/y DEO2
( clear sprite from foreground )
#40 .Screen/sprite DEO
#40 .Screen/sprite DEO
( update pointer position )
.Mouse/x DEI2 .pointer/x STZ2
@ -195,7 +195,7 @@ BRK
.pointer/y LDZ2 .Screen/y DEO2
( draw sprite with color 2 in foreground )
#4a .Screen/sprite DEO
#4a .Screen/sprite DEO
BRK
@pointer_icn [ 80c0 e0f0 f8e0 1000 ]
@ -205,9 +205,9 @@ note that it draws the pointer in the foreground, and that it uses 'a' in the lo
this blending mode would allow you to draw things in the background and have the pointer cover them with its shape only, and not with the whole square tile.
i invite you to try this!
i invite you to try this!
draw some things in the background and see how the pointer looks as it is now. then replace the pointer's sprite byte with e.g. 42 to see the difference!
draw some things in the background and see how the pointer looks as it is now. then replace the pointer's sprite byte with e.g. 42 to see the difference!
### some issues
@ -223,7 +223,7 @@ actually, that's almost what we will do, but with an additional element of uxn:
# the return stack
so far, "the stack" that we have been using is what is usually called "the working stack".
so far, "the stack" that we have been using is what is usually called "the working stack".
uxn, like other forth-like systems, has another stack of the same size, "the return stack".
@ -244,7 +244,7 @@ first of all, let's move our pointer drawing subroutine to another label in our
.pointer/y LDZ2 .Screen/y DEO2
( clear sprite from foreground )
#40 .Screen/sprite DEO
#40 .Screen/sprite DEO
( update pointer position )
.Mouse/x DEI2 .pointer/x STZ2
@ -255,7 +255,7 @@ first of all, let's move our pointer drawing subroutine to another label in our
.pointer/y LDZ2 .Screen/y DEO2
( draw sprite with color 2 in foreground )
#4a .Screen/sprite DEO
#4a .Screen/sprite DEO
BRK
```
@ -293,7 +293,7 @@ or an absolute jump:
```
@on-mouse ( -> )
;draw-pointer JMP2
&return
( something else here )
BRK
@ -304,7 +304,7 @@ the thing is, if we want something else to happen after drawing the pointer insi
at the end of our draw-pointer subroutine, we'd need to "jump back" like this:
```
;on-mouse/return JMP2
;on-mouse/return JMP2
```
it would work, but it's not the best approach.
@ -387,9 +387,9 @@ JSR or JSR2 push down into the return stack the absolute address of the next ins
how can we unconditionally jump to that absolute address that is present in the return stack?
exactly!
exactly!
activating the return mode in the JMP instruction!
activating the return mode in the JMP instruction!
additionally, as the addresses pushed by JSR are shorts, we need to activate the short mode as well:
@ -451,7 +451,7 @@ BRK
.pointer/y LDZ2 .Screen/y DEO2
( clear sprite from foreground )
#40 .Screen/sprite DEO
#40 .Screen/sprite DEO
( update pointer position )
.Mouse/x DEI2 .pointer/x STZ2
@ -462,7 +462,7 @@ BRK
.pointer/y LDZ2 .Screen/y DEO2
( draw sprite with color 2 in foreground )
#4a .Screen/sprite DEO
#4a .Screen/sprite DEO
RTN
@pointer_icn [ 80c0 e0f0 f8e0 1000 ]
@ -474,9 +474,9 @@ also note how this subroutine ends with a RTN (JMP2r) that indicates that the fl
## notes on subroutines as "functions"
keep in mind that a possible way of sending "arguments" to a subroutine would be to push them down into the working stack before calling it.
keep in mind that a possible way of sending "arguments" to a subroutine would be to push them down into the working stack before calling it.
additionaly, a possible way for a subroutine to "return" its results would be to have it pushing them down into the working stack.
additionaly, a possible way for a subroutine to "return" its results would be to have it pushing them down into the working stack.
these elements can then be consumed from the working stack after returning from the subroutine.
@ -531,14 +531,14 @@ a caret (^) after a value name indicates that it corresponds to a short.
( initialize count )
#00 ( ws: length 00 / rs: )
&loop
( stash length and count )
STH2 ( ws: / rs: length count )
( draw pixel with color 2 )
#02 .Screen/pixel DEO
( increment x )
.Screen/x DEI2 INC2 .Screen/x DEO2
@ -584,7 +584,7 @@ however, it shows how we can use these instructions to have a clean working stac
the last basic element of uxntal that we have yet to cover is its third mode for instructions: the keep mode.
the keep mode is encoded in the 8th bit of an instruction byte, counting from right to left.
the keep mode is encoded in the 8th bit of an instruction byte, counting from right to left.
in uxntal, we indicate that we want to set this flag adding the letter 'k' to the end of an instruction mnemonic.
@ -655,7 +655,7 @@ if you look carefully, you'll see that DUP2 is there in order to avoid losing th
but now, how can we perform the division without losing its operands and without using DUP2?
that's right!
that's right!
DUP2 DIV is equivalent to... DIVk! a division that doesn't lose its operands!
@ -726,7 +726,7 @@ STHkr ( retrieve a copy from the return stack )
new and interesting uses for the keep mode are still being found :)
don't hesitate to share them with us!
don't hesitate to share them with us!
# more exercises
@ -773,11 +773,11 @@ these are the uxntal instructions that we discussed today! with these, we have c
in {uxn tutorial day 6} we talk about how we can integrate everything that we have covered in order to create even more complex subroutines and programs for the varvara computer.
we base our discussion in a recreation of the classic pong game!
we base our discussion in a recreation of the classic pong game!
besides using previous strategies and snippets of code, we cover strategies for drawing and controlling multi-tile sprites, and for checking collisions.
first, i invite you to take a break!
first, i invite you to take a break!
then, keep exploring, and share your findings!

View File

@ -1,8 +1,8 @@
# uxn tutorial: day 6, towards pong
# uxn tutorial: day 6, towards pong
this is the sixth section of the {uxn tutorial}! here we talk about how we can integrate everything that we have covered in order to create more complex subroutines and programs for the varvara computer.
we base our discussion in a recreation of the classic pong game.
we base our discussion in a recreation of the classic pong game.
besides using previous strategies and snippets of code, we cover strategies for drawing and controlling multi-tile sprites, and for checking collisions.
@ -121,7 +121,7 @@ after setting the tile address, we can push our limit (the screen width) and the
we will be using that value at the top of the stack as the x coordinate.
inside the loop, we can duplicate it to set it as the screen x, and to increment it.
inside the loop, we can duplicate it to set it as the screen x, and to increment it.
in between, we can send our sprite byte in order to draw the tile.
@ -153,7 +153,7 @@ using this strategy, we would get the following loop:
DUP2 .Screen/x DEO2 ( set x coordinate )
#03 .Screen/sprite DEO ( draw 1bpp sprite with color 3 and 0 )
#0008 ADD2 ( increment x )
GTH2k ( is the width greater than x? aka is x less than the width ? )
,&loop-x JCN ( jump if x is less than the limit )
@ -188,7 +188,7 @@ the following shows our program in context, completely filling the first row of
#2ce9 .System/r DEO2
#01c0 .System/g DEO2
#2ce5 .System/b DEO2
( draw background )
;tile-background .Screen/addr DEO2 ( set tile address )
@ -262,8 +262,8 @@ WALL-MARGIN ( set initial y )
DUP2 .Screen/x DEO2 ( set x coordinate )
( draw 1bpp sprite with color 3 and 0 )
#03 .Screen/sprite DEO
#03 .Screen/sprite DEO
#0008 ADD2 ( increment x )
GTH2k ( is the width greater than x? aka is x less than the width ? )
,&loop-x JCN ( jump if x is less than the limit )
@ -284,25 +284,25 @@ now we can just wrap these nested loops inside a subroutine:
```
@draw-background ( -- )
;tile-background .Screen/addr DEO2 ( set tile address )
.Screen/height DEI2 WALL-MARGIN SUB2 ( set limit )
WALL-MARGIN ( set initial y )
&loop-y
DUP2 .Screen/y DEO2 ( set y coordinate )
( draw row )
.Screen/width DEI2 #0000 ( set limit and initial x )
&loop-x
DUP2 .Screen/x DEO2 ( set x coordinate )
( draw 1bpp sprite with color 3 and 0 )
#03 .Screen/sprite DEO
#03 .Screen/sprite DEO
#0008 ADD2 ( increment x )
GTH2k ( is the width greater than x? aka is x less than the width ? )
,&loop-x JCN ( jump if x is less than the limit )
POP2 POP2 ( remove x and limit )
#0008 ADD2 ( increment y )
GTH2k ( is the limit greater than y? aka is y less than the limit ? )
,&loop-y JCN ( jump if y is less than the limit )
@ -318,9 +318,9 @@ that we can simply call from our initialization subroutine:
=> ./img/screenshot_uxn-background-full.png screenshot showing the varvara screen covered in diagonal lines except for a margin at the top and bottom.
nice!
nice!
in {uxn tutorial appendix a} you can find a detailed discussion of how to generalize a procedure like this one into a draw-tiles subroutine that draws an arbitrary rectangle filled with a given tile.
in {uxn tutorial appendix a} you can find a detailed discussion of how to generalize a procedure like this one into a draw-tiles subroutine that draws an arbitrary rectangle filled with a given tile.
it goes into several possibilities for using uxntal in that abstract way: i'd say it's very interesting, but it is definitely out of scope for making the game :)
@ -370,7 +370,7 @@ i drew the sprite using the blending mode 85 as indicated by nasu, but i will ch
### paddle drawing subroutine
let's build a subroutine that draws the 6 tiles of the paddle in the corresponding order.
let's build a subroutine that draws the 6 tiles of the paddle in the corresponding order.
we could have the subroutine receiving as arguments the x and y position of its top left corner:
@ -378,13 +378,13 @@ we could have the subroutine receiving as arguments the x and y position of its
@draw-paddle ( x^ y^ -- )
```
but let's add a color byte for the sprite byte as well:
but let's add a color byte for the sprite byte as well:
```
@draw-paddle ( x^ y^ color -- )
```
a reminder that we are using the convention of adding a caret (^) after the name of a value to indicate it's a short, and an asterisk (*) to indicate it's a short working as a pointer (i.e. an address in program memory)
a reminder that we are using the convention of adding a caret (^) after the name of a value to indicate it's a short, and an asterisk (*) to indicate it's a short working as a pointer (i.e. an address in program memory)
on one hand this second version would allow us to change colors when e.g. hitting the ball, but more importantly this will allow us to clear the paddle before moving it, as we have done in previous days.
@ -414,7 +414,7 @@ instead of subtracting we could recover x from the return stack, or from a relat
a possible advantage of going in order is that we can increment the address of the sprite by 10 (16 in decimal) to get to the address of the next tile. for this, and/or for the changes in coordinates, we can take advantage of the screen auto byte.
however, in this case i'll go for the first approach, and i'll manually set the address for each tile.
however, in this case i'll go for the first approach, and i'll manually set the address for each tile.
additionally, i'll save the color in the return stack:
@ -424,8 +424,8 @@ additionally, i'll save the color in the return stack:
STH
( set initial y and x )
.Screen/y DEO2
.Screen/x DEO2
.Screen/y DEO2
.Screen/x DEO2
( draw tile 0 )
;paddle/tile0 .Screen/addr DEO2
@ -470,7 +470,7 @@ additionally, i'll save the color in the return stack:
RTN
```
that's it!
that's it!
now we can call it in e.g. the following way and get our paddle drawn:
@ -508,7 +508,7 @@ we can have a couple of macros to hold the dimensions and color of the paddles i
```
%PADDLE-WIDTH { #0010 } ( 2 tiles )
%PADDLE-HEIGHT { #0018 } ( 3 tiles )
%PADDLE-COLOR { #c5 }
%PADDLE-COLOR { #c5 }
```
a margin to separate the paddles from the borders could be nice as well:
@ -576,12 +576,12 @@ omitting the definition of the draw-background and draw-paddle subroutines, and
( macros )
%RTN { JMP2r }
%HALF2 { #01 SFT2 } ( short -- short/2 )
%HALF2 { #01 SFT2 } ( short -- short/2 )
( constants )
%PADDLE-WIDTH { #0010 } ( 2 tiles )
%PADDLE-HEIGHT { #0018 } ( 3 tiles )
%PADDLE-COLOR { #c5 }
%PADDLE-COLOR { #c5 }
%MARGIN { #0010 }
%WALL-MARGIN { #0010 } ( margin at the top and bottom )
@ -602,7 +602,7 @@ omitting the definition of the draw-background and draw-paddle subroutines, and
;on-frame .Screen/vector DEO2
( draw background )
;draw-background JSR2
;draw-background JSR2
( initialize paddles )
MARGIN .left/x STZ2
@ -679,32 +679,32 @@ all of this can go inside its own subroutine for readability purposes:
.Controller/button DEI
DUP #10 AND ( check bit for up )
,&left-up JCN
DUP #20 AND ( check bit for down )
DUP #20 AND ( check bit for down )
,&left-down JCN
,&right JMP ( jump if neither of them were pressed )
&left-up
.left/y LDZ2 PADDLE-SPEED SUB2 .left/y STZ2
,&right JMP
.left/y LDZ2 PADDLE-SPEED SUB2 .left/y STZ2
,&right JMP
&left-down
.left/y LDZ2 PADDLE-SPEED ADD2 .left/y STZ2
,&right JMP
.left/y LDZ2 PADDLE-SPEED ADD2 .left/y STZ2
,&right JMP
&right
( right paddle: ctrl/A and alt/B buttons )
DUP #01 AND ( check bit for A )
,&right-up JCN
DUP #02 AND ( check bit for B )
DUP #02 AND ( check bit for B )
,&right-down JCN
,&end JMP ( jump if neither of them were pressed )
&right-up
.right/y LDZ2 PADDLE-SPEED SUB2 .right/y STZ2
,&end JMP
.right/y LDZ2 PADDLE-SPEED SUB2 .right/y STZ2
,&end JMP
&right-down
.right/y LDZ2 PADDLE-SPEED ADD2 .right/y STZ2
.right/y LDZ2 PADDLE-SPEED ADD2 .right/y STZ2
&end
POP ( pop duplicate value of button )
@ -713,7 +713,7 @@ RTN
### complete procedure
integrating everything, our on-frame subroutine would look like the following.
integrating everything, our on-frame subroutine would look like the following.
now we are able to move our paddles!
@ -724,7 +724,7 @@ now we are able to move our paddles!
.right/x LDZ2 .right/y LDZ2 CLEAR-COLOR ;draw-paddle JSR2
( update paddles )
;update-paddles JSR2
;update-paddles JSR2
( draw paddles )
.left/x LDZ2 .left/y LDZ2 PADDLE-COLOR ;draw-paddle JSR2
@ -732,7 +732,7 @@ now we are able to move our paddles!
BRK
```
note that we are able to move the paddles beyond the limits of the screen.
note that we are able to move the paddles beyond the limits of the screen.
i invite you to modify the update-paddles subroutine so that there's a limit in the paddles movement. in {uxn tutorial day 4} we discussed some possible strategies for achieving it :)
@ -767,7 +767,7 @@ we can define a couple of macros to refer to its parameters:
```
%BALL-SIZE { #0010 } ( 2 tiles per side )
%BALL-COLOR { #c5 }
%BALL-COLOR { #c5 }
```
### subroutine for drawing the ball
@ -790,7 +790,7 @@ HALF2
.ball/x STZ2
.Screen/height DEI2 BALL-SIZE SUB2
HALF2
HALF2
.ball/y STZ2
```
@ -807,28 +807,28 @@ let's have the subroutine receive the color as an argument, so that we can clear
( draw tile 0 )
;ball-sprite/tile0 .Screen/addr DEO2
( color byte was in the stack already )
DUP .Screen/sprite DEO
DUP .Screen/sprite DEO
( move right )
.Screen/x DEI2 #0008 ADD2 .Screen/x DEO2
( draw tile 1 )
;ball-sprite/tile1 .Screen/addr DEO2
DUP .Screen/sprite DEO
DUP .Screen/sprite DEO
( move down )
.Screen/y DEI2 #0008 ADD2 .Screen/y DEO2
( draw tile 3 )
;ball-sprite/tile3 .Screen/addr DEO2
DUP .Screen/sprite DEO
DUP .Screen/sprite DEO
( move left )
.Screen/x DEI2 #0008 SUB2 .Screen/x DEO2
( draw tile 2 )
;ball-sprite/tile2 .Screen/addr DEO2
.Screen/sprite DEO
.Screen/sprite DEO
RTN
```
@ -841,7 +841,7 @@ BALL-COLOR ;draw-ball JSR2
=> ./img/screenshot_uxn-pong-paddles-and-ball.png screenshot of the screen showing the paddles in their horizontal position but at different heights, and the ball completely centered in the screen.
## ball movement
## ball movement
for the movement of the ball, we'll follow the same structure as before:
@ -857,7 +857,7 @@ it would look something like the following, and it could sit along the equivalen
CLEAR-COLOR ;draw-ball JSR2
( update ball )
;update-ball JSR2
;update-ball JSR2
( draw ball )
BALL-COLOR ;draw-ball JSR2
@ -903,7 +903,7 @@ in order to move to the left, we might think that we should replace ADD2 with SU
but, to leave our code as it is now: is there a value of speed-x that will make x get smaller when adding them together?
in other contexts, one might say, "-1"!
in other contexts, one might say, "-1"!
but we haven't used negative signs here in uxn; we can't!
@ -952,7 +952,7 @@ to get other "negative numbers", let's observe the following: if we subtract 1 f
1 0000 0000 0000 0000: 0000
```
we get 0! fffe works effectively as "-2"!
we get 0! fffe works effectively as "-2"!
we could continue in that way getting more and more "negative" numbers that works thanks to the constrained size of computer memory.
@ -1067,7 +1067,7 @@ considering that there's a margin at the top, we can do this check as follows:
### bottom wall
here the procedure would be similar, but considering the size of the ball.
here the procedure would be similar, but considering the size of the ball.
we'd like to know if the y coordinate, plus the size of the ball, is greater than the y coordinate of the bottom wall.
@ -1077,13 +1077,13 @@ the y coordinate of the bottom wall would be the height of the screen, less the
(inside update ball )
&check-bottom-wall
.ball/y LDZ2 BALL-SIZE ADD2 ( y + ball size )
.Screen/height DEI2
.Screen/height DEI2
WALL-MARGIN SUB2 ( height - margin )
GTH2 ( is the ball-y greater than the wall-y? )
,&set-negative-speed JCN
,&continue JMP
&set-negative-speed
&set-negative-speed
BALL-NEGATIVE-SPEED .ball/speed-y STZ2
&continue
```
@ -1113,20 +1113,20 @@ our update-ball subroutine looks like the following right now:
LTH2 ( is ball-y less than the margin? )
,&set-positive-speed JCN
,&check-bottom-wall JMP
&set-positive-speed
BALL-POSITIVE-SPEED .ball/speed-y STZ2
,&continue JMP
&check-bottom-wall
.ball/y LDZ2 BALL-SIZE ADD2 ( y + ball size )
.Screen/height DEI2
.Screen/height DEI2
WALL-MARGIN SUB2 ( height - margin )
GTH2 ( is the ball y greater than the wall y? )
,&set-negative-speed JCN
,&continue JMP
&set-negative-speed
&set-negative-speed
BALL-NEGATIVE-SPEED .ball/speed-y STZ2
&continue
RTN
@ -1171,10 +1171,10 @@ if those two conditions are met, then we can set a positive speed for x:
```
( inside update-ball )
&x-in-left
.ball/y LDZ2 DUP2
.ball/y LDZ2 DUP2
.left/y LDZ2 BALL-SIZE SUB2 GTH2 ( first flag ) STH
.left/y LDZ2 PADDLE-HEIGHT ADD2 LTH2 ( second flag )
STHr ( retrieve first flag )
.left/y LDZ2 PADDLE-HEIGHT ADD2 LTH2 ( second flag )
STHr ( retrieve first flag )
AND ( AND the two flags together )
,&bounce-left JCN
```
@ -1196,10 +1196,10 @@ the whole x-in-left code would end up looking like:
```
( inside update-ball )
&x-in-left
.ball/y LDZ2 DUP2
.ball/y LDZ2 DUP2
.left/y LDZ2 BALL-SIZE SUB2 GTH2 ( first flag ) STH
.left/y LDZ2 PADDLE-HEIGHT ADD2 LTH2 ( second flag )
STHr ( retrieve first flag )
.left/y LDZ2 PADDLE-HEIGHT ADD2 LTH2 ( second flag )
STHr ( retrieve first flag )
AND ( AND the two flags together )
,&bounce-left JCN
@ -1223,7 +1223,7 @@ the whole x-in-left code would end up looking like:
this approach of comparing with 0000 is the easiest, but keep in mind that it might not work if you change the ball speed: it could happen that it crosses the wall but with an x coordinate that is never equal to 0.
we can't really check if the x coordinate is less than 0, because as we discussed above, that would actually be a number close to ffff.
we can't really check if the x coordinate is less than 0, because as we discussed above, that would actually be a number close to ffff.
if we checked for the x coordinate being less than ffff, then every possible value would turn on the comparison flag!
@ -1242,19 +1242,19 @@ for the right paddle we will do the same as above, but changing the comparisons
,&finish JMP
&x-in-right
.ball/y LDZ2 DUP2
.ball/y LDZ2 DUP2
.right/y LDZ2 BALL-SIZE SUB2 GTH2 ( first flag ) STH
.right/y LDZ2 PADDLE-HEIGHT ADD2 LTH2 ( second flag )
STHr ( retrieve first flag )
.right/y LDZ2 PADDLE-HEIGHT ADD2 LTH2 ( second flag )
STHr ( retrieve first flag )
AND ( AND the two flags together )
,&bounce-right JCN
.ball/x LDZ2
.ball/x LDZ2
.Screen/width DEI2 NEQ2 ( has it reached the wall ? )
,&finish JCN
,&finish JCN
&reset-right
( here you can increase the score
( here you can increase the score
of the left paddle )
;reset JSR2
,&finish JMP
@ -1300,7 +1300,7 @@ here's all of the code we wrote today!
( devices )
|00 @System [ &vector $2 &pad $6 &r $2 &g $2 &b $2 ]
|20 @Screen [ &vector $2 &width $2 &height $2 &auto $1 &pad $1
|20 @Screen [ &vector $2 &width $2 &height $2 &auto $1 &pad $1
&x $2 &y $2 &addr $2 &pixel $1 &sprite $1 ]
|80 @Controller [ &vector $2 &button $1 &key $1 ]
@ -1312,10 +1312,10 @@ here's all of the code we wrote today!
( constants )
%PADDLE-WIDTH { #0010 } ( 2 tiles )
%PADDLE-HEIGHT { #0018 } ( 3 tiles )
%PADDLE-COLOR { #c5 }
%PADDLE-COLOR { #c5 }
%PADDLE-SPEED { #0001 }
%BALL-SIZE { #0010 } ( 2 tiles )
%BALL-COLOR { #c5 }
%BALL-COLOR { #c5 }
%BALL-POSITIVE-SPEED { #0001 }
%BALL-NEGATIVE-SPEED { #ffff }
%CLEAR-COLOR { #40 }
@ -1340,7 +1340,7 @@ here's all of the code we wrote today!
;on-frame .Screen/vector DEO2
( draw background )
;draw-background JSR2
;draw-background JSR2
( initialize paddles )
MARGIN .left/x STZ2
@ -1375,10 +1375,10 @@ BRK
CLEAR-COLOR ;draw-ball JSR2
( update paddles )
;update-paddles JSR2
;update-paddles JSR2
( update ball )
;update-ball JSR2
;update-ball JSR2
( draw paddles )
.left/x LDZ2 .left/y LDZ2 PADDLE-COLOR ;draw-paddle JSR2
@ -1424,19 +1424,19 @@ RTN
LTH2 ( is ball-y less than the margin? )
,&set-positive-speed JCN
,&check-bottom-wall JMP
&set-positive-speed
BALL-POSITIVE-SPEED .ball/speed-y STZ2
,&continue JMP
&check-bottom-wall
.ball/y LDZ2 BALL-SIZE ADD2 ( y + ball size )
.Screen/height DEI2 WALL-MARGIN SUB2 ( height - margin )
GTH2
,&set-negative-speed JCN
,&continue JMP
&set-negative-speed
&set-negative-speed
BALL-NEGATIVE-SPEED .ball/speed-y STZ2
&continue
@ -1447,17 +1447,17 @@ RTN
LTH2 ( is ball-x less than the margin + paddle-width? )
,&x-in-left JCN
,&check-right-paddle JMP
&x-in-left
.ball/y LDZ2 DUP2
.ball/y LDZ2 DUP2
.left/y LDZ2 BALL-SIZE SUB2 GTH2 ( first flag ) STH
.left/y LDZ2 PADDLE-HEIGHT ADD2 LTH2 ( second flag )
STHr ( retrieve first flag )
.left/y LDZ2 PADDLE-HEIGHT ADD2 LTH2 ( second flag )
STHr ( retrieve first flag )
AND ( AND the two flags together )
,&bounce-left JCN
.ball/x LDZ2 #0000 NEQ2 ( has it reached the wall ? )
,&finish JCN
,&finish JCN
&reset-left
( here you can add a point to the right paddle )
@ -1474,18 +1474,18 @@ RTN
GTH2 ( is ball-x + ball-size greater than the screen width - margin - paddle-width? )
,&x-in-right JCN
,&finish JMP
&x-in-right
.ball/y LDZ2 DUP2
.ball/y LDZ2 DUP2
.right/y LDZ2 BALL-SIZE SUB2 GTH2 ( first flag ) STH
.right/y LDZ2 PADDLE-HEIGHT ADD2 LTH2 ( second flag )
STHr ( retrieve first flag )
.right/y LDZ2 PADDLE-HEIGHT ADD2 LTH2 ( second flag )
STHr ( retrieve first flag )
AND ( AND the two flags together )
,&bounce-right JCN
.ball/x LDZ2
.ball/x LDZ2
.Screen/width DEI2 NEQ2 ( has it reached the wall ? )
,&finish JCN
,&finish JCN
&reset-right
( here you can add a point to the left paddle )
@ -1511,28 +1511,28 @@ RTN
( draw tile 0 )
;ball-sprite/tile0 .Screen/addr DEO2
( color byte was in the stack already )
DUP .Screen/sprite DEO
DUP .Screen/sprite DEO
( move right )
.Screen/x DEI2 #0008 ADD2 .Screen/x DEO2
( draw tile 1 )
;ball-sprite/tile1 .Screen/addr DEO2
DUP .Screen/sprite DEO
DUP .Screen/sprite DEO
( move down )
.Screen/y DEI2 #0008 ADD2 .Screen/y DEO2
( draw tile 3 )
;ball-sprite/tile3 .Screen/addr DEO2
DUP .Screen/sprite DEO
DUP .Screen/sprite DEO
( move left )
.Screen/x DEI2 #0008 SUB2 .Screen/x DEO2
( draw tile 2 )
;ball-sprite/tile2 .Screen/addr DEO2
.Screen/sprite DEO
.Screen/sprite DEO
RTN
```
@ -1547,32 +1547,32 @@ RTN
.Controller/button DEI
DUP #10 AND ( check bit for up )
,&left-up JCN
DUP #20 AND ( check bit for down )
DUP #20 AND ( check bit for down )
,&left-down JCN
,&right JMP ( jump if neither of them were pressed )
&left-up
.left/y LDZ2 PADDLE-SPEED SUB2 .left/y STZ2
,&right JMP
.left/y LDZ2 PADDLE-SPEED SUB2 .left/y STZ2
,&right JMP
&left-down
.left/y LDZ2 PADDLE-SPEED ADD2 .left/y STZ2
,&right JMP
.left/y LDZ2 PADDLE-SPEED ADD2 .left/y STZ2
,&right JMP
&right
( right paddle: ctrl/A 01 and alt/B 02 buttons )
DUP #01 AND ( check bit for A )
,&right-up JCN
DUP #02 AND ( check bit for B )
DUP #02 AND ( check bit for B )
,&right-down JCN
,&end JMP ( jump if neither of them were pressed )
&right-up
.right/y LDZ2 PADDLE-SPEED SUB2 .right/y STZ2
,&end JMP
.right/y LDZ2 PADDLE-SPEED SUB2 .right/y STZ2
,&end JMP
&right-down
.right/y LDZ2 PADDLE-SPEED ADD2 .right/y STZ2
.right/y LDZ2 PADDLE-SPEED ADD2 .right/y STZ2
&end
POP ( pop duplicate value of button )
@ -1587,8 +1587,8 @@ RTN
STH
( set initial y and x )
.Screen/y DEO2
.Screen/x DEO2
.Screen/y DEO2
.Screen/x DEO2
( draw tile 0 )
;paddle-sprite/tile0 .Screen/addr DEO2
@ -1633,17 +1633,17 @@ RTN
RTN
```
## draw-background
## draw-background
```
@draw-background ( -- )
;tile-background .Screen/addr DEO2 ( set tile address )
.Screen/height DEI2 WALL-MARGIN SUB2 ( set limit )
WALL-MARGIN ( set initial y )
&loop-y
DUP2 .Screen/y DEO2 ( set y coordinate )
( draw row )
.Screen/width DEI2 #0000 ( set limit and initial x )
&loop-x
@ -1653,7 +1653,7 @@ RTN
GTH2k ( is the width greater than x? aka is x less than the width ? )
,&loop-x JCN ( jump if x is less than the limit )
POP2 POP2 ( remove x and limit )
#0008 ADD2 ( increment y )
GTH2k ( is the limit greater than y? aka is y less than the limit ? )
,&loop-y JCN ( jump if y is less than the limit )
@ -1703,7 +1703,7 @@ in {uxn tutorial day 7} we talk about the devices in the varvara computer that w
this should be a light and calm end of our journey, as it has to do less with programming logic and more with the input and output conventions in these devices.
first, i invite you to take a break!
first, i invite you to take a break!
then, keep exploring, and share your findings!

View File

@ -48,10 +48,10 @@ we can use a structure like the following, where the filename and reserved memor
#00ff .File/length DEO2 ( will attempt to read 255 bytes )
( set address for the data to read, and do read )
;file/data .File/read DEO2
;file/data .File/read DEO2
( check the success byte and jump accordingly )
.File/success DEI2 #0000 EQU2 ,&failed JCN
.File/success DEI2 #0000 EQU2 ,&failed JCN
&success
LIT 'Y .Console/write DEO
@ -61,7 +61,7 @@ we can use a structure like the following, where the filename and reserved memor
LIT 'N .Console/write DEO
RTN
@file
@file
&name "test.txt 00
&data $ff ( reserving 255 bytes for the data )
```
@ -72,7 +72,7 @@ in this example we are writing a character to the console according to the succe
also, in this example we are not really concerned with how many bytes were actually read: keep in mind that this information is stored in File/success until another read or write happens!
it's important to remember that, as always in this context, we are dealing with raw bytes.
it's important to remember that, as always in this context, we are dealing with raw bytes.
not only we can choose to treat these bytes as text characters, but also we can choose to use them as sprites, coordinates, dimensions, colors, etc!
@ -94,7 +94,7 @@ the following program will write "hello" and a newline (0a) into a file called "
#0006 .File/length DEO2 ( will attempt to write 6 bytes )
( set data starting address, and do write )
;file/data .File/write DEO2
;file/data .File/write DEO2
( read and evaluate success byte )
.File/success DEI2 #0006 NEQ2 ,&failed JCN
@ -107,7 +107,7 @@ the following program will write "hello" and a newline (0a) into a file called "
LIT 'N .Console/write DEO
RTN
@file
@file
&name "test.txt 00
&data "hello 0a
```
@ -136,10 +136,10 @@ we could adapt our previous subroutine in order to load the theme file and apply
#0006 .File/length DEO2 ( will attempt to read 6 bytes )
( set address for the data to read, and do read )
;theme/data .File/load DEO2
;theme/data .File/load DEO2
( check the success byte and jump accordingly )
.File/success DEI2 #0006 NEQ2 ,&failed JCN
.File/success DEI2 #0006 NEQ2 ,&failed JCN
&success
( set the system colors from the read data )
@ -151,7 +151,7 @@ we could adapt our previous subroutine in order to load the theme file and apply
&failed
RTN
@theme
@theme
&name ".theme 00
&data ( reserving 6 bytes for the data: )
&r $2 &g $2 &b $2
@ -172,12 +172,12 @@ and for doing the opposite operation, we can read the system colors into our res
;theme/name .File/name DEO2 ( set address of file path )
#0006 .File/length DEO2 ( will attempt to write 6 bytes )
( set address for the data and do write )
;theme/data .File/save DEO2
;theme/data .File/save DEO2
( check the success byte and jump accordingly )
.File/success DEI2 #0006 NEQ2 ,&failed JCN
.File/success DEI2 #0006 NEQ2 ,&failed JCN
&success
( report success? )
@ -350,11 +350,11 @@ the piano.tal example in the uxn repository, has several of them, all of them 25
and what do these numbers mean?
in the context of varvara, we can understand them as multiple unsigned bytes (u8) that correspond to amplitudes of the sound wave that compose the sample.
in the context of varvara, we can understand them as multiple unsigned bytes (u8) that correspond to amplitudes of the sound wave that compose the sample.
a "playhead" visits each of these numbers during a specific time, and uses them to set the amplitude of the sound wave.
the following images show the waveform of each one of these samples.
the following images show the waveform of each one of these samples.
when we loop these waveforms, we get a tone based on their shape!
@ -386,7 +386,7 @@ the frequency at which this sample is played (i.e. at which the wave amplitude t
the pitch byte makes the sample start playing whenever we write to it, similar to how the sprite byte performs the drawing of the sprite when we write to it.
the first 7 bits (from right to left) of the byte correspond to a midi note, and therefore to the frequency at which the sample will be played.
the first 7 bits (from right to left) of the byte correspond to a midi note, and therefore to the frequency at which the sample will be played.
the eighth bit is a flag: when it's 0 the sample will be looped, and when it's 1 the sample will be played only once.
@ -452,7 +452,7 @@ each of these transitions are done linearly.
in the ADSR short of the audio device, there is one nibble for each of the components: therefore each one can have a duration from 0 to f.
the units for these durations are 15ths of a second.
the units for these durations are 15ths of a second.
as an example, if the duration of the attack component is 'f', then it will last one second (15/15 of a second, in decimal).
@ -536,11 +536,11 @@ the output byte allows us to read the amplitude of the envelope. it returns 0 wh
the idea of having four audio devices is that we can have all of them playing at once, and each one can have a different sample, ADSR envelope, volume, and pitch.
this gives us many more possibilities:
this gives us many more possibilities:
maybe in a game there could be a melody playing in the background along with incidental sounds related to the gameplay?
maybe in a game there could be a melody playing in the background along with incidental sounds related to the gameplay?
maybe you can build a sequencer where you can control the four devices as different tracks?
maybe you can build a sequencer where you can control the four devices as different tracks?
or maybe you create a livecoding platform to have a dialog with each of the four instruments?
@ -550,7 +550,7 @@ in any case, don't hesitate to share what you create! :)
hey! believe it or not, this is the end!
you made it to the end of the tutorial series! congratulations!
you made it to the end of the tutorial series! congratulations!
i hope you enjoyed it and i hope you see it as just the start of your uxn journey!

View File

@ -11,7 +11,7 @@ that was because the on-screen debugger uses the screen device, and therefore ne
now that you have some system colors set, run your program and press the F2 key: you'll see several elements now!
=> ./img/screenshot_uxn-debugger.png screenshot of the on-screen debugger using the assigned system colors
* there are some lines and a crosshair in the center, drawn with color 2
* there are some lines and a crosshair in the center, drawn with color 2
* at the top left, there are four rows of eight bytes each, represented in hexadecimal and drawn with color 1; these 32 bytes show the deeper contents of the stack, with the stack "top" highlighted using color 2
* below, there is a single byte drawn with color 2: it corresponds to the address of the top of the return stack that we discuss on {uxn tutorial day 5}
* finally, there is another set of 32 bytes, drawn with color 3; these show the contents of the first section of the zero page in the main memory, discussed on {uxn tutorial day 4}
@ -24,14 +24,14 @@ take a look at the representation of the stack: if you didn't change the values
[2c] e5 0c
```
what are these numbers?
what are these numbers?
2ce5 is the short we assigned to the blue components of the system colors, and 0c is the i/o address of the short corresponding to .System/b ! (can you calculate and enumerate what are the numerical addresses of each of the color components in the system device?)
those values are the leftovers from the last operation on our program, the DEO2 that set the blue component of the system colors.
we can think of the highlight in the leftmost 2c, as an arrow pointing leftwards to the "top" of the stack. it current position implies that the stack is empty, as there are no more elements to its left.
note that the stack memory is not erased when taking elements out of it, what changes is the value of the address that points to its top.
# stack debugging test

View File

@ -17,4 +17,4 @@ sudo apt install arachne-pnr yosys iverilog gtkwave
# recursos
=> https://github.com/Obijuan/open-fpga-verilog-tutorial/wiki Diseño Digital para FPGAs, con herramientas libres
=> https://github.com/Obijuan/open-fpga-verilog-tutorial/wiki Diseño Digital para FPGAs, con herramientas libres