There's a legend (perhaps me misremembering, or simply making it up, thus making it a legend rather than an anecdote) that Chuck Moore did something like this that eventually ended up as ColorForth.
The story is simply that he started with MS-DOS, some floppy disks, and DEBUG. Starting there, he bootstrapped to being able to boot something from a floppy, and just pushed on from there.
Its an interesting development idea of simply molding a RAM image to your liking with little more than POKE, PEEK, BLOCKMOVE and READ/WRITE the RAM image. The assembler is a tasty treat, but hardly necessary, and perhaps not as helpful as one would like since while the mnemonics are nice, its the labels that give an assembler its real power.
I always visualized putting subroutines at 16 byte boundaries, if only to make the addresses stand out a bit in the hex noise, but also to give a little wiggle room to make changes without stomping on other code. Thinking how cautious one has to be, particularly on an MS-DOS machine, you have to be knowing one misstep, one stuck loop, and you're reloading from disk again. "Save early, save often". Plus that one point when you're in the phase of writing the floppy bootsector and you now, suddenly have a larger step to go from bootable primitive Forth kernel, to one that can self-host, even if it's just defining code words as blocks of hex numbers, forgoing an actual assembler early on. But, ideally, by that point, you're already comfortable with block of hex code, however now you don't have the benefit of a disassembler outside of the carbon based meat computer stuck in your head.
I think after a day or two of full immersion in this environment, disassembling hex code would be mostly straightforward. Woz is said to have 6502 binary memorized. It doesn't really take much, you don't need to memorize it all. Knowing a dozen instructions can take you a long way.
Anyway, always been an interesting thought exercise. Nice to see something similar. I like the primitive base Forth used.
I think after a day or two of full immersion in this environment, disassembling hex code would be mostly straightforward. Woz is said to have 6502 binary memorized. It doesn't really take much, you don't need to memorize it all. Knowing a dozen instructions can take you a long way.
It does. I am certainly no Woz, but I used to program a KIM-1 by hand assembling with pencil and paper from a programming card, then keying hex codes into its onboard keypad. After a few days you don't need to look at the card much. It's really quite practical - it's actually easier than dealing with editor and assembler tools. After fifty years, I still recall that A5 encodes LDA.
I am teaching myself Arm assembly for the M-series of processors, M-4 for now. I have been playing and using J (jsoftware.com) since 2010, and I have to say that as much as the higher abstracted languages and programs become, I still love the atoms and terseness of array languages and writing close to the metal. I started with Factor, gforth, and retro years ago. Something magical happens when you immerse yourself in it. Right now, I am working with KlongPy, which using the PyTorch backend along with the Klong language is amazing. I used to write assembly code for my Vic-20 back in the day and then bought the VIC FORTH cartridge for like $30 in 1982. I programmed my 1977 PET 2001 in the Commodore Basic 1.0 it came with, but there was a sys instruction for machine code! I used to write my code on an index card before typing it in and saving to the cassette recorder. Magazines had code to hand type in, so my coding was learned with reading and writing it first. I accidentally bought a hardcover book on PDP-11 programming and read the whole book before I bought my PET in 1977. Machine language.
I miss the early days of computing before the internet or Genie Online, but Echo in NYC was a blast - thanks, Stacy!!
Agreed, though I would say that 6502 is a lot more straightforward to memorize than x86. A lot fewer addressing modes and every instruction is always just a byte, possibly followed by immediate data. The 6502 was a little gem.
In my very modest experience, I once wrote a system that I could boot from a floppy, edit, then recompile. For this I needed to make an assembler, or rather I was willing to meet the challenge of writing an assembler for the 8086, which was notoriously difficult (not really for the subset I needed, which did not include the complex addressing modes for one thing).
When it came to writing the changes on the floppy I was very scared to trash my hard disk (writing to HD or floppy was just a value in a register when you use the BIOS API), but fortunately I found an old Toshiba laptop that had an external power-on switch for the hard disk! That thing was running at 10 Mhz in "turbo" mode!
Bottom line: I spent a lot of times reading the ISA specs, write the assembler in Forth, and compare/check its output with an actual assembler. It would have been more efficient to enter directly the instructions in hex, I think, except maybe for the boot sector.
If you read the colorforth source (there’s only around 1000 instructions of assembly, it’s not a long read), there’s a real sense that much of the design (pretokenization, color tags, etc) are built around the punchline of a single (with rep prefix) instruction being used to linear-search the dictionary — going to trivial hardware-supported data structures here constrains the implementation a bunch, but there’s magic in self-imposed constraints.
there's a similar story by kragen on .. hmm HN or maybe SO where he describes a bootstrapping from a micro hand crafted asm monitor to forth to more and higher level languages. "stuck-in-a-basement" kindof challenge.
in good old days you could use COM or a.out format which are literally just code instead of fancy headers etc. a.out binaries used less memory as well. I could run Linux Slackware with 2mb of ram instead of 4
.COM binaries yes, but a.out binaries do have a header, similar in size to ELF.
When ELF was added to Linux, I think it used a bit less RAM than a.out.
ELF made it easier to build and deploy shared libraries, and the design was more consistent at keeping code sections read-only despite run-time linking (the PLT stuff), so more RAM pages ended up automatically shared between processes by the kernel, compared with a.out.
The story is simply that he started with MS-DOS, some floppy disks, and DEBUG. Starting there, he bootstrapped to being able to boot something from a floppy, and just pushed on from there.
Its an interesting development idea of simply molding a RAM image to your liking with little more than POKE, PEEK, BLOCKMOVE and READ/WRITE the RAM image. The assembler is a tasty treat, but hardly necessary, and perhaps not as helpful as one would like since while the mnemonics are nice, its the labels that give an assembler its real power.
I always visualized putting subroutines at 16 byte boundaries, if only to make the addresses stand out a bit in the hex noise, but also to give a little wiggle room to make changes without stomping on other code. Thinking how cautious one has to be, particularly on an MS-DOS machine, you have to be knowing one misstep, one stuck loop, and you're reloading from disk again. "Save early, save often". Plus that one point when you're in the phase of writing the floppy bootsector and you now, suddenly have a larger step to go from bootable primitive Forth kernel, to one that can self-host, even if it's just defining code words as blocks of hex numbers, forgoing an actual assembler early on. But, ideally, by that point, you're already comfortable with block of hex code, however now you don't have the benefit of a disassembler outside of the carbon based meat computer stuck in your head.
I think after a day or two of full immersion in this environment, disassembling hex code would be mostly straightforward. Woz is said to have 6502 binary memorized. It doesn't really take much, you don't need to memorize it all. Knowing a dozen instructions can take you a long way.
Anyway, always been an interesting thought exercise. Nice to see something similar. I like the primitive base Forth used.
reply