Arecibo message, surbroutines, and the COSMAC 1802


Last updated Sept 16 2014. (c) 2014 Herb Johnson See the linked Web page for more software to support the COSMAC 1802 and Lee Hart's "membership card".

In the "cosmacelf" Yahoo group for the 1802, on April 7th 2010, Steve Gemeny offered a bit of assembly code into their files archive called "arecibo". It blinks out the binary "Arecibo" message" sent by the Arecibo radio telescope back in 1974. The Q output, attached to an LED, does the job. The code was a little larger than 256 bytes. See Steve's code and further explanations in the Cosmacelf file archive under that name.

When asked for details, Steve posted: "I have my basic ELF sitting on the bookcase behind my desk, blinking away... When asked what it is, I answer, 'That's a 70's vintage interstellar communications system.' " When asked what's it doing, I answer 'sending a message from earth to M13 in the Taurus cluster', sometimes I pull out the graphic image and talk about what's in the message (Geek Alert!)."

Steve continued: "But if you are thinking of a receiver, remember there is no clock sent along with the data. That means the 0s have no transitions and there are quite a few of them. Timing would need to be rather tight unless differential encoding was added in the sending side. The easiest decoder might be to connect the Q to something a PC could sense and decode it on screen. That isn't my thing though".

"Another idea for improvement is squeezing some "air" out of the data and making the complete image fit into a quarter K. In the data format I chose there are 73 wasted bits... Squeeze them out and there is more room for data. 8 bytes down, 37 to go... That only leaves 36 Bytes for the code, could be tough."

"I'm interested to see if anyone else runs it on some other machine too.- Enjoy, Steve"

On April 10th, Dennis Boone got Steve's code down to 251 bytes. He said to me later: "Steve had to leave out part of the message due to space constraints. By bumming the code down (39 bytes) and storing the data more efficiently (210 bytes), I got all of it in. The tradeoff, of course, is some non-obvious shenanigans and the requirement that it run in page 0." Here's the assembled listing.

In response on May 2010, I saw one correction on Dennis' code, and how to add a clock to blinking the Q LED. The correction was on an extra branch (Dennis confirmed the fix.). Here's what Dennis does on toggling Q:


	(get bit)
	BNF WAIT ; If it's not 0...
	SEQ ; ...turn on the LED
WAIT:
	GHI 6 ; Handy spare 00 into D
SPIN:
	SMI 1 ; Waste some time subtracting 1
	BNZ SPIN
	REQ ; Turn off the LED
	(loop to get next bit)

This means the LED is off or on for long strings of consecutive 1's or 0's. It's possible to "lose count", and if your "signal" is lost you don't know if that's a run of zeros or not. In the signal trade we call that a lack of a "clock" signal. You want to send something all the time, if you want to "include" a clock.

A change to the clock code I came up with, is as follows:


	(get bit)
	BNF WAIT ; If it's not 0...
	SEQ ; ...turn on the LED 1/3 time if a 1
WAIT:
	GHI 6 ; Handy spare 00 into D
SPIN:
	SMI 1 ; Waste some time subtracting 1 from D
	BNZ SPIN ; LED is on or off 1/3 time

	SEQ ; ...turn on the LED 
SPIN2:
	SMI 1 ; 1/3 time with LED on 
	BNZ SPIN2

	REQ ; Turn off the LED
SPIN3:
	SMI 1 ; 1/3 time with LED ALWAYS off
	BNZ SPIN3

..so a 1 is when the LED is on 2/3 time, and a 0 is when the LED is on 1/3 time. So you always have a "signal". For Morse code enthusiasts, this is a series of "dits" and "dahs" (and space) for zero and one.

That's not hard to "detect" at the other end - measure the length of the pulses, and you'll see two kinds, "short" and "long". A simple timer set to a length between the "short" and "long" pulses will see a 1 or 0.

