Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

tiny DOS Befunge93 interpreter (1024 bytes)

7 views
Skip to first unread message

Rugxulo

unread,
Nov 9, 2009, 11:28:11 PM11/9/09
to
(Sorry if this is a re-post, I don't see it)

Anybody familiar with Befunge93? Check here:

http://www.catseye.tc/projects/bef/
http://en.wikipedia.org/wiki/Befunge
http://board.flatassembler.net/topic.php?t=10599

Anyways, it's an esoteric language, only 26 commands (plus the numeric
digits), typically limited to 80x25 in size (e.g. one small screen of
code). Standard interpreter is in C, yet it's too big once compiled
for my tastes.

Well, I hacked up a pre-existing one (written in pieces by both Ryan
Kusnery and Ben Olmstead), converted it from TASM, and shrank it a
lot. It's still got some obscure bugs, though (annoying). I might also
eventually try porting Pinecone_'s Win32 asm console version to DOS if
I can figure out where it expects what, etc. for comparison (HX as-is
only halfway correctly runs it, argh).

1024 bytes uncompressed (original TASM version was 1280) with a few
very tiny extras (386 check, LFN support, fixed a few bugs). It can
assemble with FASM or (via sed via MAKE.BAT) NASM, YASM, OCTASM, or
DJASM. I left two previous .ASM sources in there too (1213-byte FASM
version and the original TASM source plus .COM) for comparison
(bugchecking).

http://board.flatassembler.net/topic.php?t=10810
http://rugxulo.googlepages.com/befi_2i.zip

Ideas: fix all bugs, maybe convert to be fully 8086 compatible, etc.
etc.

P.S. It works everywhere I tried except XUbuntu 8.04.1 x86-64 under
DOSEMU (probably a bug in their 16-bit emulation, most other DOS stuff
works fine there).

Alexei A. Frounze

unread,
Nov 10, 2009, 12:39:09 AM11/10/09
to
On Nov 9, 8:28 pm, Rugxulo <rugx...@gmail.com> wrote:
> (Sorry if this is a re-post, I don't see it)
>
> Anybody familiar with Befunge93? Check here:
>
> http://www.catseye.tc/projects/bef/http://en.wikipedia.org/wiki/Befungehttp://board.flatassembler.net/topic.php?t=10599

>
> Anyways, it's an esoteric language, only 26 commands (plus the numeric
> digits), typically limited to 80x25 in size (e.g. one small screen of
> code). Standard interpreter is in C, yet it's too big once compiled
> for my tastes.
>
> Well, I hacked up a pre-existing one (written in pieces by both Ryan
> Kusnery and Ben Olmstead), converted it from TASM, and shrank it a
> lot. It's still got some obscure bugs, though (annoying). I might also
> eventually try porting Pinecone_'s Win32 asm console version to DOS if
> I can figure out where it expects what, etc. for comparison (HX as-is
> only halfway correctly runs it, argh).
>
> 1024 bytes uncompressed (original TASM version was 1280) with a few
> very tiny extras (386 check, LFN support, fixed a few bugs). It can
> assemble with FASM or (via sed via MAKE.BAT) NASM, YASM, OCTASM, or
> DJASM. I left two previous .ASM sources in there too (1213-byte FASM
> version and the original TASM source plus .COM) for comparison
> (bugchecking).
>
> http://board.flatassembler.net/topic.php?t=10810http://rugxulo.googlepages.com/befi_2i.zip

>
> Ideas:  fix all bugs, maybe convert to be fully 8086 compatible, etc.
> etc.
>
> P.S. It works everywhere I tried except XUbuntu 8.04.1 x86-64 under
> DOSEMU (probably a bug in their 16-bit emulation, most other DOS stuff
> works fine there).

http://en.wikipedia.org/wiki/Brainfuck would be more compact. :)

Alex

Herbert Kleebauer

unread,
Nov 10, 2009, 4:35:58 AM11/10/09
to
"Alexei A. Frounze" wrote:
> On Nov 9, 8:28 pm, Rugxulo <rugx...@gmail.com> wrote:

> > Well, I hacked up a pre-existing one (written in pieces by both Ryan
> > Kusnery and Ben Olmstead), converted it from TASM, and shrank it a
> > lot.

