IchigoJamで機械語プログラムを作っていますが、POKE文で記述しているとプログラムの容量不足に陥ります。
例えば、「ret」文の記述に「POKE#700,#70,#47」となり、2byteを記述するために「POKE#700」を引いても、8byte必要になります。
16進数ではなく、10進数にすれば少しは文字数節約になりますが、 それもたかが知れています。
(,#70,#47→,112,71 =7byte)

また、作った機械語プログラムをネットや雑誌への公開する時に、バイナリファイルで公開するのも悩ましいところです。
ネットではD/Lした人にバイナリ転送の知識が必要になるし、 雑誌では不可能に近いと思います。

そこで、エンコード方法の一つである"BASE64"を参考に、"BASE16"エンコードを考えました。
理屈は簡単で、 1byteを上位4bitと下位4bitに分けて、それぞれ「@~O」のキャラクタに割り当てます。
ret → #70,#47 → G@DG=4byte となります。

base64(6bit区切りでのエンコード)よりエンコード後の文字数が多くなりますが、プログラムを実装する際に小さくできるので、結果的にメモリの節約になると思います。



プログラムにすると下記のようになります。

BASE16_encode
機械語プログラムが、#700以後にある場合
10 for i=#700to#740
20 a=peek(i):?chr$(64+(a>>4));chr$(64+(a&#f));
30 next:end

BASE16_decode
#C04以後にある文字列を、#700以後にエンコードする場合
10 for i=0to#10
20 poke#700+i,(peek(#c04+i*2)-64)<<4+peek(#c05+i*2)-64
30 next:end

エンコードは、まずPOKE文等でメモリ内に機械語プログラムを記述した後に、上記プログラムを実行すると「@~O」の文字にエンコードされた文字列が表示されますので、頭に行番号を付けてプログラムリスト化するなりしてください。



これを実装したサンプルプログラムが下記になります。

機械語部分は、ただの逆スクロールですが、宇宙船のみスクロールせず現位置にとどまります。
衝突判定はしていません。
テンキーの1と3で左右に移動です。(一応、他のキーも使えますが…)

エンコード無し(16進)
10 poke #700,#0b,#22,#12,#02,#df,#32,#50,#18,#20,#30,#03,#78,#f0,#2b,#05,#d0,#20,#38,#03,#78,#f0,#2b,#01,#d0,#20,#30,#03,#70,#01,#3a,#10,#0a
20 poke #720,#08,#28,#f0,#d1,#52,#18,#01,#20,#00,#23,#13,#54,#01,#30,#21,#28,#fb,#d1,#70,#47
80 cls:x=15
90 lc x,15:?chr$(#f0)
100 k=inkey()
110 if k!=0 then lcx,15:?" ":x=x+((k-1)%3-1)
120 lc rnd(33),0:?"*"
130 a=usr(#700,0)
140 goto90

free()=646byte

エンコード無し(10進)
10 POKE#700,11,34,18,2,223,50,80,24,32,48,3,120,240,43,5,208,32,56,3,120,240,43,1,208,32,48,3,112,1,58,16,10
20 POKE#720,8,40,240,209,82,24,1,32,0,35,19,84,1,48,33,40,251,209,112,71,214,16,56,0,16,56,124,254,124,56,16,0,60
80 cls:x=15
90 lc x,15:?chr$(#f0)
100 k=inkey()
110 if k!=0 then lcx,15:?" ":x=x+((k-1)%3-1)
120 lc rnd(33),0:?"*"
130 a=usr(#700,0)
140 goto90

free()=658byte

BASE16 エンコード
1'@KBBAB@BMOCBE@AHB@C@@CGHO@BK@EM@B@CH@CGHO@BK@AM@B@C@@CG@@ACJA@@J@HBHO@MAEBAH@AB@@@BCACED@AC@BABHOKMAG@DG
10 fori=0to#33:poke#700+i,peek(#c05+i*2)+peek(#c04+i*2)*16-1088:next

80 cls:x=15
90 lcx,15:?chr$(#f0)
100 k=inkey()
110 if k!=0 then lcx,15:?" ":x=x+((k-1)%3-1)
120 lc rnd(33),0:?"*"
130 a=usr(#700,0)
140 goto90
free()=702byte

機械語ルーチン
r2=#b
r2=r2<<8
r2+=#DF
@LBL1
r0=r2+r1
r0+=#20
r3=[r0+0]
r3-#f0
if 0 goto @LBL2
r0-=#20
r3=[r0+0]
r3-#f0
if 0 goto @LBL2
r0+=#20
[r0+0]=r3
@LBL2
r2-=1
r0=r2>>8
r0-8
if !0 goto @LBL1
r2=r2+r1
r0=1
r3=0
@LBL3
[r2+r0]=r3
r0+=1
r0-#21
if !0 goto @LBL3
ret



この程度(52byte)の機械語プログラムですら、デコードのプログラムを実装しても、40byte以上の節約になりました。

上記はBASE16デコード部の式を展開し、さらに省メモリ化して書いています。

上記はコメント文に機械語プログラムを記述しています。
1行で済む機械語ルーチンなのでデコード部分が簡単になってますが、機械語プログラムが複数行に渡るような大作(笑)の場合は、デコード部分に工夫が必要になります。