Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Memory mapping in CP/M -- or 8 bit in general

10 views
Skip to first unread message

Norm Dresner

unread,
Jul 12, 2004, 1:18:03 PM7/12/04
to
I've personally used bank switching since ~'83 to expand the amount of
memory available to CP/M programs but I was wondering the other day if
anyone has ever actually implemented a hardware memory mapper to facilitate,
say, multitasking or just plain expansion of available 64K RAM space.

TIA
Norm

Randy McLaughlin

unread,
Jul 12, 2004, 2:28:18 PM7/12/04
to
"Norm Dresner" <nd...@att.net> wrote in message
news:fJzIc.239780$Gx4....@bgtnsc04-news.ops.worldnet.att.net...

Maybe I just don't understand your post.

I am looking at emulating bank switching in software for an eZ80, but bank
switching is a hardware memory mapper.

Memory mapping can be simple as in how CompuPro did it, a little more
sophisticateed as in how CompuPro, through how Tarbell did it and through
how Hitachi did id it for the 64180.

The sad thing is that Zilog did it like CompuPro did for the eZ80 (CompuPro
drives the high 8 bits through a latch for extended addressing giving you
64K banks for the 8085 and 1mb banks for the 8088).

Randy


Jack Peacock

unread,
Jul 12, 2004, 4:25:58 PM7/12/04
to
"Norm Dresner" <nd...@att.net> wrote in message
news:fJzIc.239780$Gx4....@bgtnsc04-news.ops.worldnet.att.net...
The problem with bank switching is the lack of granularity, especially if
you are using CP/M V3 or MP/M. An address translator that maps discrete
pages to any physical page allows for full use of every board and also makes
copying easier since the source and destination pages can both be in the
logical space.

I built an S100 card with a small TTL RAM to take the high four address
lines from the CPU (A12-A15) and use it to select one of 16 locations to
output the high 8 address lines (A16-A23). Not ideal but it worked with
most 16-bit only CPU cards coupled with 24-bit address memory, without
extensive mods to the CPU card. Timing wasn't quite to bus standards but
did work with most cards, even some DRAM versions. It did work with DMA by
disabling outputs during DMA cycles, since all the DMA cards I had were
already 24 bit address.

One of the best implementations (pre-HD64180/Z180) was the Intersystems Z80
XPU-B, which allowed each 4KB logical page to be mapped to a 4KB boundary
anywhere in the first 512KB of address space in an S100 bus. The XPU also
had provisions for making a page read only, or setting a dirty bit if the
CPU wrote to it. It wasn't perfect since it couldn't detect DMA writes to
set the dirty flag, but that was more an OS issue. The memory translation
was ideally suited to CP/M V3 and MP/M multi-tasking.
Jack Peacock


Fred J. Scipione

unread,
Jul 12, 2004, 11:07:33 PM7/12/04
to

"Norm Dresner" <nd...@att.net> wrote in message news:fJzIc.239780$Gx4....@bgtnsc04-news.ops.worldnet.att.net...

This is probably too specialized to be of much general interest, but since
you asked - here is my scheme for expanding a 64k dram machine to
256k (Your Mileage Will Vary). The ShoeBox is a single board Z80
computer (Columbia M64 Commands). ASCII graphics best viewed
w/ a fixed spacing font!

