Page 109 - The Art of Designing Embedded Systems
P. 109
96 THE ART OF DESIGNING EMBEDDED SYSTEMS
Turn ROM on when A15 is low. Run A0 to A14 into the ROM. As-
suming we’re mapping a 128k x 8 ROM into the 32k logical space, gener-
ate a fake A15 and A16 (simple bits latched into an output port) that go to
the ROM’s A15 and A16 inputs. However, feed these through AND gates.
Enable the gates only when A15 = 0 (RAM off) and A14 = 1 (bank area
enabled).
RAM is, of course, selected with logical addresses between 8000 and
FFFF. Any address under 4000 disables the gates and enables the first
4000 locations in ROM. When A14 is a one, whatever values you’ve stuck
into the fake A15 and A16 select a chunk of ROM 4000 bytes long.
The virtue of this design is its great simplicity and its conservation of
ROM-there are no wasted chunks of memory, a common problem with
other mapping schemes.
Occasionally a designer directly generates chip selects (instead of
extra address lines) from the mapping output port. I think this is a mistake.
It complicates the ROM select logic. Worse, sometimes it’s awfully hard
to make your debugging tools understand the translation from addresses to
symbols. By translating addresses you can provide your debugger with a
logical-to-physical translation cheat sheet.
The Sohare
In assembly language you control everything, so handling banked
memory is not too difficult. The hardest part of designing remappable code
is figuring out how to segment the banks. Casual calling of other routines
is out, as you dare not call something not mapped in.
Some folks write a bank manager that tracks which routines are cur-
rently located in the logical space. All calls, then, go through the bank
manager, which dynamically brings routines in and out as needed.
If you were foresighted enough to design your system around a real-
time operating system (RTOS), then managing the mapper is much sim-
pler. Assign one task per bank. Modify the context switcher to remap
whenever a new task is spawned or reawakened.
Many tasks are quite small-much smaller than the size of the logi-
cal banked area. Use memory more efficiently by giving tasks two bank-
ing parameters: the bank number associated with the task, and a starting
offset into the bank. If the context switcher both remaps and then starts the
task at the given offset, you’ll be able to pack multiple tasks per bank.
Some C compilers come with built-in banking support. Check with
your vendor. Some will completely manage a multiple bank system, auto-
matically remapping as needed to bring code in and out of the logical

