The Cromemco 256KZ Card

from Dave Dunfield’s site, http://www.classiccmp.org/dunfield/s100c/index.htm

The Cromemco 256KZ card was an S100 bus computer card. It slotted into the card cage of an old computer and provided 256 KB of RAM for the computer.

This was surprising because, at the time, the computers using the S100 bus could only access up to 64 KB of memory. Why pay for all that extra space if you can’t use it? Here’s why …

The 256KZ had bank selectable memory. This meant you could turn parts of it on and off as you needed.

Cromemco used it to run multiple users and/or multiple processes on a single computer in an era when only one process ran on a microcomputer at a time. It might be a given, or why wouldn’t you, these days; but it was pretty amazing at the time.

The approach has also evolved over time and the granularity has improved. We typically don’t switch such large chunks of memory in one go. However, this was the starting point.

Fundamentally, the 256 KB of memory was split up into 4 banks of 64 KB each. You could put a program in “bank 0”, another one in “bank 1”, and so on. You still only had one CPU (that changed later) so you could only run one of the programs at a time; but you didn’t have to unload and reload memory to switch to another program. Change banks and you’d suddenly be running one of the other programs.

The idea is what made Cromix (a Cromemco implementation of multi-user unix) possible. (This is running unix on an 8 bit microprocessor – more a “toy” than a “real” computer. Amazing.)

I never got to use Cromix. It was beyond the funds available to the person providing me with hardware and software to tinker with at the time. It sure looked interesting though so I did look into what bank switching was and how it worked.

Memory chips and cards at the time had an enable line. When that was activated, the card/chips would pay attention to information on the address bus and would read or write information to or from the data bus. We had S100 boards like a 16KZ card (with 16 KB of memory) so we’d configure a card to respond to addresses 0000-3FFF (the bottom 16 KB), 4000-7FFF (the next 16 KB), and so on. There were switches or jumpers that you’d set to make the enable line activate when an address in that range was present. These just looked at high bits of the address bus. For example, if A15 is 0 and A14 is 0 then the address is in the bottom 16 KB. It was fairly easy to build electronics onto a card to activate the enable line based on a selected combination: activate = (NOT A15) AND (NOT A14). A jumper connects NOT A15 into an AND gate. Another connects NOT A14 to the other side of the AND gate. By putting other jumpers in instead you could choose any of the four combinations and the board would activate in any of the four address ranges.

Bank switching

Bank switched memory worked in a similar way but it wasn’t tied to the address bus. The whole 64 KB was available so it didn’t need to activate based on what was on the address bus. Instead, they used an IO port to effectively extend the address bus. The concept is simple: the board (or part of a 256KZ board) activates if what was last sent to the bank port matches the board’s bank address. That way you could have a 64 KB bank 0 (if last “OUT (bank),A” == 0, and I am configured as 0, then I activate), another 64 KB bank 1 (if last … == 1, and I am … 1, then I activate), and so on.

At the time, adding electronics to compare all 8 bits sent to an IO port to one of 256 possible values was expensive. Also, up to then, no-one had ever needed or used more than 64 KB anyway. It was possible to achieve a similar end with a lot less cost by just checking individual bits. The idea was this:

– if bank port bit 0 is set, and I am configured for bit 0, then I activate.
– if bank port bit 1 is set, and I am configured for bit 1, then I activate.
– if bank port bit 2 …

The electronics for that is simple (possibly just a single piece of wire – a jumper) and we can still access up to 8 x 64KB of memory – an inconceivably large amount at the time.

Cromemco standardized on port 40H as the bank port so, on Cromemco systems or with Cromemco cards, you could:
– LD A, 1H; OUT (40H),A; to select bit 0 / bank 0
– LD A, 2H; OUT (40H),A; to select bit 1 / bank 1
– LD A, 4H; OUT (40H),A; to select bit 2 / …
– …
– LD A,40H; OUT (40H),A; to select bit 6 / bank 6

Bank 0 also activated at power up, as a computer needs some memory present at start up.

Switching between programs

Switching between programs presents some challenges. If your entire address space is about to disappear from under your feet; you are going to be running a different program the instant you send something to the bank port. There is no chance after that to do any more of what you were doing before the switch. You need to have saved whatever state information you had, and you need to have retrieved the state information of the program you are about to switch to. It is pretty hard to do. Also, how do you set up the memory that you are about to switch to, for the very first time? It might be all zeros. It might be random bytes before you load a program.

Cromemco chose to include a mode which allows common writes. If you activate what you’d expect to be bank 7 (“LD A,80H”; “OUT(40H),A”), any write to memory gets written to all banks.

From a hardware perspective, that is fairly straight forward:
– if bank port bit N is set, and I am configured for bit N, then I am active.
– if bank port bit 7 is set, and a write is occurring, then I am active.

N is 0-6 as bit 7 is reserved for common writes.

Valid values for the bank port are:

0H Power up, bank 0 and any ROMs are active
1H Bank 0 active. ROMs normally disabled (see switch settings).
2H Bank 1 active.
4H Bank 2 active.
8H Bank 3 active.
10H Bank 4 active.
20H Bank 5 active.
40H Bank 6 active.
80H Bank 0 active. Common writes.
81H Bank 0 active. Common writes.

