Giter VIP home page Giter VIP logo

brainm68k's Introduction

brainm68k

bf tests

In 1993 Urban Müller invented a Turing tarpit programming language for which he created a tiny 240 byte compiler for the Amiga.

This repo collects some basic utilities, written in bf, for working with the original bfc compiler and its compiled output.

  • m68kd.bf decompiler: Takes an AmigaOS 2.0 executable generated by Urban Müller's original 240 byte bf compiler bfc and decompiles it back into bf source.
  • gengen.bf generator: Takes a text (NULL terminated binary) or AmigaOS 2.0 executable file as input and outputs bf code to reproduce those bytes as output.
  • gen_bfc.bf bfc generator: Generated by gengen.bf. Outputs the bfc compiler AmigaOS executable. It compiles to 41,120 bytes using bfc, which is greater than its 32K CODSIZE limit and therefore overlaps the memory tape. The gengen.bf algorithm aligns it so the single utilised memory cell falls on an already NULL byte, which doesn't cause the program to crash despite the instruction pointer having to cross the tape and adjacent cells to read the full program.

Assumes 8-bit wrapping cells. Tested using Urban Müller's 240 byte bf compiler bfc running under vamos (virtual AmigaOS runtime) on Linux.

Testing

Another feature of this repo is its AmiNet and bf CI github workflow.