But I can't make my version's code "fit" the 256 byte space. The SMI 1/BNZ SPINx code is four bytes, it adds up! Is there a shorter way to make a timed loop? Can a coroutine save space? I'm not a good enough 1802 programmer to know, but it's so few bytes that most tricks don't seem to be productive.

Again, Dennis Boone responded on Sept 2 and produced this version which compressed my clocking scheme. I edited his code slightly to provide more explanation. Here's my edited version and also here's the assembled result and the hex file. One other difference between the two sources, is that I use R0 for the program counter - default after reset - while Dennis uses R3.

Dennis implemented a subroutine call/return to save space, among other tricks, as follows:

	;set R0 to program counter (reset)
	;load accumulator with SPININ address
	PLO 8 ;store SPININ addr in R8

;bit loop
	;set or reset Q depending on bit
	GHI 6 ; Handy spare 00 for accum
	SEP 8 ; Waste some time, "call" SPIN
	SEQ ; set Q
	SEP 8 ; Waste some time, "call" SPIN
	REQ ; reset Q
	SEP 8 ; Waste some time, "call" SPIN
	... loop and get more bits
	....

SPIN:   ;"called" with accum = 0 for max delay
	SMI 1  ; delay by decr accum
	BNZ SPIN
	SEP 0  ; "return" via R0 as PC; R8 -> next instruction
SPININ: ; Sub entry past end of subroutine
	BR SPIN 

The subroutine register R8 is set to the BR SPIN instruction at the END of the SPIN subroutine. Before the call, the accumulator is set to zero for the routine's use. The "call" consists of SEP-switching the PC to R8. Execution goes to the BR instruction, which runs the routine (decrement the accumulator through to zero). The end of the routine will SEP-switch the PC back to R0, which is already pointing past the prior "call" instruction. Likewise, R8 is pointing past the SEP 0 instruction back to...the BR SPIN instruction!

Dennis comments: "This goes back to the SCRT (System Call/Return Technique). Traditionally it's done in this order, I think:

RET:   SEP   0
FUNC:  ; do something useful here
       ;
       ;
       BR    RET

"Either way you reset the PC for this sub just before returning, but as you saw, I needed the entry to be 2 bytes before the data, so I flipped it over."

There's a few other tricks to gain a few more bytes. Look in Dennis code, or my edited version which I hope explains them correctly!

Herb Johnson

Other COSMAC work

[vcfmw]

Lee Hart in Aug-Sept 2014 built a NASA spacecraft model and put a Membership Card in it, "broadcasting" the Arecibo message. He exhibited it at VCFMW-9.0 in Chicago. Lee said: "By coincidence, the organizers of VCFMW had an "Arecibo challenge" contest at the door. How small a program can you write to send the message? We had that one NAILED with the Galileo model! Too bad there wasn't a prize."

But Dennis Boone corrected Lee: "No coincidence, and not really the organizers. The day before I left for Chicago, it dawned on me that we might be able to get some of the assorted hacker attendees to have a little fun, so I made up the flyers that were on the sign-in table. I also thought it would be nice to have a prize, but the last-minute nature of the thing left me no time to organize one. If anyone wants the PDF of the flyer, I'll make it available."

Herb is working on a low-power demo of the Membership Card, using the Arecibo message as a demonstrator. Since this implementation is small and needs no RAM, it's simple to run in a ROM only card.

Arecibo telescope and message

The Arecibo radio telescope is among the largest radio telescopes in the world. To celebrate an upgrade to the telescope, in 1974 a radio message was sent out. Here's some references for more information.

Prof. George Cassidy at the University of Utah explains the Arecibo message.linked with permission
"The Search for Life in the Universe" by Donald Goldsmith and Tobias Owen, has more information on SETI and the Arecibo message.
Web search engines will find more information, including some challenging interpretations.


Contact information:
Herb Johnson
New Jersey, USA

This page and edited content is copyright Herb Johnson (c) 2014. Contact Herb at www.retrotechnology.com, an email address is available on that page..