<?xml version="1.0" encoding="utf-8"?>
<feed version="0.3" xmlns="http://purl.org/atom/ns#">
<link rel="alternate" type="text/html" href="https://emergent.unpythonic.net/"/>

<title>Jeff Epler's blog</title>
<modified>2026-03-09T20:55:10Z</modified>
<tagline>Photos, electronics, cnc, and more</tagline>
<author><name>Jeff Epler</name><email>jepler@unpythonic.net</email></author>
<entry>
<title>radix40 encoding</title>
<issued>2026-03-09T20:55:10Z</issued>
<modified>2026-03-09T20:55:10Z</modified>
<id>https://emergent.unpythonic.net/01773089710</id>
<link rel="alternate" type="text/html" href="https://emergent.unpythonic.net/01773089710"/>
<content type="text/html" mode="escaped">



&lt;p&gt;&lt;br&gt;I was inspired to design an original(?) text encoding for tiny embedded
computers. It is, however, similar to &lt;a href=&quot;https://en.wikipedia.org/wiki/DEC_RADIX_50&quot;&gt;DEC RADIX 50&lt;/a&gt; from 1965. (That's 50₈=40₁₀).
Since 40³&amp;lt;65536, it is possible to store 3 symbols in each 16 bit word.

&lt;p&gt;In radix 40 you get the 26 basic alphabetic characters, 10 digits, and 4
additional symbols. I chose:
&lt;ul&gt;
&lt;li&gt;End of string
&lt;li&gt;Space (ASCII 32)
&lt;li&gt;Exclamation point (ASCII 33)
&lt;li&gt;Double quote (ASCII 34)
&lt;/ul&gt;

&lt;p&gt;The choice of 3 characters that are adjacent in ASCII saved code size on the
decoder; initially I thought maybe &amp;quot;-&amp;quot; and &amp;quot;.&amp;quot; would be useful choices.

&lt;p&gt;Unlike RADIX 50, the encoding is arranged so that no division or
remainder operation is needed. Instead, at each step of decoding, a
24 bit temporary value is multiplied by 40 and the top byte gives the
output code. In the assembler vesion, the multiplication is coded as 
&lt;tt&gt;x&lt;-x*8; tmp&lt;-x; x&lt;-x*4; x&lt;=x+tmp&lt;/tt&gt;) since the MC6800 has no multiply
instruction.

&lt;p&gt;Here are the not quite matching Python encoder
&lt;p&gt;(Embedded not available - View &lt;a href=&quot;https://codeberg.org/jepler/junkdrawer/src/commit/main/epvenhla/b40.py&quot;&gt;epvenhla/b40.py&lt;/a&gt; on codeberg.org or &lt;a href=&quot;https://codeberg.org/jepler/junkdrawer/raw/commit/main/epvenhla/b40.py&quot;&gt;download raw&lt;/a&gt;)&lt;/p&gt;
And decoder/test program in m6800 assembly:
&lt;p&gt;(Embedded not available - View &lt;a href=&quot;https://codeberg.org/jepler/junkdrawer/src/commit/main/epvenhla/b40.asm&quot;&gt;epvenhla/b40.asm&lt;/a&gt; on codeberg.org or &lt;a href=&quot;https://codeberg.org/jepler/junkdrawer/raw/commit/main/epvenhla/b40.asm&quot;&gt;download raw&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;The implementation costs 90 bytes of code and 6 bytes of zero-page (which can
be used for other purposes when the routine is not running). I estimate you'd
need somewhat above 320 characters of text in your program for it to be a benefit.

&lt;p&gt;The m6800 decoder can over-read the data by 1 byte, which seldom poses a problem in such environments.

&lt;p&gt;By the way, this post debuts improved code embeds from forgejo. On my end, I just have to write
&lt;tt&gt;[junk epvenhla/b40.py [lang python]]&lt;/tt&gt; and the blog renderer does the rest!

&lt;p&gt;</content>
</entry>
</feed>
