Part one of this topic gave a cursory summary of the Commodore TED series of microcomputer from the 1980s, in particular the ability of the eponymous MOS 7360 integrated circuit to manage a situation known as “ROM-over-RAM.”  The total memory capacity (RAM plus ROM) of 6502-based machines frequently exceeded the 64K address space, but the RAM “covered” by ROM never went wasted…at least in the case of the series that hit the market as the Plus/4, Commodore 16 or Commodore 116.

Writes anywhere into the 64K address space always went through to the underlying RAM (with the necessary exception of a small range of memory-mapped registers and code routines to control the behavior of TED itself), but a read could come either from ROM or RAM sharing the same address.  So while some amount of programming footwork–and thus CPU cycles–was required in order to get a byte value back, one could always be stashed quickly away in a free block of RAM.

When developing on a small system with limited hardware, there frequently arises the problem of how to log the activity of a program along the way to getting it to function properly.  In-Circuit Emulation (ICE) and trace capability may not exist for a particular microcontroller, or may be beyond the hobbyist’s budget.  Simulation can only help find bugs to the extent that the actual on-chip peripherals aren’t required, and aren’t the root cause of the problem.

So what’s a developer to do?  Sending status updates out a UART to be displayed by a terminal emulator running on another machine is a frequent means of monitoring program progress.  The Commodore Plus/4 was in fact one of the few 1980s machines to wire a hardware UART such as the MOS 6551 Asynchronous Communications Interface Adapater to an I/O port, and was the only shipping member of the TED series to do so. (More frequently the MOS 6502 CPU had to bit-bang any serial stream,which of course would slow down the program being debugged.)  Back then, multiple UART capability–now taken for granted on all but the most pin-limited microcontroller–was exceedingly rare except on the new 16-bit IBM clones, so when debugging any sort of serial application there again arose the dilemma of how to get the debugging stream out.

With the TED series members containing more than 32K RAM (the Plus/4 or an upgraded 16 or 116), debug logging was easy.  Just pick any range of memory above the BASIC variables or otherwise set to read from ROM.  Such memory is not normally in high demand because it cannot be read in a straightforward fashion, so vast quantities actually can be available.  For example, when the machine is first turned on the BASIC storage space begins at $1001 and ends at the first TED register, $FD00.  (And the power-on message is a fully 92% efficient “60671 bytes free” since $FD00 – $1001 = $ECFF.)  But the “heel” RAM of 192 bytes starting at $FF40 remain completely unclaimed, since preference must be given to the pan-Commodore “kernal” ROM vectors ($FFD2, $FFE4, etc.) occupying the same range of addresses.

So it would not be uncommon for my TED-series BASIC or machine language programs to POKE values into, say, a circular buffer that wraps through the uppermost 192 bytes of RAM.  Until the program terminates or a specific breakpoint is reached there is no need to view the buffer, so the cost of using TED to copy high RAM to a place where it can be read (or even making the RAM momentarily visible) is incurred only infrequently.

The new Microchip “EP” series of their popular 16-bit microcontroller family enables a similar FLASH-over-RAM configuration, not in those same terms but as a comeback appearance of the paging strategy that their 8-bit micros have always used.  Due to their limited (12-/14-/16-bit) instruction word size, the low-end series use a 7-bit literal address (0x00 through 0x7f) offset against a page number. Microchip’s original 16-bit families use a 24-bit instruction word to specify addresses in the range 0x0000 through 0x1fff as 13-bit-long literals, or the full 64KB range (0x0000 through 0xffff) by using the powerful register-indirect modes.

With the EP series Microchip has paved the way to access up to 16MB of data memory through the 16-bit register-indirect modes now offsetting against a 9-bit page number.  Yes, the famed Microchip data memory banking scheme that has been the bane of careless 8-bit assembly language programmers is back!  As soon as Microchip begins to offer devices with more than 64KB of SRAM–and they are getting perilously close, with the top of their line now at 54KB–this new mode will enable access to the high portions.  Any single 32KB page (other than the page corresponding to the lowest 32KB, which is always visible in the low half) can be made to show up in the high half of data memory.

The feature that is reminiscent of the Commodore TED series is that there are actually two page registers, DSWPAG and DSRPAG, which can specify a different active page in data space for reading than for writing.  According to the reference manual this is intended to facilitate quick copying of memory between 32KB pages.  Furthermore, the longstanding Program Space Visibility (PSV) feature which maps read-only program space into the upper half of data space becomes a just special case of the new paging scheme, through the allocation of an extra bit to the DSRPAG register.

So let’s cook up a TED-like example with a PIC24EP- or dsPIC33EP-series controller that requires only 32KB of the onboard data RAM.  The excess will always be accesible for write operations if DSWPAG is set to 0x01.  Reads to the high half of the 64KB data space, however, will return read-only information from the program space (very useful for character sets, look-up tables and other static data since they don’t have to be initialized at runtime) if DSRPAG is set to a value greater than 0x100. The upper half of data space can now carry a different meaning on an indirect read operation via W8 (pull constant data from flash) than an indirect write operation via W9 (push another word of log trace data):

mov #0x0101,W0
mov W0,DSRPAG ; do high-memory reads from PSV page 1 of flash…
mov #0x0001,W0
mov W0,DSWPAG ; but still do writes to the second 32KB of SRAM
bset W8,#15
bset W9,#15 ; make sure both W8 and W9 are high-memory addresses
mov [W8++],W0 ; pull a word from flash for imminent use in the program
mov W0,[W9++] ; and log that word to a debug buffer for safe keeping

Upcoming Swissembly topics will leave Commodore’s glory days behind, to explore other facets of modern embedded system design.

Advertisements