Now that loading into on-chip EEPROM is working, I have written a few standalone utility routines so that the final program will not need to
rely on the BUFFALO monitor (which isn’t available in some operating modes).
Simple things, such as output via the serial-port, analogue-to-digital sampling, digital input port reading and so on. This allows me to test and debug other parts of the program in the (measly) 326 bytes of available RAM, without having to download the utility routines: once debugged, I load them into EEPROM where they remain even across power-cycles.
However, this assembly-code lark is not as easy as it could be – I am making very few mistakes, but when you make one it can take ages to track it down – no GUI debuggers here, and I still haven’t quite adjusted to this level of programming. Getting there, but still occasionally dropping into inappropriate “high-level programming” habits.
The BUFFALO monitor has some debugging facilities: line-by-line assembler/disassembler, single-step, trace-until-address, register-dump to terminal, line-by-line interactive memory-modify, interactive register-tweaking, and even a breakpoint facility. Given that the on-chip BUFFALO ROM also includes the downloader, terminal routines, 4 different host-port device-drivers (SCI, SPI, ACIA, DUART), command-parser, EEPROM programming routines, S-record decoder, et al, it really is a remarkably compact program.
Whilst writing a standalone function to convert binary register contents into ASCII hexadecimal, I needed to be able to inspect the ALU condition-codes at specific points, which would have been somewhat cumbersome. Fortunately, the LEDs on the breakout board I built earlier can be used for exactly this, even though I had originally intended them just for playing about with, for fun. It only takes a couple of instructions to dump a nibble to the 4 LEDs, so I could use a technique a little like the old “insert a few printf() calls” method (which I cannot use here as there is no printf() in this deliberately minimal environment), but instead of printing trace messages to the terminal, we display bit-patterns on the LEDs. Of course, it also required inserting the occasional delays, otherwise the patterns would flash by too quickly to be seen: but that was easy too thanks to the programmable-delay routine I wrote earlier (which now lives permanently in EEPROM)… this “illuminating” debugging technique is quite useful, and has the advantage of a certain amount of prettiness, it’s almost hypnotic. Reminds me of watching the changing front-panel lights on an old huge PDP-11 I timeshared in the early 80s…
A 68hc11 Idiosyncracy
trying to squeeze 68hc11 program-code to the smallest size possible, so that it will fit into the small on-chip memory, led to an interesting discovery: indexed addressing using the Y index-register makes instructions 1 byte bigger than when using the X index-register.
One of the “selling points” of the 68hc11 was that it had *two* index-registers (block-pointer registers) instead of the single one available on the older 6800 and 6805 processors. Experience had shown Motorola that a single index-register on the older parts had been quite limiting and inconvenient to application programmers…
On the 68hc11, Y-register indexing is signalled by a constant instruction-prefix byte, which can be very wasteful of memory-space in a highly-constrained environment. Thus I have discovered the 68hc11 “rule-of-thumb”: use Y-register for indexed addressing only sparingly, try to get all the frequently-accessed data either in zero-page RAM (8-bit absolute address) or within range of an 8-bit offset from the X register (8-bit offset address).
Of course, I had initially used Y-indexed addressing everywhere, so was running out of RAM… now fixed to do it the “other way around”, amazing how much smaller everything has become!