74LS00: 5 ___ O +5 V
1 ___ P2 >----! \ 6 !
P1 >---o----! \ 3 4 ! )O---+ ! 14
! 2 ! )O-----------!___/ ! 9 _I_
+----!___/ 12 ___ +----! \ 8
! 7 A15 >----! \ 11 10 ! )O----> V
! 13 ! )O--------!___/
GND --- A14 >----!___/
-
MUX* >------------------o-----------------------------+
! !
V >--------------o---)-------------------------+ !
! ! ! !
P2 >----------+ ! ! RFRSH >-------+ ! !
! 9 !10 !11 ! 9 !10 !11
+------------+ +------------+
12 ! S2 S1 S0 ! 12 ! S2 S1 S0 !
A14 >---!D7 ! R7 >--o---!D7 !
13 ! ! !13 ! !
A15 >---!D6 ! o---!D6 !
14 ! 74LS151 ! !14 ! 74LS151 !
V >-o---!D5 "A" ! o---!D5 "B" !
!15 ! ! 5 !15 ! ! 5
o---!D4 Y !----> M8 +---!D4 Y !----> M7
! 1 ! ! 1 ! !
o---!D3 ! "1" >-o---!D3 !
! 2 ! 8:1 MUX ! ! 2 ! 8:1 MUX !
+---!D2 ! +---!D2 !
3 ! ! 3 ! !
P0 >----!D1 ! A14 >----!D1 !
4 ! ! 4 ! !
P1 >----!D0 ! A15 >----!D0 !
! G* GND VCC ! ! G* GND VCC !
+------------+ +------------+
! 7 ! 8 !16 ! 7 ! 8 !16
o---+ ! o---+ !
! ! ! !
GND --- O +5 V GND --- O +5 V
- -
---- +------------+
+------------+ A ! +------+ !
1 ! ! 8 ! ! ) '00 ! !------O +5 V
RFRSH >---!CLK-1 Q2D!---> R7 ! ! 1------+ !---< A15
6 ! ! ! ! +------+ !---< A14
+-<-!Q1D ! ! ! )'151-A! !------> M8
!14 ! 74LS393 ! ! ! 1------+ !---< P2
+->-!CLK-2 ! 2.4" ! +------+ !---< P1
2 ! DUAL ! ! ! )'151-B! !------> M7
+---!CLR1 4 BIT ! ! ! 1------+ !---< P0
!12 ! COUNTER ! ! ! +------+ !---< MUX*
o---!CLR2 ! ! ! ) '393 ! !---< RFRSH
! ! GND VCC ! V ! 1------+ !------V GND
! +------------+ ---- +------------+
! ! 7 !14
+-----o ! ! !
! ! !<---1.2"--->!
GND --- A +5 v BOARD LAYOUT
- V (COMPONENT SIDE)

Tie pin 1 of all (8) RAM chips together and pull up to +5 V through
a 1/8th watt 1K ohm resistor on the bottom of the board. Wire circuit
as shown on a small piece of perf board (1.2" x 2.4") with low profile
sockets and 30 ga. wirewrap wire. Solder connections to mother board as
follows:

Signal: Connection:
(Name) (IC no. - pin no.)

+5 V U15-16
Gnd U15-8

A15 U15-2
A14 U15-3

MUX* U15-1

RFRSH U37-12

P0 U10-13
P1 U10-11
P2 U10-10

M7 U5-9
M8 U5-1

(Note the major role of U15, one of the dynamic RAM address
multiplexers.)


Cut the trace on the top of the board from U15, pin 4 to resistor
pack AR2, pin 4. Insert chips in circuit. Reassemble the computer,
leaving off the top cover. Computer should still run normally.

Secure the circuit over U14 and U15 with double sticky foam tape.
Replace the 64 K RAM chips with 256 K chips. Computer should still run
normally, but with BIOS control of banks also functional. Replace the
top cover.

Banks are controlled by U10, port C, bits 4, 6, and 7. These bits
can be controlled by writing the properly masked values to port 057H
or by sending bit set/reset command values to port 054H. Bit 4 is the
least significant bit of the bank no. and bit 7 the most. Banks 0-4 are
available in the lower 48K of RAM. Bank 5 is a repeat of bank 4 and
banks 6 and 7 are repeats of bank 0 (this is a feature, not a bug).

Scott Moore

unread,
Jul 13, 2004, 5:04:47 AM7/13/04
to
Norm Dresner wrote:

I worked for one company that used the scheme like the one mentioned by
Jack Peacock. A TTL 256*8 ram was used to take the upper 4 address bits of
the Z80 with a 4 bit select register and gave the top 8 bits of a 20 bit address
as a result. The net effect was to give 16 different address maps selectable
by the "bank select" register, each address map having an arbitrary collection
of 16 4kb pages selected from a 1mb total address space.

The system was used much like a standard bank selection system, with the "kernel"
system (a collection of I/O routines) at the bottom of each address space, and
various modules of the system above that. Calls between sections were performed
by special routines in the kernel that were called by one module, then flipped
address maps to the target module and made a call on behalf of the original module.
I improved the system somewhat by creating a call that was able to call arbitrary
addresses anywhere in the address space, instead of having a single call for each
"cross module" call type.

