The last week of fiddling with the 68hc11 EVBU SBC has been a bit of a slog, with not much productive output…
The first task was to write a reliable parameterised “delay” routine, so I could ditch the awful mechanical workaround (wedge a keyboard key down!) I had previously used for the LED-flasher program.
This took a bit of trial-and-error, but made it in the end: a routine that sleeps for the number of milliseconds passed in the 16-bit X index register. The timing is based on a cycle-counted loop rather than the on-chip hardware-timers, but it is accurate, reliable, and scales from 1ms to over a minute. It was quite fun to play with programmable delays for the LED-flasher program, you can get some funky visual effects that way.
The 68hc11 has a *very* nice feature – on-board EEPROM, which can be used for program storage, static data, dynamic data or all three. On the 68hc11E1, there is 512 bytes of EEPROM, plenty for what I have in mind, given that 68hc11 object-code can be very “dense” if you avoid floating-point or excessively 16-/32-bit operations.
The 68hc11 was the first commercial CPU/MCU to contain on-chip EEPROM, and Motorola implemented it very well. Unlike Flash memory, EEPROM can be erased/written a byte at a time, but requires quite a bit more than 5V to do so. Many early EEPROM-containing CPUs required the chip to have auxiliary 9V (or 12V or even 20V) power-supply lines to provide the voltage needed to erase/write/rewrite EPPROM cells.
Motorola avoided the need for wacky power voltages by implementing on-chip charge-pumps, so the 68hc11 chip can directly program both internal and even external parallel EEPROM, using the chips’ normal 5V power input line. Neat!
The slight drawback is that there is a specific sequence of events needed to program an EEPROM cell, particularly a 10ms delay needed for the charge-pumps to charge on each erase/write operation. Fortunately, Motorola had the sense to make the EEPROM erase/write operations controllable directly under program control, so you can write a 68hc11 subroutine to perform EEPROM-modification operations – no special auxiliary hardware needed, it’s all internal.
So, armed with a mini-application that runs from on-chip RAM, the next step for me was to get the program into EEPROM, so that I don’t have to keep downloading it to the chip, which can become very tiresome after a while…
The on-chip BUFFALO ROM monitor can in principle directly load a download into EEPROM, but the BUFFALO implementation is quite slow, and as the 68hc11 built-in serial (5V RS-232) interface has *no* flow-control, when downloading at the default slow speed of 1200 baud, the BUFFALO S-record-conversion-and-EEPROM-rewrite routine stalls hard, requiring a reset.
For very small programs, such as the LED-flasher from the last episode, I was able to use the BUFFALO “modify memory” command to program the EEPROM bytes one at a time by typing each MM command “by hand” at the terminal. This worked OK, but there is no way such a method is going to be feasible for anything but utterly trivial programs.
A common alternative is to download a (custom) EEPROM-programming program into RAM, and execute it there. Such a program can be written in such a way as to read address/data values from eg: the serial-port, and to then program the requested bytes from that data.
Of course, you are still faced with the “no-flow-control” and potential serial-overrun problem, and would also have to code-up your own “protocol”, such as an S-record decoder, for the download format. Although there are examples of such 68hc11 programs around on the ‘net, none of the ones I could find could deal with the flow-control issue without requiring custom or special host-resident software or full UART external hardware; plain-old terminal-emulator host software talking to an EVBU just isn’t going to cut it for EEPROM programming. It’s fine for RAM programming using BUFFALO, as that is very fast, way fast enough to keep up with download speed.
Time to look for other alternatives…
The EVBU comes with Motorola-written DOS software that provides a character-mode GUI (!) for talking to the 68hc11, including download-to-EEPROM commands. These download a special program to RAM, that then uses a mysterious (undocumented) protocol to sequence the download of EEPROM data. Let’s give it a bash!
First problem: PCBUG11 is only provided on 800k Mac Classic floppies or 5.25-inch DOS floppies – and I do not have such ancient drives. Fortunately, it can also be found on third-party sites on the ‘net, so one quick download later and I was ready to rock.
I had planned to use an old 1998 Toshiba laptop to run PCBUG11, but it has no Ethernet interface. No problem, let’s use 3.5-inch sneakernet to get the software over… ouch, the diskette drive on my SPARCstation is dead. Plan B: I have a USB 3.5-inch diskette drive, so could copy over from the modern home PC. OK!
Unfortunately, the ancient PCBUG11 software was written using 8086 blind timing-loops for synchronising communication with the EVBU, and therefore fails utterly on any PC running at more than 80MHz.
I suppose that in 1985, the idea of a PC running at more than 16MHz seemed pretty remote, and speeds above 200MHz was surely several decades away (ha!); I’m still upset with Motorola about this daft way PCBUG11 was written.
On the ‘net, from a 1998 Motorola listserv, there is a binary patch for the PCBUG11 executable that relieves the issue, and allows PCBUG11 to work on 166MHz PCs, but it was still no-go on my 233MHz Pentium-II.
As Dick Dastardly would say: “Drat! And double-drat!”
Back to The Job
OK, we’ll defer the bulk-load-to-EEPROM for now, and get back to a bit of assembly-language programming again.
Although the 68hc11 is quite a capable 8-bit CPU, the lack of stack-indexed addressing is a royal pain: the only explicit stack-relative memory-operations available are PUSH/PULL of an 8-bit acculumulator or 16-bit index-register. For someone like me, coming from a C background, it required quite a head-switch to get used to passing function-parameters in registers or even fixed memory, rather than “just push it all on the stack and access it from there”. The very few registers available (A, B, X, Y), and the “syntax style” of the 68hc11 standard assembly language made it all the more confusing at first.
Obvious examples are that “inc b” and “incb” are not the same operation at all: the first increments an 8-bit memory-location, the other (implicitly) increments the B register, and I frequently got it the wrong way around. I’m just not used to that kind of thing: in SPARC-land, general registers are *always* explicit, and direct memory operands typically use explicit register-indirect index-notation. I should not have been troubled by this head-switch, because I used to program in Z80, 7809, 68000, NS32016, and a few other assembly languages, all with their own idiosyncratic ways of looking at things: but that was all over 25 years ago, and I have just become unacclimatised!
Lesson: having programmed in a couple of 8-bit assembly-languages a few decades ago does not mean you’ll pick up a new one at all quickly.
The other “Doh!” moment I kept having when using the BUFFALO “load” command, was downloading the assembly-code file instead of the assembled object-code, which of course sends BUFFALO into fits, requiring a reset. The tell-tale sign is when the terminal emulator reports “123 lines downloaded” for what should be a tiny program (compiled to 7 object-code S-records)… “Darn! I didn’t mean to do that… again!”
More Progress At Last
Back in RAM-land, the next task was to write a program to demonstrate (1) ability to report binary byte-values in ASCII hex to the terminal, and (2) a sounder grasp of conditional logic in assembly: a program to output a formatted, line-wrapped, block of all 8-bit binary values in ASCII hex.
NOLF EQU 1 * if host is tip or minicom, then * we don't need line-feeds putc EQU $ffb8 getc EQU $ffcd include(lib.asm) CR EQU $0D LF EQU $0A ORG $0100 init ldab #$0 bra body loop pshb pula anda #$FF beq nextblk anda #$0F beq nextlin body pshb pula anda #$07 bne report ldy #3 loopy ldaa #' ' jsr putc dey bne loopy ldx #500 jsr delayms report pshb pula jsr puthex ldaa #' ' jsr putc incb jmp loop nextlin jsr newline bra body nextblk jsr newline ldx #750 jsr delayms jsr newline bra body newline ldaa #CR jsr putc ldaa #NOLF bne skiplf ldaa #LF jsr putc skiplf ldx #333 jsr delayms rts * print register A value to terminal as 2 hex-digits * NOTE: the BUFFALO nibble-hexification routines * trash the A register!!! puthex psha jsr $ffb2 pula jsr $ffb5 rts
This went quite quickly, although it still leans on BUFFALO subroutines more than I would ideally like, rather than being more self-contained. However, the conditional bits are good, as can be seen in the video (the background sound is “Special Ops Force” on TV, but count yourselves lucky – earlier on today it was 1977-vintage “Wonder Woman“…)
Breakthrough: we have reliable download to EEPROM, even using dumb terminal emulator (Solaris “tip”)!
The trick is to use a BUFFALO “modify memory” command to update one of the 68hc11 memory-mapped control-registers to set the on-chip SCI baud-rate to just 300 baud. It means having to connect at the default baud-rate (1200), then switch, disconnect then reconnect at 300 baud, before downloading, but that’s way easier than typing the object-code bytes in by hand one at a time:
sol% tip evbu connected >MM 102B 102B 30 35@^%^[ [EOT] sol% tip evbu -300 connected >load t ^[>Local file name? eel.s19 4 lines transferred in 0 seconds ! done >
As shown, this slow speed gives the BUFFALO “load” command has enough inter-byte time to program each EEPROM location. The LED-flasher is now running directly from EEPROM without having to type in the object-code a byte-at-a-time.