1 Punkte von GN⁺ 3 시간 전 | 1 Kommentare | Auf WhatsApp teilen
  • Wake up! 16b ist ein 16-Byte-x86-Real-Mode-DOS-Intro, das auf der Outline Demoparty vorgestellt wurde und gleichzeitig ein Sierpinski-Fraktal sowie Ton über den Textpuffer erzeugt
  • Mit int 10h und der Einstellung ds=0xb800 wird das Startbild des 40x25-Textmodus als Rechenraum genutzt, wobei Leerzeichen- und Farbattribute die Ausgabe beeinflussen
  • xor [si], al arbeitet wie eine Addition ohne Carry, erzeugt so die Sierpinski-Struktur von Bit 1 und sendet dasselbe Byte per out 61h, al an den PC-Lautsprecher
  • Die eigentliche Schleife bewegt sich pro Wiederholung um -56 Byte und wird nach 8.192 Schritten zurückgesetzt; der Ton sinkt um eine Oktave, und auf dem Bildschirm erscheint ein diagonal geschertes Muster in 10 Zeichenspalten
  • Laufzeitumgebungen wie der 0xB000-Patch für MDA/Hercules sowie Unterschiede bei BIOS- und RAM-Zustand verändern das Ergebnis, wodurch natürliche Hardware-Artefakte Teil des Sizecoding werden

Kernstruktur des 16-Byte-x86-Intros

  • Wake up! 16b ist ein 16-Byte-x86-Real-Mode-DOS-Assembler-Intro, das im Mai 2026 auf der Outline Demoparty im niederländischen Ommen vorgestellt wurde
  • Es verwendet den VGA/CGA-Textpuffer als Rechenraum, um ein unendliches Sierpinski-Fraktal auf dem Bildschirm zu erzeugen, und sendet dieselben Daten an den PC-Lautsprecher-Port, um Ton zu erzeugen
  • Der gesamte Code besteht aus 16 Byte
    int 10h          ; 2바이트
    mov bh, 0xb8     ; 2바이트
    mov ds, bx       ; 2바이트
    L:
    lodsb            ; 1바이트
    sub si, byte 57  ; 3바이트
    xor [si], al     ; 2바이트
    out 61h, al      ; 2바이트
    jmp short L      ; 2바이트
    
  • Im Entwicklungsprozess wurden zelluläre Automaten untersucht, die Grafik und Sound gemeinsam nutzen, außerdem polymorphe Assembler-Instruktionen, bei denen add [bx+si],al zu 0x0000 wird, sowie Sizecoding-Techniken, die Bytes und Opcodes durch Sprünge mitten in Instruktionen wiederverwenden
  • Die frühere Arbeit "M8trix" war ein 8-Byte- bzw. 7-Byte-Intro aus dem Jahr 2014, das pseudorandomisierte Zeichen über den Bildschirm ausbreitete; bei Wake up! 16b kommt zuerst der Ton, danach greift der visuelle Effekt ein

Der initialisierte Textbildschirm

  • int 10h setzt Videomodus 0 und erzeugt damit ein 40x25-Raster im Textmodus
  • mov bh, 0xb8 und mov ds, bx setzen das Datensegment ds auf die VGA/CGA-Textpufferadresse 0xb800
  • Wenn das BIOS den Bildschirm löscht, füllt es den Speicher nicht mit Nullen, sondern die 2.000 Zeichenslots mit dem Zeichenbyte 0x20 (Leerzeichen) und dem Farbattribut 0x07 (hellgrau auf schwarzem Hintergrund)
  • Der Bildschirm wirkt leer, aber im Speicher bleibt ein gleichmäßiges Muster erhalten, und dieser Anfangszustand beeinflusst Sound und visuelle Ausgabe
  • Auch Daten vor und hinter dem sichtbaren Videospeicher sowie die Art der Initialisierung nach „clear screen“ fließen in das Ergebnis ein und erzeugen einen raueren, eigenständigeren Klang als erwartet