With common writes, you still have your address space but you can write into other banks. You can also jump to a location, do a bank switch, and know what you will find when you get there. You can copy a small bit of code into, for example, high memory; jump to it, and then switch all of the rest of memory from any bank in or out below you. You remain running the same bit of common code whilst you set up any or all of the other banks.

z80sim

I have included a 256KZ card in my latest update of z80sim (version 0.05). It doesn’t do much with CP/M or CDOS but I hope to see it run with Cromix at some point. For now, all you can see is the memory changing beneath you as you issue bank switch commands:


C:\Users\Greg\Downloads\run-cdos0236\cdos0236>z80sim -x cdosboot.hex

#######  #####    ###            #####    ###   #     #
     #  #     #  #   #          #     #    #    ##   ##
    #   #     # #     #         #          #    # # # #
   #     #####  #     #  #####   #####     #    #  #  #
  #     #     # #     #               #    #    #     #
 #      #     #  #   #          #     #    #    #     #
#######  #####    ###            #####    ###   #     #

Release 1.35 Simulator, Copyright (C) 1987-2017 by Udo Munk
Release 0.05 Windows Build, Copyright (C) 2017 by Greg Sydney-Smith

CPU speed is unlimited

Loader statistics for file cdosboot.hex:
START : 0080H
END   : 00ffH
LOADED: 0080H (128)


CDOS version 02.36
Cromemco Disk Operating System
Copyright (c) 1978, 1980 Cromemco, Inc.

A.User Interrupt

PC   A  SZHPNC I  IFF BC   DE   HL   A'F' B'C' D'E' H'L' IX   IY   SP
fa75 20 000000 00 00  f801 0010 f88c 0257 ef96 886d 412f f87c 007f f944
>>> d100
Adr    00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f  ASCII
0100 - 01 d6 30 11 c7 fb 21 55 32 ed b8 c3 54 cb 00 00  ..0...!U2...T...
0110 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0120 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0130 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0140 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0150 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0160 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0170 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0180 - 0d 43 44 4f 53 20 76 65 72 73 69 6f 6e 20 80 00  .CDOS version ..
0190 - 00 2e 80 00 00 0d 0a 43 72 6f 6d 65 6d 63 6f 20  .......Cromemco
01a0 - 44 69 73 6b 20 4f 70 65 72 61 74 69 6e 67 20 53  Disk Operating S
01b0 - 79 73 74 65 6d 0d 0a 43 6f 70 79 72 69 67 68 74  ystem..Copyright
01c0 - 20 28 63 29 20 31 39 37 38 2c 20 31 39 38 30 20   (c) 1978, 1980
01d0 - 43 72 6f 6d 65 6d 63 6f 2c 20 49 6e 63 2e 20 0d  Cromemco, Inc. .
01e0 - 0a 00 31 80 00 97 32 03 00 32 5a 00 32 5b 00 21  ..1...2..2Z.2[.!
01f0 - 51 cb cd 0b f0 cd 73 f5 cd 54 ef cd 84 ef cd 78  Q.....s..T.....x
>>> p40
40 = 01 : 02
>>> d100
Adr    00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f  ASCII
0100 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0110 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0120 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0130 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0140 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0150 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0160 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0170 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0180 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0190 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
01a0 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
01b0 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
01c0 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
01d0 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
01e0 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
01f0 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
>>> p40
40 = 02 : 1
>>> d100
Adr    00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f  ASCII
0100 - 01 d6 30 11 c7 fb 21 55 32 ed b8 c3 54 cb 00 00  ..0...!U2...T...
0110 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0120 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0130 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0140 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0150 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0160 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0170 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0180 - 0d 43 44 4f 53 20 76 65 72 73 69 6f 6e 20 80 00  .CDOS version ..
0190 - 00 2e 80 00 00 0d 0a 43 72 6f 6d 65 6d 63 6f 20  .......Cromemco
01a0 - 44 69 73 6b 20 4f 70 65 72 61 74 69 6e 67 20 53  Disk Operating S
01b0 - 79 73 74 65 6d 0d 0a 43 6f 70 79 72 69 67 68 74  ystem..Copyright
01c0 - 20 28 63 29 20 31 39 37 38 2c 20 31 39 38 30 20   (c) 1978, 1980
01d0 - 43 72 6f 6d 65 6d 63 6f 2c 20 49 6e 63 2e 20 0d  Cromemco, Inc. .
01e0 - 0a 00 31 80 00 97 32 03 00 32 5a 00 32 5b 00 21  ..1...2..2Z.2[.!
01f0 - 51 cb cd 0b f0 cd 73 f5 cd 54 ef cd 84 ef cd 78  Q.....s..T.....x
>>>

Further reading:

  • Dave has a manual to go with the picture of his 256KZ card.
  • z80sim is open source. You can see the implementation of the 256KZ in software in cpm/z80sim.
  • This is part of the CP/M topic.
  • It's only fair to share...Share on FacebookTweet about this on TwitterShare on Google+Share on LinkedInShare on StumbleUponDigg thisPin on PinterestEmail this to someone

Leave a Reply

Your email address will not be published. Required fields are marked *