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


Beginner PIC mistakes, and detective work

September 18, 2007

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

Symbolics keyboard to PIC, step 1

September 4, 2007

The first step is to connect the Symbolics keyboard to the PIC. I am using the 16F690 which comes with the PICkit 2 starter kit on the low pin count demo board (Microchip DM164120-1). The keyboard cable mates to a 6-pin modular jack (such as Digikey part number 609-1061-ND), which I tacked onto the side of the board. Unfortunately, this mod jack has pin spacings of 50 mil “horizontally” between successive pins, so I bent up the odd pins and soldered the even pins to the demo board.

Mod jack pin Keyboard function PIC function PIC pin marking
5 GND (N/C)
4 Vdd
3 Key Data RX/DT RB5
1 /CLR RC5 RC5

My first task will be to power up the keyboard, code a scanning loop, and try to detect keystrokes for a single key, such as the Left Control Key, displaying the count of key-down events in binary to the LEDs connected to RC0-RC3. If the keyboard is not debounced by the internal microcontroller, the count will not increment cleanly, but I hope to at least prove that I can talk to the keyboard and make sense of what comes back. I’m not sure how much current the keyboard will need, so I might have to power the demo board with an external supply.

[UPDATE: It turns out the standard numbering of modular jack pins is the reverse of the pin numbering of the P1 header inside the keyboard. I’ve corrected the table above to reflect the standard modular jack scheme. Looking into the opening of the jack, with the locking tab down, pin 1 is on the left side.]

Debouncing switches

August 30, 2007

I made a little exercise out of compacting the example “switch debounce” code that the PIC tutorial examples uses. My next exercise will be to improve the debouncing in the “reverse variable speed LED rotation by pressing switch” by interleaving the debouncing check into the delay loop. As it stands, when the rotation is slow, the example can miss brief switch pushes.

My glorious savings of three instructions is documented on a separate page.

One nifty trick I found through Google that might be very helpful if I have to debounce 88 keys on a Symbolics keyboard (naturally, the same number as on a piano) is called “vertical counters.” This consists basically of replacing counter increments with boolean operations, which can be easily performed in parallel, if the corresponding bits for multiple counters are grouped in register-sized words.

This page shows how to use a four-count two-bit vertical counting scheme to debounce eight switches in parallel.

Learning more about PIC

August 27, 2007

A few comments about the PICkit 2 learning experience.

There’s a slight bit of polish that could be applied to the example code.

  1. A few redundant instructions, such as
    • Extraneous operations setting register pages
    • In A-to-D examples, the data sheet seems to say the 5 microsecond settling time is needed only when changing the input source, not for every conversion, as in the examples
    • For the 5 microsecond interval, a few of those microseconds are covered by the non-NOP instructions before the conversions
  2. In one of the variable-speed rotating bits examples, the carry flag is not explicitly cleared when it needs to be clear. When I modified the example to change the sign of the pot setting-to-delay conversion, I would sometimes set the carry, putting extra bits into the display. Took me a good fifteen minutes to debug that.
  3. I think a few extra instructions are wasted using the W register and an explicit move to the file register when the file register destination could be used instead

I also got bitten by the issue mentioned briefly in the PICkit 2 release note: if you program the examples from the IDE, the IDE forces the line controlled by the push-button low, meaning the push-button examples fail to work, unless you program the device from the dedicated programming application and the .HEX file produced by the IDE.

I am slightly disappointed that there doesn’t seem to be any visible progress getting the PICkit 2 with version 2 firmware to work under Mac OS X.

Also, I find a real lack of documentation of the PICkit 2 “Debug Express” support for in-circuit debugging. This may be because Microchip doesn’t want to undercut sales of the MPIDE 2 hardware. I think, however, one can use a combination of the AC162061 (containing an ICD version of the 16F690) and AC164110 (to convert the ICSP six-pin interface to the modular plug used by the usual ICD interface) to do in-circuit debugging of 16F690 applications with the PICkit 2, at an additional cost of about $50.

I’ve started sketching out some ideas for interfacing the Symbolics keyboard on a dedicated page.