> > 1024 bytes uncompressed (original TASM version was 1280) with a few


> > very tiny extras (386 check, LFN support, fixed a few bugs). It can

> http://en.wikipedia.org/wiki/Brainfuck would be more compact. :)

How about a complete virtual machine with an embedded assembler in
500 byte:


run.com is a simple 16 bit Virtual Machine which can address 32k 16 bit
words (=64 kbyte) and a 32k 16 bit word stack. A program executed in the
VM can only write to stdout and stderr and read from stdin and (if
present) from the file run.dat. There is no other way to communicate
with the operating system and therefore a program executed in the VM
cannot harm the system in any way.

The VM only supports 5 instructions:

15 14 0
+-+---------------------+
|0| addr | jump to addr if flag is clear
+-+---------------------+ clear flag


15 14 0
+-+---------------------+
|1| addr1 | add content of address addr1
+-+---------------------+ to content of address addr2
|0| addr2 | and store result in addr3
+-+---------------------+ set flag if the add generates a carry
|0| addr3 | clear flag if the add generates no carry
+-+---------------------+


15 14 0
+-+---------------------+
|1| addr1 | sub content of address addr1
+-+---------------------+ from content of address addr2
|0| addr2 | and store result in addr3
+-+---------------------+ set flag if the result is zero
|1| addr3 | clear flag if the result is not zero
+-+---------------------+


15 14 0
+-+---------------------+
|1| addr1 | and content of address addr1
+-+---------------------+ to content of address addr2
|1| addr2 | and store result in addr3
+-+---------------------+ set flag if the result is zero
|0| addr3 | clear flag if the result is not zero
+-+---------------------+


15 14 0
+-+---------------------+
|1| addr1 | or content of address addr1
+-+---------------------+ to content of address addr2
|1| addr2 | and store result in addr3
+-+---------------------+ set flag if the result is zero
|1| addr3 | clear flag if the result is not zero
+-+---------------------+


A write to memory address 0x7fff (0x7ffe) writes the least significant
byte to stdout (stderr). If a 0xffff (EOF) is written to 0x7fff (0x7ffe)
the program terminates with error level 1 (2). A memory read from
address 0x7fff (0x7ffe) reads the next byte from stdin (run.dat).
If the end of file is reached, a 0xffff is read.

A write to 0x7ffd pushes a word onto the stack and a read from
0x7ffd pops a word from the stack. After program start, the
command line is on the stack, terminated by an EOF (0xffff).

-----------------------------------------------------------------------


A program for the VM is written in a simple assembler syntax.
The assembler is part of the VM. An assembler program is a
sequence of 16 bit hex numbers followed by one of the 6
characters :+-#=* . Any characters after a ; till the end of line
is ignored. Any character other than 0123456789abcdefABCDEF:+-#;=*
is ignored.

hexnr: the label with the number hexnr is assigned the current
location counter. You can use 32k labels numbered from
0 to 0x7fff. The values assigned to a label are also in
the range of 0 to 0x7fff.

hexnr- the value of the label with the number hexnr
is written into memory at the current location counter

hexnr+ 0x8000 + the value of the label with the number hexnr
is written into memory at the current location counter

hexnr# hexnr is written into memory at the current location counter

hexnr= hexnr is written into the current location counter

hexnr* hexnr is added to the current location counter

-----------------------------------------------------------------------

example:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; u2d.run ;
; usage: run u2d.run <unixfile >dosfile ;
; ;
; converts a UNIX text file to a DOS text file ;
; by replacing any <LF> by <CR><LF> ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

f100: c0+ 7fff# d1- ; move stdin,d1
c1+ d1- d2+ ; cmp #$0a,d1
f101- ; bne f101
c0+ c2- 7fff# ; move #$0d,stdout
f101: c0+ d1- 7fff# ; move d1,stdout
f100- ; br f100

c0: 0000#
c1: 000a#
c2: 000d#
d1: 0000#
d2: 0000#
d3: 0000#


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; d2u.run ;
; usage: run d2u.run <dosfile >unixfile ;
; ;
; converts a DOS text file to a UNIX text file ;
; by removing any <CR> ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

