# x86 machine code (.COM file): <del>121</del> <del>120</del> 113 bytes Hexdump: 00000000 b4 3e bb 01 00 cd 21 b4 3c 31 c9 ba 40 01 cd 21 |.>....!.<1..@..!| 00000010 42 b4 09 cd 21 be 5a 01 81 fe 71 01 0f 84 e0 fe |B...!.Z...q.....| 00000020 8a 0c 46 e8 07 00 b1 32 e8 02 00 eb eb 88 cb c0 |..F....2........| 00000030 e3 07 c1 e1 04 30 d2 b4 02 00 da cd 21 e2 fa c3 |.....0......!...| 00000040 61 2e 73 6e 64 00 00 00 18 ff ff ff ff 00 00 00 |a.snd...........| 00000050 02 00 00 10 00 00 00 00 01 24 33 33 99 99 99 66 |.........$33...f| 00000060 99 99 99 99 99 66 33 99 99 99 99 66 33 33 33 33 |.....f3....f3333| 00000070 33 |3| Can be easily run under DosBox; the output is a .SND file named `a.snd`. [Here is a FLAC version][1] of its output (and [here][2] the .COM file). Commented assembly: org 100h start: ; close stdout mov ah,3eh mov bx,1 int 21h ; open a.snd mov ah,3ch xor cx,cx mov dx,filename int 21h ; write the header inc dx mov ah,9h int 21h mov si,data .l: ; data read cycle ; quit if we reached the end of data cmp si,eof je 0 ; read the current byte in cl (zero-extending to 16-bit) ; notice that ch is already zero (at the first iteration it's 0 from the ; int 21h/3ch, then we are coming from gen, which leaves cx to zero) mov cl,[si] ; move to next byte inc si ; generate the tone call gen ; generate the pause mov cl,50 call gen ; rinse and repeat jmp .l gen: ; generate a sawtooth wave at sampling frequency/2 Hz ; receives length (in samples>>4) in cx, with lowest bit indicating if ; it has to write a wave or a pause mov bl,cl ; shift the rightmost bit all the way to the left; this kills the ; unrelated data and puts a 128 in bl (if cx & 1 != 0) shl bl,7 ; rescale the samples number shl cx,4 ; zero the starting signal xor dl,dl ; prepare the stuff for int 21h mov ah,2h .l: ; increment the signal add dl,bl ; write it int 21h ; decrement iteration count and loop loop .l ret ; here be the data ; used for the file name; we recycle the .snd from the beginning ; of the file header, exploiting the fact that it comes just before a zero filename: db "a" header: ; .SND file header (8000 samples, mono, PCM) db ".snd",0,0,0,24,0xff,0xff,0xff,0xff,0,0,0,2,0,0,0x10,0,0,0,0,1 ; terminator for int 21h/ah=9h db '$' data: ; generated by gendata.py incbin "data.dat" eof: The `data.dat` included above is an easy-to-use representation of the morse string (lower bit: sound on/sound off, upper 7 bits: sound length in samples >> 4) generated by a Python script: #!/usr/bin/env python2 import sys # source string s = "..--- ----- .---- ....." # samples sr = 4096 conv = { '.': 1 | (((sr/5) >> 4) & ~1), # dot: 1/5 second, dI/dt=1 '-': 1 | (((sr/5*3) >> 4) & ~1), # line: 3/5 second, dI/dt=1 ' ': ((sr/5*2) >> 4) & ~1 # space: 2/5 second (+1/5 from the always-present pause), dI/dt=0 (silent) } sys.stdout.write(''.join(chr(conv[a]) for a in s)) [1]: https://bitbucket.org/mitalia/pcg/downloads/morse.flac [2]: https://bitbucket.org/mitalia/pcg/downloads/morse.com