Kumulierte Summen und Binomialstruktur

  • Betrachtet man nur die mathematische Struktur, kann man annehmen, dass der Zustand statt bei 0x20 bei 0 beginnt, dass statt xor ein add verwendet wird, dass in Schritten von 16 Byte vorgerückt wird und dass al bei 2 startet
  • Ein DOS-Segment umfasst exakt 65.536 Byte, und bei Schritten von 16 Byte benötigt man 4.096 Schritte, um das gesamte Segment zu durchlaufen
  • 4.096 ist ein Vielfaches von 256, also der Größe eines 8-Bit-Registers; dadurch richten sich Carryovers beim Wraparound des Segments aus, und zu Beginn jedes Sweeps kehrt al zu 2 zurück
  • Addiert man die Werte zwischen den Zellen fortlaufend, entsteht eine Partialsumme (prefix sum), und die Werte entfalten sich wie eine mit Faktor 2 skalierte Folge von Binomialkoeffizienten
  • Betrachtet man mehrere Durchläufe über die ersten 16 Zellen, akkumulieren sich die Werte zeilenweise; da es sich um 8-Bit-Werte handelt, wird alles oberhalb von 256 wieder umgebrochen und erscheint erneut als kleiner Wert

XOR und die Sierpinski-Struktur

  • Aufgrund kombinatorischer Eigenschaften modulo 2 erscheint das Sierpinski-Dreieck, und dieses Bit wird direkt an den PC-Lautsprecher ausgegeben
  • Auf Bitebene ist eine Addition ohne Carry ein XOR, deshalb verwendet der Code xor [si], al statt add
  • Der Startwert 2 entspricht binär 00000010, sodass nur Bit 1 zwischen 0x00 und 0x02 umgeschaltet wird
  • Dieses Muster entspricht dem elementaren zellulären Automaten Rule 60
  • Nach dem Satz von Lucas stimmt dieses Muster mit Bit 1 der Additions-Tabelle überein; in der Tabelle werden Positionen mit aktivem Bit 1 als 2 dargestellt

Wie Daten zu Klang werden

  • out 61h, al sendet das berechnete Byte an den mit dem PC-Lautsprecher verbundenen Port 61h
  • Bit 1 von Port 61h bestimmt, ob die Lautsprechermembran nach außen gedrückt oder nach innen gezogen wird
  • Der Code berechnet das Fraktal per XOR, schreibt das Ergebnis in den Speicher und sendet dasselbe Byte unmittelbar danach an den Lautsprecher-Port
  • Die Einsen und Nullen des Fraktals erzeugen eine Rechteckwelle (square wave) mit natürlich variierender Pulsbreite und Frequenz; zeilenweise abgespielt entsteht daraus ein selbstähnlicher, nahezu tempoinvarianter Bytebeat
  • In den ausgegebenen Klang mischt sich nicht nur der Textpuffer, sondern auch der Rest des 64-KB-Segments ein; durch den dort enthaltenen shadowed Video-ROM-BIOS-Code entsteht ein rauerer, funkigerer Sound als beim erwarteten, auf Sierpinski-Zeilen basierenden overlayed rectangle wave bytebeat

56-Byte-Schritt: Oktave und diagonale Scherung

  • Der eigentliche Code bewegt sich nicht in 16-Byte-Schritten, sondern durch die Kombination aus lodsb und sub si, byte 57 pro Wiederholung um -56 Byte zurück
  • Diese Schrittweite füllt den Bildschirm nur spärlich, hält aber zugleich den Soundpuffer davon ab, zu groß zu werden, und wird genutzt, um einen visuellen Effekt ähnlich wie bei M8trix zu reproduzieren
  • Audio

    • 56 teilt 65.536 nicht ohne Rest
    • Der Code besucht nur Offsets, die Vielfache von 8 sind, und setzt sich erst nach 8.192 Schritten sowie 7 Wraparounds zurück
    • Durch die verdoppelte Zykluslänge sinkt die Grundfrequenz auf die Hälfte, der Ton fällt also um eine Oktave
  • Visuals

    • Auf einem Bildschirm mit 80 Byte Breite entspricht ein Sprung von -56 Byte einem Vorwärtssprung um 24 Byte, also einer Verschiebung um 12 Spalten
    • Es werden nur 10 verschiedene Spalten besucht
    • Das Fraktal erscheint daher nicht als geschlossenes Bild, sondern diagonal geschert in 10 Zeichenspalten, die sich nach oben über den Bildschirm bewegen
    • Das eigentliche Dreieck ist 8.192 „Pixel“ breit, eine Bildschirmzeile umfasst aber nur 80 Byte, sodass die Bewegung zwar wahrnehmbar ist, die Gesamtstruktur jedoch kaum direkt sichtbar wird
    • Würde man ohne ausgelassene Pixel auf einmal zeichnen oder einen deutlich größeren Bildschirm verwenden, ließe sich das Dreieck erkennen