f100: c0+ 7fff# d1- ; move stdin,d1
c2+ d1- d2+ ; cmp #$0d,d1
f101- f100- ; beq f100
f101: c0+ d1- 7fff# ; move d1,stdout
f100- ; br f100

c0: 0000#
c2: 000d#
d1: 0000#
d2: 0000#
d3: 0000#


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; tee.run ;
; usage: run tee.run ;
; ;
; copy stdin to stdout and stderr ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

f100: c0+ 7fff# d1- ; move stdin,d1
c0+ d1- 7fff# ; move d1,stdout
c0+ d1- 7ffe# ; move d1,stderr
f100- ; br f100

c0: 0000#
d1: 0000#


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; echo.run ;
; usage: run echo.run text ;
; ;
; echo text to stdout, no <cr><lf> is appended ;
; text can include any binary character by using ;
; it's hex form preceded by a $. ;
; ;
; example: run echo.run hello $3c$3e$0d$0a ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

f100: c0+ 7ffd# d1- ; move cmdline,d1
c2+ d1- d2- ; cmp #$20,d1
f100- ; bls f100

f102: c0+ 7ffd# d1- ; move cmdline,d1
c1+ d1- d2+ ; cmp #$ffff,d1
f103- f104- ; beq f104
f103: c2+ d1- d2- ; cmp #$20,d1
f101- f102- ; bhi f102


f101: c0+ 7ffd# d1- ; move cmdline,d1
c3+ d1- d2+ ; cmp #'$',d1
f104- f105- ; beq f105
f104: c0+ d1- 7fff# ; move d1,stdout
f101- ; br f101

f105: c0+ b0- 7ffd# ; push #f106
f200- ; jsr f200
f106: c0+ b1- 7ffd# ; push #f104
f200- ; jsr f200

f200: c0+ 7ffd# f203- ; move retadr,f203
d1+ d1- d1- ; lsl d1
d1+ d1- d1- ; lsl d1
d1+ d1- d1- ; lsl d1
d1+ d1- d1- ; lsl d1
f201: c0+ 7ffd# d3- ; move cmdline,d3
c4+ d3- d2- ; cmp #'0',d3
f201- ; blo f201
c5+ d3- d2- ; cmp #'9',d3
f202- ; bls f202
c7+ d3+ d3+ ; or #$20,d3 (A-z -> a-z)
c8+ d3- d3+ ; sub #'a'-10-'0',d3
f202: c6+ d3- d2+ ; sub #'0',d3,d2
d2+ d1- d1- ; add d2,d1
c9+ d1+ d1- ; and #$00ff,d1
f203- ; clear flag
f203: 0000# ; rts


b0: f106-
b1: f104-
c0: 0000#
c1: ffff#
c2: ffdf#
c3: 0024#
c4: ffd0#
c5: ffc6#
c6: 0030#
c7: 0020#
c8: 0027#
c9: 00ff#
d1: 0000#
d2: 0000#
d3: 0000#


-----------------------------------------------------------------------

The binary of the VM:

echo hD1X-s0P_kUHP0UxGWX4ax1y1ieimnfeinklddmemkjanmndnadmndnpbbn>run.com
echo hhpbbnpljhoxolnhaigidpllnbkdnhlkfhlflefblffahfUebdfahhfkokh>>run.com
echo s1EDuGq/B6WQ2AOP2k7q4//3C1Q0//VXUL//EgX01/kQEkjj01k2qmozgm2>>run.com
echo 7rRFGpVTAPb7qomInV3ht8Szua3ht0QzuUYcw9l9DUQryCZsl5H//s1EDB6>>run.com
echo WQLbsk8WDW3of//3nzlMDhzcvP2YP//oQ7mt@GpRr2qOkP2Mj0gBkzoZ/D9>>run.com
echo wEZ5kq/fnBDuEbHwA1RFln9o44DhEL9wg2RrkHDoN8DeE6aw/XQwmHCql/2>>run.com
echo UkHMm8@DaRbfgQ1@k3gt33UlfDOAG6htYh70FXS1EPGW4QoFfzcl5kq/0gC>>run.com
echo WFPCN8mnu0a7wfTii//suNX@/14XolYQnVoo24WqzouHnVs@U/wUhA3Unlw>>run.com
echo DN6Lkzz62kDxYW3s3N8KUsqbcDlBEAq6HmaoOoU@61EbiQqbclf@Duh/EWJ>>run.com
echo @r3cP1/mRE/ezUY0jC5dcy2I5wuFUy3/7r0Vcy2I5wu4YUuDENkcn3/f@QW>>run.com
echo 2D7k5Eb1mNV8@SV8h5Bs2jc6lBkU53r/1EqWLgSvU4nq7VIR5AU6hB/RMEv>>run.com
echo Duyq/t5//B6m21Sdz7Jr0Vhc4jBku76aizzzu1bsk21g0oNUQFMGWLAwUi3>>run.com
echo r/1gc6lB/N8SlkUhP//U3Gp4kE7OlP27o23qZzo1YijBEi0/EnVwUUBtDGD>>run.com
echo I7Gy6qkmJbPiEKMo0//////////.>>run.com