I later got a 254kb static memory module for my home Z80 computer, and, of course,
wanted to access all memory. After considering several techniques, I decided on
a very simple bank selection scheme where the bank select register simply provided
the upper 2 bits of the address (actually, it drove 8 bits of the 24 bit S-100
extended address space). It used no fixed bank sections. If you changed the
bank, the floor dropped out from under you, there was no section in common
with the new bank.

What made it work was that a bit existed that would cause writes to go to another
bank besides the one being run from. This allowed the other banks to be set up
before entering full bank addressed mode. A small peice of code was laid at the
beginning of all banks that switched from one bank to a specified bank when
called, then executed a specified location in that bank. Because all banks had
this identical code, it didn't matter if the bank was changed inside that code,
since it was identical in all banks.

The result was an extremely simple bank selector, and full use of the 64kb
in each bank, not just a fixed/transient bank section. This was used to create
the first version of OS/Z, a full multitasking CP/M compatible operating system.

I include the latter mainly to show that bank selectors/memory managers don't have
to be complex. A lot of the work can be shuffled off to software.

--
Samiam is Scott A. Moore

Personal web site: http:/www.moorecad.com/scott
My electronics engineering consulting site: http://www.moorecad.com
ISO 7185 Standard Pascal web site: http://www.moorecad.com/standardpascal
Classic Basic Games web site: http://www.moorecad.com/classicbasic
The IP Pascal web site, a high performance, highly portable ISO 7185 Pascal
compiler system: http://www.moorecad.com/ippas

Being right is more powerfull than large corporations or governments.
The right argument may not be pervasive, but the facts eventually are.

Norm Dresner

unread,
Jul 13, 2004, 2:36:48 PM7/13/04
to
"Jack Peacock" <pea...@simconv.com> wrote in message
news:TImdnfWIzrB...@mpowercom.net...

Thanks, I'll follow up on that one.

Norm

Randy McLaughlin

unread,
Jul 13, 2004, 4:35:27 PM7/13/04
to
"Norm Dresner" <nd...@att.net> wrote in message
news:4ZVIc.246611$Gx4.2...@bgtnsc04-news.ops.worldnet.att.net...

Tarbell's CPU also use bipolar RAM to map any 4K of 24 bit addressed RAM
into the Z80's 64K addressing space.

The up side is that you could address any 4K anywhere the downside is that
you generally had to re-map several blocks to do the effective bank swapping
(usually all 16 blocks were re-mapped at once even though you could get away
with only 12).

Systems like Cromemco or the SuperIO's internal RAM can do bank swapping
with one out command, Cromemco re-maps 48K at a time and the Super IO
generally re-maps 32K at a time.

Randy


Norm Dresner

unread,
Jul 13, 2004, 8:53:12 PM7/13/04
to
"Randy McLaughlin" <ra...@nospam.com> wrote in message
news:ZHXIc.2547$%Q4....@bignews2.bellsouth.net...

>
> Tarbell's CPU also use bipolar RAM to map any 4K of 24 bit addressed RAM
> into the Z80's 64K addressing space.
>
> The up side is that you could address any 4K anywhere the downside is that
> you generally had to re-map several blocks to do the effective bank
swapping
> (usually all 16 blocks were re-mapped at once even though you could get
away
> with only 12).
>
> Systems like Cromemco or the SuperIO's internal RAM can do bank swapping
> with one out command, Cromemco re-maps 48K at a time and the Super IO
> generally re-maps 32K at a time.
>
> Randy
>

My own Z-80 S-100 system for which I modded cards and added others, some of
my own doing, does bank switching, 32K at a time IIRC. But this is
definitely not the same thing as memory mapping.

Norm

Randy McLaughlin

unread,
Jul 13, 2004, 10:08:54 PM7/13/04
to
"Norm Dresner" <nd...@att.net> wrote in message
news:Yt%Ic.248270$Gx4....@bgtnsc04-news.ops.worldnet.att.net...


