Genera and Packages

December 3, 2007 by jaoswald

As I alluded to in an earlier post, Symbolics Genera takes a slightly different approach to packages than most current environments (such as SLIME under Emacs).

Part of that is because, unlike GNU Emacs today, the editor and all its intelligence is running inside the Lisp environment; another part is due to Genera supporting multiple dialects of Lisp, each slightly compatible with the other.

One consequence is that Zmacs pays close attention to the “file attributes line” in your Lisp source files. (That’s the line at the beginning of the file which contains the marker “-*-”). Other Lisp environments use a heuristic, like looking for the first IN-PACKAGE form.

A chicken-and-egg problem arises when loading a file that expects to be read in a particular package. What if the package doesn’t exist? Well, it isn’t possible to use that package to read the file. But the package itself is defined in a file.

For me this caused a bit of confusion, because if you try to load a file with a non-existent package defined in the attributes, and you have not given Genera permission to create the package, it complains that “<package name> is not meaningful as a package name in <Lisp dialect>”.

You can press Resume to allow it to be created, and then the problem goes away until you try to bootstrap again without the package existing.

The answer is found in the documentation section “Specifying Packages in Programs.” If the package attribute is enclosed in parentheses, it is automatically created if it does not exist. Furthermore, you can include one package name, or a list of package names, as the second element of the list in order to specify packages which this package uses.

The other way to approach this is to create a system definition file which defines the packages up front.

(Another aspect that made me more confused is that the package name was “6502″, which if in the package attribute without quotes will read as an integer, which cannot designate a package. I had to muck around a bit trying double-quotes and vertical-bar escapes, in an effort to make the problem go away, before I realized the “not meaningful” was not referring to violating some non-existent rule about package names. From time to time, I would create the package and not realize that made the message go away.)

System 7 Accessing Mac OS X file servers

December 3, 2007 by jaoswald

Using my MacIvory, until now, I have been using an old Mac Powerbook running Mac OS 9 with AppleTalk file-sharing to allow me to copy files from a USB key to the Mac IIfx host running 7.6.1. Trying to access shared folders on my newer laptop running Mac OS X failed, as did sharing in the opposite direction.

Presumably, the problem is that Mac OS X uses a revision of the AFP file-sharing protocol which is incompatible with the version used by the default Mac OS 7.6.1.

It turns out there is a fix for this issue:

  1. Install Open Transport 1.1.2 (a dependency for the next step) on the 7.6.1 Mac
  2. Install AppleShare Client 3.8.3 on the 7.6.1 Mac

The Apple article on AppleShare Client 3.8.3 has more information on this release of the software.

Apparently AppleShare 3.8.8 requires System 8.

Learning Genera, bit by bit…

November 6, 2007 by jaoswald

Having hacked on the COMFY code for a while in Emacs Lisp, I got the itch to move it over to my MacIvory, which has been waiting for real work to do. I’ve crafted some tests in the Emacs Lisp using elk-test (trying to add heirarchical suites-of-suites along the way), and wanted to port them to one of the Common Lisp test frameworks (I’m thinking of checking out Stefil, LIFT, and rt, which I’ve used briefly). While copying the files, I ran into a few issues.

  1.  I couldn’t figure out an automatic way to handle line-ending issues in the text files. I ended up locating the file on the Mac OS side in the file browser, Mouse-R clicking to Edit the file, then M-%, C-q [LINE key] [Return] C-q [Return] [Return] ! in Zmacs, then saving to a file on the Ivory file system. (I like the offer to create non-existent directories on a save.) There is probably a Copy File(s) command I could have used to move them en masse, and I should have been able to code up a quick conversion routine or Zmacs keyboard macro, but it worked.
  2. Trying to compile the RT framework, I think I had been misled by my experience in the Genera Development Tutorial. The Common-Lisp mode apparently is Common Lisp the Language, 2d ed. What I was looking for is ANSI-Common-Lisp. The confusion cause all sorts of problems with DEFPACKAGE, and the presence of FUTURE-COMMON-LISP made me even more confused. An e-mail on the SLUG list apparently explains the various Common-Lisp strategies on Genera.

Baker’s COMFY: a few notes

November 3, 2007 by jaoswald

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.

MacIvory ADB Adapter Protocol

November 3, 2007 by jaoswald

Working with ResEdit and DeRez, I believe I have traced out the keyboard protocol used by the MacIvory ADB adapter. My adapter is on the blink, probably because of the small screw I found rattling about inside. I hope DKS can bring it back to life, or the PIC-based project I had begun will make its way back to the front burner.

MacIvory Keyboard Support Software

October 9, 2007 by jaoswald

The ADB adapter has not just given me some help uncovering the behavior of the Rev. C Symbolics keyboard protocol, but also works when attached to my MacIvory. Along the way (and with the help of David K. Schmidt) I encountered some glitches, mostly stemming from my original accidental trashing of the System file DKS installed.

There are a few software components the ADB adapter box needs to convert the Symbolics keyboard to something the Mac OS 7.6.1 (including the “FEP” window which communicates to the Ivory board on a low level) will accept as a keyboard with the right keymapping, and furthermore to something the Genera application will recognize with all the Symbolics-specific keys. Without these components, you will see one of the following two stages of malfunction.

Stage 1: The mouse connected to the ADB adapter works fine. In the Mac OS (including the FEP window), there is total keyboard confusion, with the keys all scrambled. On the Genera side, things are less scrambled, but some keys are missing, such as “e”, “t”, “u”, and “o”; the “o” in fact causes the Mac menu bar to flash. Modifier keys seem absent. If you activate the keyboard control application, Genera seems to crash easily. Peter Paine reported this at the time System 7.5.3 came out.