Rod Pemberton

unread,
Nov 10, 2009, 6:32:59 AM11/10/09
to
"Rugxulo" <rug...@gmail.com> wrote in message
news:3e065d36-e869-4a86...@n35g2000yqm.googlegroups.com...

> (Sorry if this is a re-post, I don't see it)
>

No.

> Anybody familiar with Befunge93?

No, but I recall reading seeing "Befunge" somewhere. IIRC, when looking for
"brainfuck" interpreters.

> Check here:
>
> http://www.catseye.tc/projects/bef/

Likely there.

> http://en.wikipedia.org/wiki/Befunge
> http://board.flatassembler.net/topic.php?t=10599
>

Esolangs also has a writeup:
http://esolangs.org/wiki/Befunge

Esolangs (Esoteric programming languages):
http://esolangs.org

Toadskin:
http://esolangs.org/wiki/Toadskin

Lots of obscure languages listed there...

For classical programming languages HOPL (History of Programming Languages):
http://hopl.murdoch.edu.au/

Both websites can be very slow to load. You may need to adjust your
browser's timeout.


Rod Pemberton


Rugxulo

unread,
Nov 11, 2009, 6:08:18 PM11/11/09
to
Hi,

On Nov 9, 11:39 pm, "Alexei A. Frounze" <alexfrun...@gmail.com> wrote:
>
> http://en.wikipedia.org/wiki/Brainfuck would be more compact. :)

Sure, but harder and (in some ways) not as fun. But yeah, one guy made
a real *compiler* (799 bytes) for Brainf*** in NASM:

http://home.arcor.de/partusch/html_en/bfd.html

:-)

Rugxulo

unread,
Nov 11, 2009, 6:13:40 PM11/11/09
to
Hi,

On Nov 10, 5:32 am, "Rod Pemberton" <do_not_h...@nohavenot.cmm> wrote:
> "Rugxulo" <rugx...@gmail.com> wrote in message
>
> news:3e065d36-e869-4a86...@n35g2000yqm.googlegroups.com...
>


> > Anybody familiar with Befunge93?
>
> No, but I recall reading seeing "Befunge" somewhere.  IIRC, when looking for
> "brainfuck" interpreters.

It's because they both are two of the most popular esolangs.

> Lots of obscure languages listed there...

Still lacks some stuff. I should try making a page myself with links
to everything as it's somewhat hard to find good Befunge stuff. (Where
is Ben Olmstead when ya need him? Heh.)

> For classical programming languages HOPL (History of Programming Languages): http://hopl.murdoch.edu.au/

That one actually has Befunge, but it's an old link that's broken
(catseye.mb.ca).

Rugxulo

unread,
Nov 11, 2009, 6:20:28 PM11/11/09
to
Hi,

On Nov 10, 3:35 am, Herbert Kleebauer <k...@unibwm.de> wrote:
> "Alexei A. Frounze" wrote:
> > On Nov 9, 8:28 pm, Rugxulo <rugx...@gmail.com> wrote:
> > > Well, I hacked up a pre-existing one (written in pieces by both Ryan
> > > Kusnery and Ben Olmstead), converted it from TASM, and shrank it a
> > > lot.
> > > 1024 bytes uncompressed (original TASM version was 1280) with a few
> > > very tiny extras (386 check, LFN support, fixed a few bugs). It can