To test functionality, the workflow downloads bfc from AmiNet (it's still there!), and uses that in conjunction with the vamos Amiga emulator to compile and run bf code and check the results are as expected.

External resources

brainm68k's People

Contributors

hornc avatar

Stargazers

 avatar

Watchers

 avatar

brainm68k's Issues

Hilarious bug arising from bfc handling of comments

It turns out the original bfc does not recognise comments (not really surprising given the small size...) It simply ignores everything that isn't one of the 8 bf commands. Comments should therefore avoid these.

I added a header comment to m68kd.bf then discovered the decompiled output was not matching expectations.

diff <(vamos m68kd.m68k < hello.m68k | sed 's/+-]/]/g') <(cat src/hello.b | tr -dc "+-<>[],.")
Binary files /dev/fd/63 and /dev/fd/62 differ

and

diff -a <(vamos m68kd.m68k < hello.m68k | sed 's/+-]/]/g') <(cat src/hello.b | tr -dc "+-<>[],.")
1c1
< >+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.[-]>++++++++[<++++>-]<.>+++++++++++[<+++++>-]<.>++++++++[<+++>-]<.+++.------.--------.[-]>++++++++[<++++>-]<+.[-]++++++++++.
\ No newline at end of file
---
> >+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.[-]>++++++++[<++++>-]<.>+++++++++++[<+++++>-]<.>++++++++[<+++>-]<.+++.------.--------.[-]>++++++++[<++++>-]<+.[-]++++++++++.
\ No newline at end of file

... which looks identical, and why does it think the files are binary?

Turns out there are 3 null characters prepended to the m68kd output.

What is causing that?

Let's decompile the m68kd M68000 executable m68kd.m68k and find out:

vamos m68kd.m68k < m68kd.m68k
...+++++[>++++++++++<-+-]>[->,<+-]>,++++++++++++++[--------------[<-[>-<---+-]>+++++++>+<[----[-[-------------[------[<----[>---<----+-]>+[>-<[-+-]+-]>[,,,,,,,,,,,,+-]>[-+-]<[-+-]+-]>[-<,,,[-+-]<-[>+<---+-]>++++++++.[-+-]+-]>[-+-]<[-+-]+-]>[-<,,,[-+-]<-[>+<---+-]>++++++.[-+-]+-]>[-+-]<[-+-]+-]>[-<,<+++[>-------<-+-]>>+<[<-[>-<++++++++++-]>---.[-+-]>[-+-]<+-]>[[-+-]<<[-+-]--[>+<+++++++-]>++.[-+-]+-]+-]>[-+-]<[-+-]+-]>[-<,<+++[>-------<-+-]>>+<[<-[>-<++++++++++-]>-.[-+-]>[-+-]<+-]>[[-+-]<<[-+-]--[>+<+++++++-]>.[-+-]+-]+-]>[-+-]<[-+-]+-]>[-<,,,<-[>+<-----+-]>+++[[-+-]>++<+-]--[>+<+++++++-]>+.,,,,,,,,[-+-]<+-]+-],+++++++++++++++-]

What are those initial ... doing there? That's not in my original code.... oh, right. The comments in lines 1 and 2 have 3 periods.

This illustrates the value of m68kd.bf as a debugging tool. 🤪

  • "Hilarious" -- YMMV.

Issue generating bfc

Relates to PR #2

The gengen.bf script should be able to generate bf code which outputs the bfc binary.

Steps:

# 1, Compile the generator:

vamos bfc < gengen.bf > gengen.m68k

# 2, Generate a bfc generator:

vamos gengen.m68k < bfc > gen_bfc.bf

# 3, Compile the bfc generator:

vamos bfc < gen_bfc.bf > gen_bfc.m68k

# 4, Run the compiled bfc generator to generate a bfc copy:

vamos gen_bfc.m68k > bfc2

# Expect the binary files to be identical:

diff -s bfc bfc2

Step 3 produces errors, and the output is truncated from 240 bytes to 191 bytes.

20:29:43.836    machine:  ERROR:  ----- ERROR in CPU Run #1 -----
20:29:43.836    machine:  ERROR:  Run: 'gen_bfc.m68k': Initial PC=0020b8, SP=0140a0
20:29:43.836    machine:  ERROR:  PC=00000404  SR=--Z--    USP=000140a0 ISP=000006fa MSP=00000780
20:29:43.836    machine:  ERROR:  D0=00000000  D1=0000081c  D2=00009dba  D3=00000001  D4=00000000  D5=00000000  D6=00000000  D7=00000000
20:29:43.836    machine:  ERROR:  A0=000140a8  A1=00000000  A2=ff01dd05  A3=00000000  A4=00000004  A5=00009dba  A6=00001ae8  A7=000006fa
20:29:43.836    machine:  ERROR:  SP-32=000000 SP-28=000000 SP-24=000000 SP-20=000000 SP-16=000000 SP-12=000000 SP-08=000000 SP-04=000000
20:29:43.836    machine:  ERROR:  SP+00=7040000 SP+04=9dbc0000 SP+08=000000 SP+12=000000 SP+16=000000 SP+20=000000 SP+24=000000 SP+28=000000
20:29:43.836    machine:  ERROR:  InvalidCPUStateError: Invalid CPU State: pc=009dbc: m68k Exception: sr=0704
20:29:43.836       main:  ERROR:  vamos failed!
20:29:43.836     libmgr:WARNING:  can't expunge: 'dos.library' with open count 1
20:29:43.836     libmgr:WARNING:  shutdown: can't expunge 1 vamos libs/devs!

Strangely the first output bytes are not NULLs (the first cell is not zeroed):

xxd bfc2
00000000: 6666 69f3 0000 0000 0000 0001 0000 0000  ffi.............
00000010: 0000 0000 0000 5f75 0000 03e9 0000 0033  ......_u.......3
00000020: 0000 03f3 0000 0000 0000 0001 0000 0000  ................
00000030: 0000 0000 0000 3ff7 0000 03e9 0000 3ff7  ......?.......?.
00000040: 4bfa 7d00 7004 2840 2c54 4eae fcd6 2c40  K.}.p.(@,TN...,@
00000050: 7601 244d 7aff 421a 51cd fffc 353c 03f2  v.$Mz.B.Q...5<..
00000060: 244d 1a83 1815 47fa 0066 1a1b 121b b81b  $M....G..f......
00000070: 65f8 6620 d7c5 1adb 5301 66fa 5005 6402  e.f ....S.f.P.d.
00000080: 250d 5605 660e 205a 2008 908d 3ac0 4440  %.V.f. Z ...:.D@
00000090: 5940 3100 4215 4eae ffca 2200 240d 4eae  [email protected]...".$.N.
000000a0: ffd6 4a04 66be 2a4a 4843 4eae ffc4 2200  ..J.f.*JHCN...".
000000b0: 240d 4eae ffd0 224e 2c54 4eae fe62 70    $.N..."N,TN..bp

A small test shows the first cell is zeroed when using the first few lines of bfc_gen.bf

vamos bfc <<< "..+++.[-]-------------.[+].\n.\n." > tmp.exe ; vamos tmp.exe | xxd
00000000: 0000 03f3 0000 00                        .......

Is the problem caused by the source length? Seems to be a problem with bfc?

Correct output up up to character 14665:

vamos bfc < <(head -c14665 gen_bfc.bf ) > tmp.exe ; vamos tmp.exe | xxd
00000000: 0000 03f3 0000 0000 0000 0001 0000 0000  ................
00000010: 0000 0000 0000 5f75 0000 03e9 0000 0033  ......_u.......3
00000020: 0000 03f3 0000 0000 0000 0001 0000 0000  ................
00000030: 0000 0000 0000 3ff7 0000 03e9 0000 3ff7  ......?.......?.
00000040: 4bfa 7d00 7004 2840 2c54 4eae fcd6 2c40  K.}.p.(@,TN...,@
00000050: 7601 244d 7aff 421a 51cd fffc 353c 03f2  v.$Mz.B.Q...5<..
00000060: 244d 1a83 1815 47fa 0066 1a1b 121b b81b  $M....G..f......
00000070: 65f8 6620 d7c5 1adb 5301 66fa 5005 6402  e.f ....S.f.P.d.
00000080: 250d 5605 660e 205a 2008 908d 3ac0 4440  %.V.f. Z ...:.D@
00000090: 5940 3100 4215 4eae ffca 2200 240d 4eae  [email protected]...".$.N.
000000a0: ffd6 4a04 66be 2a4a 4843 4eae ffc4 2200  ..J.f.*JHCN...".
000000b0: 240d 4eae ffd0 224e 2c54 4eae fe62       $.N..."N,TN..b

Adding one more byte from the source triggers the error:

vamos bfc < <(head -c14666 gen_bfc.bf ) > tmp.exe ; vamos tmp.exe | xxd
20:55:42.830    machine:  ERROR:  ----- ERROR in CPU Run #1 -----
20:55:42.831    machine:  ERROR:  Run: 'tmp.exe': Initial PC=0020b8, SP=0140a0
20:55:42.831    machine:  ERROR:  PC=00000404  SR=-----    USP=000140a0 ISP=000006fa MSP=00000780
20:55:42.831    machine:  ERROR:  D0=00000075  D1=0000081c  D2=00009dba  D3=00000001  D4=00000000  D5=00000000  D6=00000000  D7=00000000
20:55:42.831    machine:  ERROR:  A0=000140a8  A1=00001ae8  A2=ff01dd05  A3=00000000  A4=00000004  A5=00009dba  A6=0000133c  A7=000006fa
20:55:42.831    machine:  ERROR:  SP-32=000000 SP-28=000000 SP-24=000000 SP-20=000000 SP-16=000000 SP-12=000000 SP-08=000000 SP-04=000000
20:55:42.831    machine:  ERROR:  SP+00=7000001 SP+04=20980000 SP+08=000000 SP+12=000000 SP+16=000000 SP+20=000000 SP+24=000000 SP+28=000000
20:55:42.831    machine:  ERROR:  InvalidCPUStateError: Invalid CPU State: pc=012098: m68k Exception: sr=0700
20:55:42.831       main:  ERROR:  vamos failed!
00000000: 4e4e 51f3 0000 0000 0000 0001 0000 0000  NNQ.............
00000010: 0000 0000 0000 5f75 0000 03e9 0000 0033  ......_u.......3
00000020: 0000 03f3 0000 0000 0000 0001 0000 0000  ................
00000030: 0000 0000 0000 3ff7 0000 03e9 0000 3ff7  ......?.......?.
00000040: 4bfa 7d00 7004 2840 2c54 4eae fcd6 2c40  K.}.p.(@,TN...,@
00000050: 7601 244d 7aff 421a 51cd fffc 353c 03f2  v.$Mz.B.Q...5<..
00000060: 244d 1a83 1815 47fa 0066 1a1b 121b b81b  $M....G..f......
00000070: 65f8 6620 d7c5 1adb 5301 66fa 5005 6402  e.f ....S.f.P.d.
00000080: 250d 5605 660e 205a 2008 908d 3ac0 4440  %.V.f. Z ...:.D@
00000090: 5940 3100 4215 4eae ffca 2200 240d 4eae  [email protected]...".$.N.
000000a0: ffd6 4a04 66be 2a4a 4843 4eae ffc4 2200  ..J.f.*JHCN...".
000000b0: 240d 4eae ffd0 224e 2c54 4eae fe62 70    $.N..."N,TN..bp

Looks like there is a limit on the source size bfc can handle.

14666 is close to half CODSIZE EQU 32000 which appears in bfc.asm --- investigate the actual input limits in bfc.

Add header comment to gen_bfc.bf

Add a "what is this?" comment to gen_bfc.bf

  • Write that is generated code, generated by gengen.bf
  • State and describe what it generates: bfc
  • license and (c) statements
  • (rename it to genbfc.bf or gen-bfc.bf?)

What's next?

Scripts already present in this repo:

bf source --(bfc)--> AmigaOS 2.0 executable --(m68kd.bf)--> bf source


data --(gengen.bf)--> bf source
                     (bf source)--> data  
                     
bfc --(gengen.bf)--> gen_bfc.bf
                    (gen_bfc.bf)--> bfc

Notation:

() run / execute / compile and execute / interpret a program

()--> program produces an output

--()--> program takes an input and produces an output

Next steps:

A)

bf source --(bfc)--> AmigaOS 2.0 executable --(???.bf)--> expected output of bf source

Two ways to do this:

  • as a bf interpreter that can parse bfc generated Amiga executables
  • as an interpreter of a restricted subset of m68k instructions

B)

bfc --(???.bf)--> takes input and outputs a m68k executable as bfc would 
  • (partial) m68k emulation in bf

C)

[bf source --(bfc)--> AmigaOS 2.0 executable | bfc] --(???.bf)--> expected output of bfc OR expected output of an executable generated by bfc.
  • requires restricted subset of m68k to be emulated in bf

Looks like a bf script that acts as a partial m68k interpreter will be more interesting than what would effectively be a bf-self-interpreter which accepts a messy binary syntax. Do the (partial) m68k interpreter.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.