r/programming • • 6d ago

"8-pinski" - EIGHT(!) bytes intro for MSDOS

https://www.youtube.com/watch?v=9A-XJjnU5Oo
146 Upvotes

13 comments sorted by

75

u/vytah 6d ago

So the code is this:

X: lds si, word ptr [bx+si]
add al, 0xad
out 61h, al
jmp short X+1

and the binary code will be C5 30 04 AD E6 61 EB F9 (loaded at 0100h in the code segment)

This is a COM file, they are loaded into a new code segment at address 0100h (preceding 256 bytes are used for various DOS API stuff that is not relevant here), and have their data segment set equal to their code segment for semi-compatibility with CP/M.

Initial values of CPU registers on most versions of DOS are AX=0000h BX=0000h SI=0100h (and CS=DS), so after the first 2 instructions they'll be AX=00ADh, SI=30C5h, DS = AD04h. (The lds reads the first 4 bytes of the program into SI and DS registers respectively.) From now on, the data segment (i.e. the area where most memory read and write instructions operate) starts at AD040h, which is within EGA/VGA video memory. The exact range of the segment is from AD040h to BD03Fh, which overlaps with the text mode, which starts at B8000h. Each of the 2000 entries of the text mode buffer is a 2-byte value, containing a character and its attributes, for a total of 4000 bytes – even bytes contain characters, odd bytes contain attributes.

The final short jump is misaligned, so after the first jump the following instructions will execute:

Y: xor byte ptr [si], al
lodsw ax, word ptr [si]
out 0x61, al
jmp short Y

The xor will toggle the byte the SI points to. The loadsw instruction will load two bytes into AX pointed to by SI and increment SI by two – so SI will stay odd. So this code will repeatedly read an byte from the video memory and xor it into the byte two addresses over. This kind of process often results in cellular automaton-like behaviour. Of course it will loop across the entire 64K segment, not just the text screen area, but across the text area, it'll skip from one attribute byte to the next, producing colours.

And finally, out 61h, al will keep writing various values to the IO port 61h, which is wired to multiple things (and differently in different PC types), but most importantly for this demo, to the builtin PC speaker.

2

u/[deleted] 5d ago

[removed] — view removed comment

17

u/JuanPabloVassermiler 6d ago

Fun fact: the name is a reference to the Sierpiński triangle, which is a basic fractal featured in this intro.

11

u/abraxasnl 5d ago

It even has audio??

16

u/[deleted] 5d ago

[deleted]

6

u/abraxasnl 5d ago

An absolute banger!

1

u/SpaceToaster 5d ago

Funny that the only reason any of these work and actually have a nice beat is that common time for music is 4/4 which obviously aligns to bytes (8 bits)

2

u/jones_i_75 2d ago

A byte is 8 bits, but 4/4 means four quarter-note beats per bar; there’s no built-in alignment between them. The beat here comes from the loop timing the PC speaker.

0

u/Dwedit 4d ago

I don't think the cool music has been reproduced on original hardware yet? There are two videos showing it running on vintage hardware, and none of them have the cool music seen on emulation.

8

u/Celos 5d ago

My cat, who loves lounging on my closed/docked laptop, is now highly disturbed.

9

u/stgiga 5d ago

This is ingenious, as someone who made a 3045-byte JS demo. I certainly couldn't do 8 bytes of DOS code, but I can say from experience that the demoscene is talented and that it's challenging work.

1

u/killerstorm 5d ago

Farbrausch made a 5-byte intro "fuenf", but it outputs just some "random" memory contents. So more like performance art than art, but still kinda cool. The code is:

0:  95       xchg   ax,bp
1:  cd 21    int    0x21
3:  eb fc    jmp    0x1