En la Flashparty del año 2020, participé en la categoría 256 bytes combinados y mi programa o entry
compitió con otras producciones increíbles. En este artículo comento el código fuente en detalle
de la entry
original que originalmente tenía 27 bytes
, y al final un par de cambios para reducir el tamaño del programa aún más y una pequeña
modificación a la selección de colores para hacer el efecto más "dinámico" (?)
Aquí abajo está el video de la versión final
, reducida a 24 bytes
y con más colores locos
.
Sizecoding
Para dar una definición aproximada sobre que es el sizecoding
vamos a decir que es el arte
de crear programas lo más pequeños posibles para los tipos más populares de CPUs.
En particular, nos referimos a que esta categoría de programas tienen 256 bytes
o menos, creados
típicamente por miembros de la Demoscene como una manera de demostrar habilidad como programador.
El tamaño de estos pequeños programas se mide en el tamaño total de sus opcodes y generalmente
son ejecutables de la arquitectura objetivo: .COM
para MS-DOS
, PRGs
para Commodore 64
, etc…
FlashParty
Citando directamente al sitio de Flashparty: es un evento basado en el modelo Demoparty que tiene su origen en la sub-cultura de la Demoscene. La Demoscene es un movimiento artístico que usa tecnologías informáticas a nivel muy eficiente e ingenioso para la creación de piezas de arte: código, animaciones, música y gráficos. Una Demoparty es la reunión de artistas en un lugar físico para presentar sus obras y participar en competencias que se dirimen por votación del público presente.
La entry
Para obtener el zip
original enviado a la competencia, podés descargarlo de el siguiente link de scene.org.
A continuación, voy a mostarles el código fuente del mismo programa que envié, pero con muchísimos comentarios.
Con esto seteamos el modo de video en MS-DOS
en el Modo 13h
, de 320x200 con 256 colores
.
O sea, pasamos del modo normal del sistema operativo que es el modo texto a un modo gráfico para
poder empezar a dibujar algo.
Acá les dejo un link a la instrucción LES. En resumen, modificamos el segmento
ES
para que apunte a la memoria de video mapeada en A000:0000
. Pero en verdad estamos
haciendo un truco. Tradicionalmente esto se hace con las instrucciones push 0xa000
y pop es
.
Pusheamos en el stack
el segmento de memoria de la memoria de video y popeamos este valor
en el registro de segmento ES
. Estas instrucciones ocupan en total 4 bytes.
PUSH
ocupa un byte. El word 0xa000
ocupa 2 bytes, y pop es
ocupa un byte más, haciendo
el total de 4 bytes.
Para ahorrarnos un byte, usamos la instrucción LES, que escencialmente hace lo mismo, aprovechando
los valores de inicialización de registros en el momento que empieza a ejecutarse un programa en
MS-DOS. ES
en vez de valer 0xa000
va a valer un byte menos: 0x9fff
y todo lo que dibujemos
en la memoria de video va a estar offseteado por un byte. No es muy terrible, si tenemos esto
siempre en cuenta. El tradeoff es este offset de un byte para ganar un byte de espacio
en nuestro programa.
Con estas instrucciones lo que hacemos es lograr obtener la posición X
e Y
de la pantalla, avanzada por el puntero DI
que se incrementa cuando más tarde
en el programa usamos la instrucción stosb
.
De todas las cosas que se pueden dibujar en un espacio altamente reducido, hay un método llamado
el método AND del Triángulo de Sierpinski
. Prácticamente la instrucción que lo dibuja es and ax, dx
dentro del loop que
itera X e Y en el espacio de memoria.
Para obtener el dato del color a dibujar, usamos la posición de memora fs:046ch
que es donde
está el timer de MS-DOS, que nos da un valor incremental en cada iteración del loop. Para darle
variedad y que se pueda ver la diferencia entre el triángulo de Sierpinski y el fondo,
cambiamos el color del fondo sumando 127 bytes al registro AL
cuando and ax, dx
es igual a cero.
Optimizando la entry: A 24 bytes, con más colores!
Este programa es chiquito. Pero se puede hacer aún mas pequeño.
Removí las instrucciones para calcular X e Y e hice uso de una técnica llamada rrrola trick.
Para que haya más variación de colores, cambié la instrucción add al, 127
por xor al, dl
.
Es importante aclarar que al ahorrarnos estos 3 bytes con el rrrola trick, las coordenadas X e Y
son aproximadas y hay una deformación en el ploteo del Triángulo de Sierpinski
, por lo que no se
ve exactamente como la entry original. Hay como una especie de zoom in
medio feo, pero hey:
son 3 bytes menos! ;D
Referencias
- Sizecoding
- Flashparty
- Triángulo de Sierpinski: el método AND
- Demoscene
- Valores por defecto de los registros al ejecutarse un programa en
MS-DOS
- rrrola trick