While bank switching and memory mapping have technical differences the way
it is applied to these Z80 S100 systems makes the differences moot in most
cases.

As an example the Tarbell CPU does a comprehensive memory mapping where any
4K block can be mapped and Cromemco has a much more crude mapping by
switching in 48K at a time. Both are doing true memory mapping and both do
so by bank switching where the tarbell has 4K banks and can switch multiple
banks in at a time the Cromemco has up to 8 48K banks where only one can be
switched in at a time and only to one base address.

The Tarbell has the MMU on the CPU card and the SuperIO and Cromemco has the
MMU on the RAM card.


Randy


Amardeep S Chana

unread,
Jul 14, 2004, 7:54:59 AM7/14/04
to
Randy McLaughlin wrote:
>
> the Cromemco has up to 8 48K banks where only one can be
> switched in at a time and only to one base address.
>


Randy,

The Cromemco banking system is not limited to a single base address nor
a single block size. There are, as you mentioned, 8 active banks each
represented by one bit in port 40h plus the ninth "phantom" bank.

In their scheme, a memory card can have one or more blocks of any size.
A block's base address can be at any location and it may be active in
more than one bank including the "phantom" bank.

The 4KZ and 16KZ have one block addressable on their respective size
boundary. The 64KZ has two blocks of 32K each which can be located at
0000h or 8000h. The 256KZ can be configured by a PROM but Cromemco
didn't seem to publish how this was done. The PROMs they sold mapped a
linear array of memory (designed for IEEE-696 use) back to an 8-bit
bankable array compatible with Z-80 Cromix.

Their graphics system used cards called 48KTP which were a single 48K
chunk addressable on any 16K boundary. The TP meant twin-port since
they had a second memory bus over ribbon cables at the top of the card
to feed the video subsystem.

Amardeep

Randy McLaughlin

unread,
Jul 14, 2004, 1:56:19 PM7/14/04
to
"Amardeep S Chana" <asc...@despammed.com> wrote in message
news:na9Jc.64401$bp1....@twister.nyroc.rr.com...

In the Cromemco bank switching scheme there was always intended to have one
common bank, normally 16K. This common memory was fixed in size and
location which software could not change (i.e. no MMU for common RAM). The
rest of the address space was swapped in one bank at a time via out to bank
40h (each bit representing a specific bank).

Technically it is possible to switch in more than bank at a time as long as
they don't overlap. I never used that "feature".

While technically the Cromemco scheme did not force specific bank size and
locations I never saw nor heard of an implementation that had different bank
sizes and locations (in one system). So as a practical matter Cromemco's
generally had common @ 0000h or 0C000h with 48K banks.


The SuperIO bank switching scheme (for 8080, 8085, Z80) has the 1st 64K as
common and a window of varying sizes placed over it. The "best" window size
is 32K. The window is just a slice of on board RAM/FlashROM. This window
is how I have been controlling the 8088 processor on my CompuPro processor.
I map a section of RAM into the 8085 high address space, copy 8088 startup
code including a long jump @ 0FFF0h. I re-map the same window to 0FFFF0h
and start the 8088 processor. This is what I call a handy MMU.

Tarbell has a "better" MMU in the fact that any 4K IEEE-696 RAM gets mapped
into any 4K Z80 address space. While it has a technical advantage it is
just that a technical advantage. In the real life it takes 16 times the
effort to swap banks over either the Cromemco or the SuperIO methods.

Randy


Message has been deleted

Norm Dresner