If you do a custom install of the “Symbolics Keyboard for System 7″ selection in the MacIvory software installer, you get the Symbolics Keyboard extension icon at Mac OS startup, and a Symbolics keyboard layout choice in the Keyboard control panel. The situation improves, reaching

Stage 2: The alphanumeric keys work for both the Mac OS and for Symbolics. However, Genera treats a press of the “Page” key as a press of the “Line” key, treats “Escape” as “Select”, and ignores the \{ and |} keys, the Hyper modifier key, and most of the large function keys (Function, Refresh, Square, Circle, Triangle, Suspend, Resume, Abort, Network, Local, Select, Line). Kent Pitman reported this after an upgrade to System 7.5.

The solution is to do a full install of the MacIvory support software. I believe this is necessary to get all of the resources installed in the Mac’s System file.

I’ll try to gather more details on the resources; it would be nice to understand how to make a box that takes, for instance, a PS/2 keyboard & mouse and connects it to the MacIvory, although the Symbolics keyboards and mice may be more plentiful than than the Ivory boards at this point, so it might be mere archaeology. More practical, if ADB adapters are scarcer than Ivory boards, would be a combination of the Apple keyboard (which works well enough for MacIvory use) and a three-button PS/2 mouse with a “partial ADB adapter” allowing it to provide multi-button mouse function to Genera.

UPDATE: I examined the resources, and was able to decode the Symbolics ADB adapter encoding.

Symbolics Rev. C Keyboard Secrets

September 26, 2007 by jaoswald

The ADB adapter has fulfilled its main purpose: providing an example of hardware which can speak to my Rev. C Symbolics keyboard.

The apparent trick is that the clock pulses must be narrow, without being too rapid (i.e., a relatively low duty cycle.) A 10 microsecond long low pulse on /CLR, followed 30 microseconds after the beginning of that pulse by the clock going low for roughly 9 microseconds, continuing with a clock period of approximately 50 microseconds does the trick. The ADB adapter pauses somewhat between groups of 11 clock pulses, corresponding to the natural “section breaks” of the keyboard mapping; I don’t know if that is strictly necessary. My first crude approximation, using bit-bashing for the PIC with timing loops resulted in Caps Lock and Mode Lock that felt a bit sluggish—needing to be held down relatively long to “lock” or “unlock.” The overall cycle time may be important in that regard.

In any event, I reconstructed the keyboard mapping from the LMKBD project, although I chose to count pulses from zero, rather than n=1 in that listing.

Unfortunately, this seems to make the PIC EUSART not fit the application: its clock pulses have a symmetric duty cycle. I had hoped to use the serial port intelligence to offload enough of the bit-handling to allow for rapid response that the ADB protocol seems to require. Perhaps I need to look at some of the other peripherals; can I use some pulse-width modulation output to drive the keyboard and the EUSART in synchronous slave mode together?

ADB adapter on its way…

September 24, 2007 by jaoswald

David K. Schmidt evidently scrounged up another ADB converter box which he just sold to me. Assuming I haven’t blown up my Symbolics keyboard, I may finally have what I wanted: a piece of hardware that knows how to talk to my Rev. C keyboard! I hope that will shorten the time to coerce my PIC circuit to do the same.

Baker’s COMFY for the PIC?

September 24, 2007 by jaoswald

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.]

Beginner PIC mistakes, and detective work

September 18, 2007 by jaoswald

Step 1 in the Symbolics keyboard to PIC project was not as quick as I had hoped.

It was pretty easy to generate the reset pulse, and get the serial port to send a clock signal to the keyboard. I then was using an oscilloscope to look at the keyboard response, but various attempts to get the PIC code to light up LEDs in response didn’t work at all. In fact, I was being bitten by two bugs, which I used the PICkit 2 in-circuit debug to discover.

  1. An array overrun bug (it seems the default radix in MPASM is hex, so reading 16 bytes into a sixteen element array doesn’t work! Unfortunately, my byte counter was located after the array, was stomped directly from 6 to zero, missing the “decrement and skip if zero” termination test until the array covered well into register bank 1.) Safety tip of the day: put your counter before the array!
  2. Something not addressed in the early lessons: ANSEL. The RX/DT pin of the 16F690 is shared with AN11, and the low bits of PORT C driving the LEDs are shared with AN4 through AN7. That means, unless one clears the corresponding bit in the ANSEL registers, they read as digital 0, no matter what the RX data is, and no matter what the state of my PORT C output. Toggling RC5 with a read-modify-write operation was clearing my LEDs before I could see them. Read your data sheets carefully!

A few tips/gripes on the PICkit 2 in-circuit debugging experience

  1. At least for newbies like me, and probably for more complex applications, any ICD is a great puzzle solver. At US$45 plus shipping, it is a great deal.
  2. The white triangle on the PICkit 2 programmer goes to pin 6 (near the “ICSP” silkscreen) of the AC164110—mark a triangle there to make it more foolproof.
  3. The green execution arrow stops after the line marked with the red B. I.e., the instruction with the breakpoint on it gets executed before control comes back to the user. This is counter to my habits built up using the similar looking VBA debugger in Excel.
  4. With the 16F690, you get only one active ICD breakpoint. That’s much better than zero, of course.
  5. The W register indicator in the MPLAB IDE seems not to work (stuck at zero); look at the Special Function Register window instead.
  6. Another MPLAB IDE gripe: hovering over constants in code (such as a bit number) shows the value of the File Register at that constant address. Not so helpful when I want to check which bit position I am trying to flip.
  7. Modifying special function registers in the File Register window is evidently forbidden; modify them in the Special Function Register window.

Modifying special function registers directly is a real time-saver. Instead of downloading different code to set up the baud rate registers, I edit them by hand to experiment. (And, unfortunately, my Rev. C keyboard behaves differently at different clock rates! More to come on a separate page.)