Ausführung auf echter Hardware

  • Der Scener miragept führte es auf echter Hardware aus und patchte die Adresse von 0xB800 auf das von MDA verwendete 0xB000, um grünen Text passend für MDA/Hercules zu erhalten
  • Die verwendete Maschine war kein exakter IBM-Rechner, sondern ein 286er mit EGA-Karte, die MDA/Hercules emulieren konnte, zusammen mit einem echten MDA-Monitor
  • Im aufgenommenen Audio mischt sich dauerhaftes Rauschen der Maschine ein, und der IBM-5151-Monitor besitzt langes Phosphor-Nachleuchten, was für extrem schnelle Darstellung nachteilig ist
  • Durch die Änderung des Adressbytes klang der Ton etwas anders, funktionierte aber wie beabsichtigt; im späteren Teil ist die Sierpinski-Struktur sogar besser sichtbar als in der Originalversion
  • Je nach Emulator und BIOS-Version unterscheiden sich die im RAM verbleibenden Artefakte, und da der Code XOR auf diesen Speicherzustand anwendet, reagiert die Ausgabe empfindlich auf die Laufzeitumgebung
  • Man könnte den Speicher vorher löschen, um eine gleichmäßigere Ausgabe zu erhalten, doch dafür wären zusätzliche Bytes nötig; gerade das Akzeptieren des natürlichen Hardwarezustands bleibt ein Reiz des Sizecoding

Weiterführendes Material

1 Kommentare

 
GN⁺ 3 시간 전
Hacker-News-Kommentare
  • Ich bin dem hier gefolgt und in einem einstündigen Rabbit Hole verschwunden, an dessen Ende ich mir sogar ein Video angesehen habe, in dem zwei Leute mit einer rekursiven PowerPoint-Präsentation ein Sierpinski-Dreieck erzeugen
    https://youtu.be/b-Fa6HtvGtQ?si=LpQszgA9_K-m3V3-
    • Matt Parker und Steve Mould gehören auf YouTube zu den besten STEM-Bildnern
      Beide sind witzig und experimentierfreudig. Parker ist stärker in der klassischen Mathematik verankert, während Mould fachübergreifend unterwegs ist und den Drang nach Experimenten/DIY perfekt bedient
      Wenn dir dieses Video gefällt, kann ich nur dringend empfehlen, auch die beiden Kanäle anzuschauen
      https://www.youtube.com/@standupmaths
      https://www.youtube.com/@SteveMould
  • Früher dachte ich ernsthaft, die 32-Byte-Demo, die ich einmal gesehen habe, sei die Grenze dafür, wie klein man ein Binary machen und es trotzdem noch ansehnlich halten kann
    Diese Demo hatte nicht einmal Ton
    Das hier ist wirklich eine gewaltige Arbeit und ein Meisterwerk, das man als Abschlusswerk nehmen könnte. Realistischer ist aber wohl, dass es auf einer anderen Architektur wieder weitergeht
  • Wenn ich solchen extrem kleinen generativen Code sehe, möchte ich nur „Hexe!“ rufen
    Bravo
  • Von den verlinkten Demos hat mich rainbow surf völlig in den Bann gezogen
    https://www.youtube.com/watch?v=QKLhH_ANwIc
    • Das ist von der Person, die "wake up" gemacht hat. Ja, genau diese Demo hat mich wieder aktiv werden lassen
      Unsere Size-Coding-Community dachte, wir hätten die Tricks mit zellulären Automaten schon vor Jahren alle entdeckt, aber dann kam Plex und hat gezeigt, dass das nicht stimmt ♥
  • Wirklich großartig
    Ich weiß nicht, ob es einen Artikel über den Vorgänger namens m8trix gab, aber ich habe ihn mir damals, als er herauskam, 2014 einmal genauer angesehen: https://scot.tg/2014/05/31/amazing-code-density/
  • Solche großartigen Schöpfungen sind der Grund, warum uns Technologie begeistert
  • Zuerst dachte ich, das sei kein 16-Byte-Demo, sondern ein LLM mit 16B Parametern
    • Dachte ich auch. Aber das hier ist viel cooler
    • Ein Unterschied von neun Größenordnungen
  • Ich bin wirklich beeindruckt. Solche Dinge sind der Grund, warum ich Programmierung und Computing liebe
    Das alles ist so schön, echte Kunst. Schade, dass man in der Branche bei all dem AI-Zeug normalerweise kaum Gelegenheit bekommt, so etwas zu bauen
    • Wenn es mit Electron gemacht wäre, wären es wahrscheinlich 300 MB Download und ungefähr 1 GB RAM-Verbrauch
  • Ich versuche immer noch zu begreifen, dass das überhaupt möglich ist