[UPDATE: Microchip does, after all, document the PICkit 2 Debug Express hardware requirements (scroll down a bit to see what I missed before.) I ordered the combination even before I found the document, and when the backorder is filled, I will be giving it a try myself.]

[UPDATE: Jeff Post announced that he releasing alpha code supporting v2 firmware for the PICkit 2 on Linux/Mac OS X]

Making lights blink…

August 21, 2007

My latest diversion is a Microchip PICkit2. The idea is to make something that can understand the Symbolics keyboard I have, and then connect that something to other things that can speak Apple Desktop Bus (ADB), PS/2 keyboard protocol, or USB, in roughly that order. If I can make something that takes a multi-button PS/2 mouse and a Symbolics keyboard and connects both to a MacIvory, I could be set for beautiful three-button mousing and classic keyboarding on my Lisp Machine.

I’ve mostly traced out the schematic of my Rev. C Symbolics slim-line keyboard (thank god for simple two-layer boards!). Rev. C has LED’s in the Caps Lock and Mode Lock keys, in contrast to this picture of the similar Symbolics Rev. B keyboard. Compared to the Symbolics 3600 keyboard schematic, mine is roughly similar, but unfortunately has a 40-pin microcontroller (an Intel 8749H, a member of the MCS-48 family) soldered in. I am certain I could make something work with the simple protocol the 3600 keyboard apparently implements, but if the microcontroller does anything beyond driving the LEDs on and off based on simply counting the corresponding keystrokes, I might be sunk. I’ve fired off a few questions to people who can hopefully tell me that all of these are plug- and wire-compatible.

As for the 3600, it is pretty obviously a matter of pulling the reset line low to clear the counters, and clocking through the other 127 counter states to read off the switch matrix closures on the 16 X by 8 Y (I surmise that high on the output would mean the corresponding key is down.) I’m not sure how frequently I have to collect the bits to avoid missing keypresses, and what debouncing I might have to do.

The strange thing about my Rev C is that the ICs driving what I guess is the X direction are a pair of 74145 devices with what the datasheet claims are open-collector outputs, and the IC connected to what I guess is the the Y direction is a 7442 with conventional TTL outputs. That seems to mean that scanning an X column with a pressed key causes an open-collector pulling low to compete with the TTL high output on the Y row, except when the Y scan tests that line with a TTL low. What good that does is a mystery. That, and I haven’t finished tracing out the part of the circuit with an LM319 comparator. The 3600 schematic drives the X columns (one low, the rest high) and muxes the Y rows (driving ordinary inputs through any pressed keys) to the readout.

[UPDATE: Seems that the keyboard protocol should be identical, so I’m going to forge ahead with the plan, and assume the circuit knows how to work itself.]

[UPDATE 2: fixed the link to the online 3600 schematic.]

[UPDATE 3: I probably should have given more explicit acknowledgment for the inspiration of the project. If I had not seen asciilifeform‘s schematic revealing the simplicity of the protocol, I’m sure I would have been far less tempted to start this project.]

MacIvory speaks!

August 8, 2007

I’ve only had a bit of time to play with my MacIvory, but already things are getting interesting.

One is getting used to the system administration style: typical UNIX system configuration resides in text files, and the boot process reads them. Genera is different. The state of the system is contained in the memory image (“world”); you change it through various operations—some interactive, some by loading Lisp files—and preserve it by saving a new world as a file, which can be defined incrementally based on an existing world. The boot process involves loading that saved file back into the living Lisp machine. I haven’t yet developed the sense to complete a block of tasks before saving the world, and how much change pushes one from incremental to a complete world.

Another was getting the network to speak, and part of that is the timewarp of working in Mac OS 7, an era in which Mac networking was going through the introduction of Open Transport, and an AppleTalk era which Mac OS X refuses to acknowledge. Luckily, I’ve got a PowerBook G3 that runs Mac OS 9. My first ethernet card didn’t work, either because I screwed up some software setting or because the hardware was bad. (More embarrassing disclosure later.) DKS sent me a replacement, which worked immediately. I’ve only got ChaosNet configured on the MacIvory side at this point, and my ChaosNet work isn’t up-to-date on my Powerbook, so I’ve only seen raw ethernet packets in tcpdump, but my archaeology is already progressing—documentation to follow soon, as well as getting some Python software (with libpcap or Mac OS X kernel packet filters?) to respond to Chaos-formatted Ethernet packets.