unread,
Jul 14, 2004, 8:24:28 PM7/14/04
to
<nos...@nouce.bellatlantic.net> wrote in message
news:frdbf0d62s2n4a56r...@4ax.com...
> Having done this since '81 I've had time to experiment and try
> different things.
>
> Page mapping was by far the most flexible but the page size
> (granularity) was a question. I implemented and tried 1k 4k and 16k
> and found in practice that the 4k or 16k was most useful and
> practical. Smaller pages required too much overhead to manage and
> larger than 16K wasted too much space. In the end I went with 4k and
> mapped that into a 1MB linear space, the overhead for mapping was
> reasonable. I also implemented a dirty tag in the MMU that was set by
> any write to that page.
>
> The last item was linear vs mapped DMA, in the end I went with linear
> dma to facilitate fast block moves to mapped or unmapped pages. The
> dma was done in ttl (not unlike Compupro) and allowed for the 20bit
> address range and could copy a full 64k from (source) to
> (destination). Implementing the Mapper as a piggyback to the cpu card
> with the DMA proved easiest as then I avoided some of the S100 DMA
> arbitration problems that IEE696 tried to solve. It also allowed me
> to use a NS* Z80 cpu I already had.
>
> At that time my focus with z80 and CPM was that moving data and
> loading ram (from or to mass storage) were the two big overheads
> slowing the system. The design of that base system with MMU and DMA
> helped confirm this. It's follow on was a later system that had
> each mass storage and IO device having it's own CPU and local ram
> to facilitate things like circular buffers and LRU caches. One thing
> was certain, having ram look like a large linear array rather than
> isolated banks was more efficient.
>
> Allison
>

That's the kind of thing I had in mind when I wrote the OP. I hadn't
thought about the dirty tag but it's a wonderful idea and doesn't seem on
reflection all that hard to implement.

Thanks
Norm

Randy McLaughlin

unread,
Jul 14, 2004, 9:19:54 PM7/14/04
to
"Norm Dresner" <nd...@att.net> wrote in message
news:09kJc.254675$Gx4.1...@bgtnsc04-news.ops.worldnet.att.net...

While it is technically superior to most other methods the real issue is
application.

If you use CP/M v3, MP/M or just LRU buffering these technicalities add
little to applying the extra memory to standard software.

Generally speaking DRI just recomended 16K fixed @ 0C000h & multiple 48K
banks starting @ 0000h. Cromemco & the SuperIO method of a single out
command to switch banks are faster at swapping banks so are better for most
applications (yes I know the the SuperIO scheme uses 32K banks).

Randy


Message has been deleted

Norm Dresner

unread,
Jul 15, 2004, 11:42:29 AM7/15/04
to
"Randy McLaughlin" <ra...@nospam.com> wrote in message
news:DYkJc.8428$yi3...@bignews6.bellsouth.net...

> "Norm Dresner" <nd...@att.net> wrote in message
> > That's the kind of thing I had in mind when I wrote the OP. I hadn't
> > thought about the dirty tag but it's a wonderful idea and doesn't seem
on
> > reflection all that hard to implement.
> >
> > Thanks
> > Norm
>
> While it is technically superior to most other methods the real issue is
> application.
>
> If you use CP/M v3, MP/M or just LRU buffering these technicalities add
> little to applying the extra memory to standard software.
>
> Generally speaking DRI just recomended 16K fixed @ 0C000h & multiple 48K
> banks starting @ 0000h. Cromemco & the SuperIO method of a single out
> command to switch banks are faster at swapping banks so are better for
most
> applications (yes I know the the SuperIO scheme uses 32K banks).
>
> Randy
>
I've been thinking about writing a modern real-time OS for the Z-80.
I'd hoped to use at least some of the CP/M code -- while it isn't exaact;y
the most general stuff, it's probably as much as I'd want for file I/O since
RT programs shouldn't be doing file machinations anyway.

Thanks to all who told me of their experiences and provided
encouragement for me to go forward with a virtual memory scheme [Yes, I
know that RT programs shouldn't be using virtual memory either but there are
usually both soft and hard RT components to any real-world application].

Norm

Randy McLaughlin

unread,
Jul 15, 2004, 12:26:35 PM7/15/04
to
"Norm Dresner" <nd...@att.net> wrote in message
news:FBxJc.97592$OB3....@bgtnsc05-news.ops.worldnet.att.net...

If you are rolling your own then you may want to look at two methods of
memory management:

Use the MP/M (CP/M v3) method of low granularity (and less OS overhead).

Or use a "better" hardware MMU method that keeps track of memory blocks and
knows whether they are relocatable, dirty, etc.


The second method could take advantage of "smarter" MMU's but it would take
more overhead. Personally I believe that the first method would be
significantly faster.

Randy


Norm Dresner

