Arecibo message as simple art demo

Using, learning, programming and modding the Gigatron and anything related.
Forum rules
Be nice. No drama.
Post Reply
petersieg
Posts: 109
Joined: 28 Jun 2023, 09:06

Arecibo message as simple art demo

Post by petersieg »

I was inspired to show the arecibo message as a simple art demo with Gigatron.
Here is the first draft - feel free to alter it in your way ;-)

64k required due to string constant (maybe there is a better solution to this).

Original code from:
https://codegolf.stackexchange.com/ques ... bo-message
(see: [C++ (VC++)(but tested with gcc as well)], 585 bytes)

v0 contains plain console output
v1 first test version

Have fun,
Peter
Attachments
arecibo.zip
(12.71 KiB) Downloaded 103 times
arecibo.png
arecibo.png (59.59 KiB) Viewed 799 times
petersieg
Posts: 109
Joined: 28 Jun 2023, 09:06

Re: Arecibo message as simple art demo

Post by petersieg »

Just wanted to see, what code cost which amount of program size:

Code: Select all

-rw-r--r--  1 ich  staff  3160  6 Jan 17:27 arecibo64.gt1 - original size
-rw-r--r--  1 ich  staff  2283 10 Jan 19:41 arecibo64.gt1 - no use _console*
-rw-r--r--  1 ich  staff  1884 10 Jan 19:46 arecibo64.gt1 - no rand > SYS_Random
-rw-r--r--  1 ich  staff  1419 10 Jan 19:51 arecibo64.gt1z - compressed gt1z
What else could save some amount of code size?
The arecibo string is 360 bytes. 12 int variables = 24 bytes.
Is there is SYS_* for clearing the screen?

best, Peter
Attachments
arecibo.zip
(14.03 KiB) Downloaded 100 times
lb3361
Posts: 367
Joined: 17 Feb 2021, 23:07

Re: Arecibo message as simple art demo

Post by lb3361 »

The cheapest way to clear the screen is:

Code: Select all

    _console_clear((char*)0x800, 0x00,120);  /* 0x00 is the background color */
This calls SYS_SetMemory 120 times, one for each row of the screen. No dependencies.

You can add option --no-runtime-bss to save another 100 bytes or so.

Instead of "SYS_Random() % 64", try "SYS_Random() & 63" to avoid importing the division code.

You can also save some code by using a pointer (const char*) instead of an index (int) to scan the Arecibo string.

Finally, to make it work on a 32K gigatron, you need to split the string in pieces of about 92 bytes max. One way to do this is to have a code in the string that gives the address of the next one. To do this in C, you probably need to initialize the string like

Code: Select all

#define JUMPCODE '@'
#deifne hi(addr) (((int)(addr)&0xff00)>>8)
#define lo(addr) ((int)(addr)&0xff)
char part1[92] = { 'A', '0', ...    ,  JUMPCODE,lo(part2), hi(part2) };
char part2[92] = { .....  , JUMPCODE, lo(part2), hi(part2) };
char part3[92] = ....
and of course you need to handle JUMPCODE in your decoding routine. But since you no longer can use the convenient string syntax, you could just as well store 8 bits per byte, and use code 0x00 or any unused 8 bit combination as a jump code. Anyway, endless possibilities.
petersieg
Posts: 109
Joined: 28 Jun 2023, 09:06

Re: Arecibo message as simple art demo

Post by petersieg »

Many thanks for your suggestions!
Clear screen code is very helpful. Same for all other hints. Code size is now 1601 bytes and 1147 bytes compressed with clear screen again:

Code: Select all

-rw-r--r--  1 ich  staff  1601 11 Jan 14:16 arecibo64.gt1  - suggestions
-rw-r--r--  1 ich  staff  1147 11 Jan 14:22 arecibo64.gt1z - compressed gt1z
(No pointer and split string used)

To code the message in single bits, 1680 / 8 = 210 bytes are required. So would probably safe 150 bytes, depending on decode code size.

Thx, Peter
Attachments
arecibo.zip
(13.94 KiB) Downloaded 82 times
petersieg
Posts: 109
Joined: 28 Jun 2023, 09:06

Re: Arecibo message as simple art demo

Post by petersieg »

Just for further reference, this is the original 0+1 message:

Code: Select all