As for the embarrasing disclosure, one of the first things I did was try to set the video card to a mode not supported by my Sony Multisync 15sf monitor. Instead of waiting for the change to timeout and revert, I hit Esc or Command-. or some other key which confirmed the change, leaving me with a blank screen. I tried various reboot, PRAM zapping, or magic key sequences to force the Radius Precision Color 24X to a good mode, but none of that worked, and at some point I screwed up the system. Once I hooked up the Dell 2007fp that understood 1152×870, I saw the floppy-with-blinking-question-mark. Recovery without a working network card involved the ancient hassles of multiple-floppy installs.

I have a Kensington ADB multi-button mouse, but all the drivers I have downloaded are either for Mac OS 8 or cause serious bugginess: system freezes or error -192 when launching the configuration application. I hope I don’t have to roll my own software to get multi-button goodness to work with the Ivory. (At this date, few vendors pay much attention to 68k Macintosh support.)

UPDATE: I’ve captured a bit of the tcpdump results in my ChaosNET information page.

Ordering a Lisp machine

July 11, 2007

Just sent off the Paypal payment for a MacIvory II system with 2.6 MW of memory. I’m hoping also to get a Symbolics keyboard, although Symbolics is apparently out of the ADB box that allows the keyboard to be used with the vintage Macs.

It was a tough call whether to splurge for this or, for about twice the money, a new MacBook Pro. I’m hoping the Symbolics machine will be much more entertaining.

My main idea of a project is to use the Lisp Machine as a Chaos FILE host, in order to allow development on the CADR simulator with a versioned file system, without having to simulate and learn ITS or TOPS-20.  To get that to work, I probably will need to do a little bit of investigation to understand how the Symbolics box gets configured to talk on the network, what Chaos packets look like on the Ethernet, how to get those to my Python/Lisp code on the modern machine, and, for data security what would be needed to talk to a CD-ROM drive on a remote computer, or to use a remote computer to do backups (to a simulated tape drive?).  In order to get 2.6 MW of NuBus memory, I had to choose a Mac config without a CD-ROM drive, and I’m not too excited about trying to get an external SCSI drive for this old machine. Backing up to floppies is another thing I don’t want to relive.

Some other things I’m looking forward to are Zmail, Concordia (to generate HTML output, anyone?) and Document Examiner,  using CLIM, and grokking the Symbolics compiler(s).

Moving to…

April 10, 2007

Well, I’m trying out, mainly because the database fee on, while quite reasonable, is a substantial fraction of the cost of hosting my WordPress-based blog. (If I find a blogging system—or roll my own—which does not require a MySql process, but can run with Sqlite or a similar library, I’ll probably switch to that, and keep NFSN as my main site.).

Secondarily, I hope will keep me from having to worry about WordPress releases. I’m not sure what I will lose in the process, but this is the easiest way to find out. I’m assuming it will include

  1. Losing Google Adsense (not that I was making anything)
  2. Losing the ability to embed a site-metering plugin, to see where my clicks are coming from (but we’ll see what tracking tools provides)
  3. Limit my ability to hack WordPress (which was not very high on my list, except to get Lisp code to look nice) and use funky plug-ins
  4. 50 MB storage limit

Note that I apparently had to upgrade to WordPress 2.1 on the original site in order to get the Export functionality that let me make the move. (I had to guess…the documentation on touts the ease of migration, but isn’t clear on this point.)

UPDATE: I just turned on re-direct for the original, so my traffic, such as it is, should all be coming here. I actually am liking the Blog Stats that is able to provide. I’m assuming it is getting as much data as was able to provide, and the blog stats summary gives me a quicker impression as to what search terms are leading to the site.

My non-blog web site

March 13, 2007

I should mention my non-blog site, which exists pretty much to hold information for recruiters who want to get some idea of my software experience. Don’t expect much exciting there. I am, by the way, currently and happily employed, but am interested in opportunities in the New York City metropolitan area.