Archive for the ‘Apple II’ Category

COMFY-6502: a slight correction

February 11, 2008

After all the work to write a post showing off COMFY-6502’s ability to reproduce the Red Book tone routine, I made a slight mistake in translation. The code I presented differed ever-so-slightly from the Red Book routine in the case where the Y-register reached zero.


COMFY-6502: work in progress

February 5, 2008

As I’ve mentioned before, I’ve become intrigued by Baker’s COMFY assembler, and have been working on porting it to Common Lisp, and making it a bit more powerful in the link stage.

One metric to judge the success of this kind of “medium-level” language is how well it compiles compared to hand-written assembler code. For the 6502, there are a few examples of code created by wizards like Steve Wozniak, which you can find copies of around the web, the largest being the Apple II monitor, the Integer Basic interpreter, and some medium-sized ones like the Apple II 6502 step/trace, the mini-assembler, the floating-point “Wozpack,” and the Sweet-16 virtual machine.

This kind of code has a lot of quirks that make it hard to straight-forwardly translate: lots of shared “tail code”, branches known by the programmer to always be taken (to save a precious extra byte consumed by an unconditional JMP), and the classic “fake RTS trick”, pushing a return address picked from a table onto the stack, then using an RTS instead of a zero-page indirect JMP. Common in Woz’s code is a further shortening of the code by arranging the destination addresses to all be in the same 256-byte page, so the high-order byte is a constant. Some of these ideas will likely be possible with intelligent macros, combined with address labels and computation on those labels. I’m puzzling a bit over how to optimize the “same page” condition: whether to include a “link-time assert”, which will issue an error if the code is emitted so as to cross a page, or an even more intelligent “link-time computation” which, given the current available memory space, can choose a location that meets the constraints.

Another interesting mid-level assembler

December 17, 2007

While I’m still digesting COMFY in my “ample spare time,” a post on comp.sys.apple2 mentioned some assemblers from “Ron” having a similar flavor: SPL for the 6502 and PIC0 for PIC 10F2xx microcontrollers. They are apparently implemented in Python, and inspired by Forth. They emit assembler.

Baker’s COMFY: a few notes

November 3, 2007

I’ve been working a bit with Baker’s COMFY-6502 code; a few notes of what I have learned so far.

First, a couple of tiny bugs in the genbrc; the code miscounts the size of the branch instructions, meaning that (- l 2) should be a (+ l 2) and so on. I found it handy to enumerate each clause of the cond. Each clause handles a particular case, such as when the “lose” continuation can be reached by a short branch instruction, while the “win” continuation is far enough away to require an absolute jump.

Second, genbrc, genbr, and compile all provide the address of the resulting “continuation” as the return value. This is perhaps clear when one traces out all the recursion, but it isn’t explicitly mentioned. One interesting case is genbrc when the “win” and “lose” branch destinations are the same: one could simply emit an unconditional branch to that destination, and return the address of that branch but actually returning the destination works just as well. (In the emit routine, if the continuation does not happen to be the next instruction, the unconditional branch is, after all, emitted, moving the continuation to the front of the instruction stream, ready for the non-branching instruction to be emitted just in front of it.)

As for “upgrades” to the package, I have been focused up to this point on moving the knowledge of 6502 opcodes and addressing modes from magic decimal numbers to symbolic processing. Instead of simply emitting a decimal opcode, I have been changing the code to emit symbolic opcodes, such as (ADC ABSOLUTE), with routines to reduce these symbolic forms to the appropriate opcode, including checking for invalid opcodes. Baker’s original code will happily emit opcodes with addressing modes not supported by the chip. Currently, the compiler emits these symbolic codes into the code vector, awaiting a processing step to convert them to the decimal equivalent. Ideally, one would detect invalid addressing modes in the compilation stage, not the post-processing stage.

Some other changes I am contemplating are allowing for symbolic jump destinations, so that object code can be relocated and external labels could be used to relax the restrictions of the current scheme, which requires manually sequencing compilation and storing of addresses.

Baker’s COMFY for the PIC?

September 24, 2007

I encountered Henry G. Baker’s COMFY compiler a couple years ago. (Baker’s site contains a text article, a TeX format article, and an Emacs Lisp implementation. The ACM published the two articles COMFY theory and COMFY-65) COMFY is not a very high-level language, in the conventional sense, but is an attempt to provide a clean but simple set of control structures on top of conventional machine code. Baker calls it ‘medium-level.’

The resulting compiler is very small; its main task in life is to automate the generation of branch instructions, which is one of the tedious parts of tightly optimizing assembly programs. Yet it allows as well for arbitrary Lisp-style macros.

