Device Equals ANSI Dot Sys

Click here to download the above image in android wallpaper format!

As a kid I figured out how to edit my father’s config.sys and autoexec.bat to change font colors in MS-DOS. Without the help from the internet, it was such a mysterious age where small technological discoveries were made based solely on trial and error, gossip, obscure scripts, tools and white papers spread on LAN parties and floppies.

The trick was to load the binary file ansi.sys using the DEVICE= directive in config.sys, enabling escape sequence interpretation to the standard output — which included means for changing the background and foreground font color on the command prompt.

I later installed Red Hat Linux 5.2 in 1998, but after a while I ended up compiling my own “distro” based on Linux from Scratch. My favourite nostalgic piece of memory is still my only ANSI art creation to date, namely my /etc/issue (image shown above), born based on piping and overlying Tux from Welcome2L (c) LittleIgloo.Org on a classical Windows 9x blue screen of death replica!

UPDATED 17/8-18: Added Android wallpaper version of BSOD Tux.

The Riddle

I was scanning through an old hard drive when I came across it. A large file of assembly code I had written many years ago. Its code section was tiny, but its data section huge.

Image credit:
Image credit:

It was my good old Linux audio player where the raw audio data was baked into the source itself. Or the other way around, a raw audio file with a built-in player. An interesting but sort of pathetic attempt to an executable audio file with no form of compression.

Skipping most of the data section (i.e. …), it looks like this:

; Minimalistic (or maximalistic?) Linux OSS audio player 
; by Geir K. Nilsen (2006)

dsp dd "/dev/dsp", 0
on  dd 1
fmt dd 0x00000010
sfr dd 44100
buf db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...

global _start 
        mov eax, 5	    ; Open DSP for read/write. System call
        mov ebx, dsp	    ; no 5. Set pointer to dsp string
        mov ecx, 02	    ; O_RDWR is defined to be 2 according
	int 0x80	    ; to asm/fcntl.h

			    ; File descriptor number now in eax.
	push eax            ; Take four copies for later system
	push eax            ; calls.
	push eax
	push eax
	push eax
			    ; OSS configuration
	mov eax, 54	    ; Set stereo, sys call ioctl is 54
	pop ebx
	mov ecx, 0xC0045003 ; See man ioctl_list, 
	mov edx, on         ; SNDCTL_DSP_STEREO
	int 0x80
	mov eax, 54	    ; Set format, 16 bit little endian
	pop ebx		    ; Format of buf is 8 bit, but 2-by-2
	mov ecx, 0xC0045005 ; samples are multiplexed to 16 bits
	mov edx, fmt        ; stereo samples.
	int 0x80

	mov eax, 54	    ; Set sampling frequency, 44100 Hz.
	pop ebx
	mov ecx, 0xC0045002
	mov edx, sfr
	int 0x80	
	mov eax, 4	    ; Prepare and write to DSP.
	pop ebx
	mov ecx, buf
	mov edx, 0x000AC440 
	int 0x80	    ; ..and play!

	mov eax, 6	    ; Close DSP. Sys call number 6.
	pop ebx
	int 0x80

	mov eax, 1	    ; Exit
	mov ebx, 0 
	int 0x80 

The file can be downloaded using the link (wait until loaded completely, then copy-paste into a plain text file):

I tried to recall what audio could be included in the file. Must boot up Linux to find the answer. Then assemble the file, and execute it. But I only have Windows on my laptop these days, so need to install it. This calls for WMware, or will it work under Cygwin? Heck, is OSS still supported by the kernel? And what assembler to use, Nasm? Or was it gas back then?

Wait, I will just parse and extract buf instead, the long string of comma-separated numbers. All the required information is provided by my comments: 16-bits samples, little endian, stereo (2 channels), sampling rate of 44100 Hz. Must be an easy job in Matlab using fscanf() and sound(). On the other hand, to recognize what will be played can turn out to be tricky. Given the file size and sampling rate, not so many audible seconds there will be. But Shazam can probably help, since I am quite sure it is a song.

I decided to challenge my team instead. They can solve my riddle outside normal working hours. Good learning for them it might be. Speaking about killing two birds with one stone.

Later the same night, me having forgotten all about the audio riddle, senior software engineer Øyvind Rørtveit sent out an e-mail containing just a short and incomprehensible sentence – “Blame it on me”. Yikes, what has he done now? I Will never blame it on you buddy, but come on, why so tight-lipped?

Øyvind is one of the best programmers I have ever known. He is like Mel,

The Story of Mel

but also with the ability to understand and translate complex mathematical concepts into working code. More about him sometime later.

I grabbed the phone and called him. I asked what was going on, and he said, “Isn’t it correct?” — “Correct what?”, I responded. “The riddle”, he said with a disappointed voice. But I was confused and struggled to find the harmony in all this.

It turned out that the brilliant riddle-maker had completely lost the solution to his own riddle, and that Øyvind had to convince him of the answer. “Yes! You are right!” — “But no, I know the answer and it isn’t this”, I said with a hint of despair, simultaneously not able to tell him the actual solution.

But he was right, and after listening to the whole song after we hung up, it again reminded me why I had chosen this song as the solution to the riddle.

Simply because the lady is a genius.