unread,
Jul 15, 2004, 8:24:15 PM7/15/04
to
"Randy McLaughlin" <ra...@nospam.com> wrote in message
news:EeyJc.4945$jU1....@bignews3.bellsouth.net...
Thanks for the advice. I'll have to give it some thought before I decide
how to proceed since everything is a trade-off

Norm

Jonathan Graham Harston

unread,
Jul 16, 2004, 7:20:33 PM7/16/04
to
> Message-ID: <E1BkK4z-...@stasis.kostecke.net>


Scott Moore <sam...@moorecad.com> wrote:
> > memory available to CP/M programs but I was wondering the other day if
> > anyone has ever actually implemented a hardware memory mapper to
facilitate,
> > say, multitasking or just plain expansion of available 64K RAM space.
> >
> I worked for one company that used the scheme like the one mentioned by
> Jack Peacock. A TTL 256*8 ram was used to take the upper 4 address bits of
> the Z80 with a 4 bit select register and gave the top 8 bits of a 20 bit
> address
> as a result. The net effect was to give 16 different address maps selectable
> by the "bank select" register, each address map having an arbitrary
collection
> of 16 4kb pages selected from a 1mb total address space.

This seems to be a co-evolved optimal solution, as this is exactly what I
did. The circuit diagram is at http://www.mdfs.net/Info/Comp/Z80/Circuits
16 4k "slots" in the 64k logical memory map that can each map to any 4k
page in the 1Mb real memory.

The other thing I thought about was that an application that knew about
the mapper and only needed, say, 12k of memory could tell the kernel it
wouldn't be using memory above 2FFF, and the kernel could release the
unrequired pages to the memory pool.


> extended address space). It used no fixed bank sections. If you changed the
> bank, the floor dropped out from under you, there was no section in common
> with the new bank.

Let's swap out the swapper!


> What made it work was that a bit existed that would cause writes to go
> to another bank besides the one being run from. This allowed the other

Oo, that's a useful idea.

--
J.G.Harston - j...@arcade.demon.co.uk - mdfs.net/User/JGH
Badly formed email is deleted unseen as spam

Bill Gates

unread,
Jul 17, 2004, 7:31:33 AM7/17/04
to
Excuse me, but I find it very boring to
be obliged to scroll down all the
repeated messages of this thread.

(I think it is called "top post" in English).

Please, don't republish several screens
of text, just to write one line!!!

Yours Sincerely,
"French Luser"

Message has been deleted

Norm Dresner

unread,
Jul 17, 2004, 4:32:16 PM7/17/04
to
"Bill Gates" <Bill....@Microsoft.com> wrote in message
news:cdb4uf$4k1$1...@news-reader4.wanadoo.fr...

> Excuse me, but I find it very boring to
> be obliged to scroll down all the
> repeated messages of this thread.
>
> (I think it is called "top post" in English).
>
> Please, don't republish several screens
> of text, just to write one line!!!
>

OMG, PLEASE let's not start this again.

There are newsgroups where you'll get flamed for even thinking about
top-posting.

The right solution is to judiciously edit previous text to leave only the
thing(s) you're commenting on.

Norm

J.G.Harston

unread,
Jul 17, 2004, 6:32:21 PM7/17/04
to
"Bill Gates" <Bill....@Microsoft.com> wrote:
> Excuse me, but I find it very boring to be obliged to
> scroll down all the repeated messages of this thread.
>
> (I think it is called "top post" in English).
>
> Please, don't republish several screens of text, just
> to write one line!!!

No, it's called insufficient snipping or overly verbose quoting in English.
As you pointed out it makes for tedious scrolling to find the entire
previous messages has been quoted for a single comment.

Top posting is where the replier writes at the top of the post, most often
also including the entirety of the previous post *after* the reply. This
tends to happen frequenty when poster use Microsoft products as they
leave the editing cursor at the top of the reply, encouraging people to
top post. Top posting is considered, variously, impolite, a sign of
ignorance or inexperience or the cause for flame wars.

If you consider the natural flow of a converation you will see why
adequate quoting and in-line and post-quoting replies makes sense.
See the common sig lines:

A: Because it breaks the flow of the dialogue
Q: Why is top posting considered rude?

or

A: Top posters
Q: What is the most annoying thing on usenet?

--
JGH

0 new messages