I found the concept intriguing, but I found the article and the compiler code itself rather obscure. Part of the obscurity is the unconventional names for the 6502 operations, unconventional notation for the addressing modes, and decimal numbers for opcodes (because Emacs Lisp does not accept other radixes). Another is that the implementation is lean-and-mean, emitting code bytes directly into a destination vector—the only output to look at is a vector filled with decimal numbers. The manipulations on the 6502 opcodes take advantage of the low-level bit patterns without explanation. Finally, it uses the term ‘continuation’, which, no matter how many times I think I understand it, scares me, probably because it introduces a highly abstract term into an area like assembly programming which is relentlessly concrete.

I’ve been learning about it by going through the code, restructuring a bit as I go. I’m beginning to be impressed by the subtlety of the code. One thing that is just dawning on me is that the return values of the code-emitting functions is as important as the side-effect. (To those of you chuckling, you see how far I have yet to go.) Lisp can hide that from you when it “looks imperative.”

My longer term goal is to see if the same technique can be fruitful even within the more restrictive limits of the PIC. In order to get there, I’m going to have to gain confidence that I understand the formal concept of the ‘win’ and ‘lose’ continuations, which means, I think, having to come up with legible examples that compile to 6502 code, and use that to firm up my understanding of the compiler. Finally, I’ll try to code the ‘genbrc’ routine for PIC branches.

For the “legible examples” part, I think I will try to break the lean-and-mean single-pass direct-to-binary compiler into a “compile to a vector or list with symbolic 6502 mnemonics” followed by a very simple 6502 assembly pass. A similar enhancement might accumulate a relocation table to allow more flexible linking. (I’m still not used to the idea that the code is emitted starting in high memory and working down.) I’ve begun abstracting out the addressing mode bit manipulations, and probably will add error-checking to make sure invalid opcodes are not generated by mistake.

One thing that I think that will have to go in the PIC version is the shallow binding mentioned in the TeX column, but not in the text version; without a stack, I’m not sure where to save anything. I’m also just a bit worried that the PIC has so many idiosyncracies (e.g., register pages controlled by special flags, instead of a uniform zero-page) that even a medium-level language doesn’t help much.

(I should mention in passing Frode Vatvedt Fjeld’s nifty little Lisp code to generate PIC instructions from the bit chart.)

[UPDATE: I should also mention a COMFY-based assember for x86, implemented in Scheme, called `Sassy’, although I have never tried to use it.]

Apple II Disk Transfer

July 25, 2006

It seems that others have also had the desire to upgrade the ADT (Apple Disk Transfer) tool to work with disks other than the Disk II 5-1/4 inch floppy format under DOS 3.3.

ADTPro is a ProDOS-based version of ADT. It should presumably work with all block devices recognized by ProDOS. I e-mailed some code to David Schmidt which allowed ADT to work with the ordinary IIgs serial ports; direct access to the Z8530 chip might allow for faster transfers; that’s a potential project.

What is this about

January 29, 2006

This blog is a simple experiment for now, to understand what is available for a “scratchpad on the Web.”

I have a picture which is something more like a lab notebook for my various hacking projects. The requirements are roughly

  • access from various places where hacking might happen; an idea for a project can happen at work, but I don’t want my personal laptop with me at all times.
  • some kind of permanence, as suits a lab notebook. Various things this might mean:
    • version control with timestamping
    • no revisions allowed at all (this seems extreme: one wants to separate a polished presentation view from the underlying archival lab notebook. One can revise slides for a talk without altering the historical record of the lab notebook)
    • ability to archive into a big .tgz for burning to disk as necessary
  • flexible project documentation
    • easy way to archive associated files; diffs, error messages, screen shots, sketches, links, data sheets downloaded for the web.
    • perhaps I need to wait for my copy of Kanare’s Writing the Laboratory Notebook (as seen on Lispmeister) to arrive to understand what should be required here.

Some projects to comment on here

  • work on CADR emulator and MIT-released Lisp machine code
    • make it work on Mac OS X/PPC for my laptop
    • make Chaos emulation work on Mac OS X
    • fix some Y2K-type issues, site configuration
    • create Chaos layer in OpenMCL or more portable Common Lisp, to develop gateways to things like
      • AIM/Jabber
      • regular e-mail
      • other retro people running Chaos emulation
      • support versioning file system semantics (e.g. blah.type~version~) on a UNIX FILE host.
      • build a world from the MIT-provided code, alllowing bootstrap
  • Apple II file transfer (extend ADT = Apple Disk Transfer) to include 140k, 800k ProDOS and Macintosh HFS floppy formats
  • Possibly, an Apple II compatible USB peripheral interface, to allow easy transfers to a Mac/PC with USB connection
  • Mac OS X support for foot-pedal shift & mouse-click operations

Interesting that Netscape 7 on Windows gives me little editing widgets on my post that Safari on Mac OS 10.4 didn’t give me (as I recall.) Perhaps I should check, try to add that capability.