> >http://en.wikipedia.org/wiki/Brainfuckwould be more compact. :)


>
> How about a complete virtual machine with an embedded assembler in
> 500 byte:
>
> run.com is a simple 16 bit Virtual Machine which can address 32k 16 bit
> words (=64 kbyte) and a 32k 16 bit word stack. A program executed in the
> VM can only write to stdout and stderr and read from stdin and (if
> present) from the file run.dat. There is no other way to communicate
> with the operating system and therefore a program executed in the VM
> cannot harm the system in any way.
>
> The VM only supports 5 instructions:

Wow, I'm impressed!

Now if I can only wrap my feeble head around it .... ;-)

Benjamin David Lunt

unread,
Nov 11, 2009, 7:24:47 PM11/11/09
to

Hi guys,

I haven't been following this thread much, but due to the
recent interest in the Hugi Compo, I just wanted to mention
that we had a compo on this same subject.

http://www.frontiernet.net/~fys/hugi/compoold.htm#compo6

Smallest was 98 bytes. :-)

Ben


"Rugxulo" <rug...@gmail.com> wrote in message

news:724c2a84-28eb-45a1...@g23g2000vbr.googlegroups.com...
Hi,

On Nov 9, 11:39 pm, "Alexei A. Frounze" <alexfrun...@gmail.com> wrote:
>

> http://en.wikipedia.org/wiki/Brainf*** would be more compact. :)

Rugxulo

unread,
Nov 11, 2009, 7:55:36 PM11/11/09
to
Hi,

On Nov 11, 6:24 pm, "Benjamin David Lunt" <zf...@frontiernet.net>
wrote:


>
> I haven't been following this thread much,

Can't blame you, there's too much spam! :-( That's part of the
reason I "bumped" it again.

> but due to the
> recent interest in the Hugi Compo, I just wanted to mention
> that we had a compo on this same subject.
>
> http://www.frontiernet.net/~fys/hugi/compoold.htm#compo6
>
> Smallest was 98 bytes. :-)

I went back to that recently, but they didn't work for my examples. So
either I did it wrong or who knows ....

And I definitely did think about you guys: the original Befunge
interpreter was TASM and 1280 bytes. After switching to FASM, I knew
that alone would shave some space: 1213 bytes. And aPACK compressed it
to under 1024 bytes (nice round number, good for floppies with small
clusters). Hence I wondered (very very skeptically) if I could shrink
it to 1024 bytes manually.

1280 -> (removed useless stuff, fixed a bug or two, switched to FASM)
1213 -> (temporarily happy that aPACK shrank to < 1024)
1154 -> (curious to see how small I could make it)
1077 -> (incredulous but still kept trying, ironically worsening
compression)
1021 -> (amazed beyond belief)
1023 -> (added LFN support)
1024 -> (added 386 check)

Something like Befunge (1000+ bytes) might be too complex or big for a
Hugi Compo, hence limiting entries, but I did almost want to suggest
it anyways. ;-)

Rod Pemberton

unread,
Nov 11, 2009, 11:54:52 PM11/11/09
to
"Rugxulo" <rug...@gmail.com> wrote in message
news:4288767c-2d98-4542...@15g2000yqy.googlegroups.com...
>
> ... Hugi Compo ... but I did almost want to suggest it anyways.
>

Well, I've been wanting to suggest something useful, like a C compiler...
But, I'm afraid it'll end up like the USB compo with no or few entries.
Although, they did do two assembler related compo's. My occasional comments
for HK to do a C compiler inspired him to do so either...


Rod Pemberton


Rod Pemberton

unread,
Nov 12, 2009, 12:05:14 AM11/12/09
to

"Rod Pemberton" <do_no...@nohavenot.cmm> wrote in message
news:hdg4i7$254$1...@aioe.org...

Huh? Wha...?

"... C compiler" didn't inspire "him to ..."

Man, I should've waited 'til morning to post.


Rod Pemberton


0 new messages