00000010101010000000000
00101000001010000000100
10001000100010010110010
10101010101010100100100
00000000000000000000000 - just 23 times 0
00000000000011000000000
00000000001101000000000
00000000001101000000000
00000000010101000000000
00000000011111000000000
00000000000000000000000 - just 23 times 0
11000011100011000011000
10000000000000110010000
11010001100011000011010
11111011111011111011111
00000000000000000000000 - just 23 times 0
00010000000000000000010
00000000000000000000000 - just 23 times 0
00001000000000000000001
11111000000000000011111
00000000000000000000000 - just 23 times 0
11000011000011100011000
10000000100000000010000
11010000110001110011010
11111011111011111011111
00000000000000000000000 - just 23 times 0
00010000001100000000010
00000000001100000000000
00001000001100000000001
11111000001100000011111
00000000001100000000000
00100000000100000000100
00010000001100000001000
00001100001100000010000
00000011000100001100000
00000000001100110000000
00000011000100001100000
00001100001100000010000
00010000001000000001000
00100000001100000000100
01000000001100000000100
01000000000100000001000
00100000001000000010000
00010000000000001100000
00001100000000110000000
00100011101011000000000
00100000001000000000000
00100000111110000000000
00100001011101001011011
00000010011100100111111
10111000011100000110111
00000000010100000111011
00100000010100000111111
00100000010100000110000
00100000110110000000000
00000000000000000000000 - just 23 times 0
00111000001000000000000
00111010100010101010101
00111000000000101010100
00000000000000101000000
00000000111110000000000
00000011111111100000000
00001110000000111000000
00011000000000001100000
00110100000000010110000
01100110000000110011000
01000101000001010001000
01000100100010010001000
00000100010100010000000
00000100001000010000000
00000100000000010000000
00000001001010000000000
01111001111101001111000
Length is 1679 bytes (or bits).
There are a 7 lines with just 23 times 0. If one would use '2' to put 23*'0' out, would safe 7*23=161-7=153 bytes.
3-9 could be number of '0' to output.

The beginning would then be:

Code: Select all

6101010190
0010151017100
13131310010110010
10101010101010100100100
2
93119
9011019
9011019
9101019
9111119
2
114111311411000
194110014
...
Hmm. Have to think about it, if this could result in a shorter string to decode..?
Edit: Just did a simple find & replace = 804 byte = a lot longer as with existing coding ;-)


best, Peter
lb3361
Posts: 367
Joined: 17 Feb 2021, 23:07

Re: Arecibo message as simple art demo

Post by lb3361 »

With 8 pixels per byte, each row is encoded on three bytes, meaning 73 * 3 = 219 bytes. There is a free bit in each row. So each row could be composed of a first byte in range 0-127 (7 pixels) and two bytes in range 0-255 (8 pixels each). One could code special situations by having a first byte in range 128 to 255. For instance a single 128 bytes could indicate a row of 23 zeroes (saving 7*2 = 14 bytes). Another code could be used to say that the data continues at another address (to split it into small segments for a 32k machine), and another could indicate the end of the image, eliminating the need to count the rows in the decoding program.
petersieg
Posts: 109
Joined: 28 Jun 2023, 09:06

Re: Arecibo message as simple art demo

Post by petersieg »

Now with arecibo message as bit array (3*79) unsigned chars each 8 bit.
--- arecibo msg as bit array:
-rw-r--r-- 1 ich staff 990 15 Feb 21:21 arecibo64.gt1
-rw-r--r-- 1 ich staff 987 15 Feb 21:25 arecibo64.gt1 - calc xpos just ones
-rw-r--r-- 1 ich staff 768 15 Feb 21:34 arecibo64.gt1z - compressed gt1z
The message itself is 3*79= 237 bytes. So still app. 750 bytes program logic.

As a side note: lcc does seem to not understand binary constants like 0b01010101?
Therefore, I had to write a little gcc program to convert to hex (see: test.c).

best, Peter
Attachments
arecibo2.zip
(10.31 KiB) Downloaded 63 times
lb3361
Posts: 367
Joined: 17 Feb 2021, 23:07

Re: Arecibo message as simple art demo

Post by lb3361 »

It turns out that binary constants are not in the C standard!
Yet GCC implements them and C++ requires them.
That's easy to add.
lb3361
Posts: 367
Joined: 17 Feb 2021, 23:07

Re: Arecibo message as simple art demo

Post by lb3361 »

Just added binary constants to the compiler.

I also added a map overlay "bare" to compile something that do not use libc at all and skip the overhead.
Such programs have to do everything by hand. There is still some stack management overhead
because C allows recursion. So to make a program very small, best is to do everything inside main.
arecibo_v4.gt1
(417 Bytes) Downloaded 67 times
arecibo3.zip
(2.33 KiB) Downloaded 53 times
petersieg
Posts: 109
Joined: 28 Jun 2023, 09:06

Re: Arecibo message as simple art demo

Post by petersieg »

Thats just great!

Thx, Peter
Post Reply