View
 

Questions-and-Answers-about-N8VEM-design

Page history last edited by Andrew Lynch 6 years, 9 months ago

Source:

www.vintage-computer.com

Hi,

Is anyone interested in a home brew Z80 computer project? I have built them in the past and

are a lot of fun to do. There are some others on this forum who have built their own machines

but I am curious to see if there are others who would be interested in a group project. Please

reply here or PM me if interested.

My latest Z80 machine is an updated design that tries to keep it simple while retaining the

"feel" of vintage machines. It is a blend of technologies to address some of the major

frustrating things which I faced as a home brew builder.

The first issue is parts availability; if you can't get the parts you can't build the machine. For

this project, I am selecting only rather common and readily available 74LSxxx chips and LSI

components like Z80 CPU, 16550 UART, 8255 PPI. All parts are readily available from vendors

such as Jameco.com, etc. Custom programmable devices (except for boot EPROM) such as

GALs, PALs, FPGAs, etc are out as those devices are difficult for many hobbyists to get

without the special tools required to program them.

The second issue is the technology needed to build the unit; many of the advanced PCB

techniques require special tools and processes which are beyond the typical hobbyist. As a

result, I selected plain "through hole" (i.e. generic DIP packaging with 0.10" pin spacing)

technology which is fairly simple and only requires a 25 watt soldering iron and related tools

to produce. Any of the various SMT techniques are out even though they are much more

dense they are too difficult.

The third issue is the PCB itself; there are a variety of techniques to make your home brew

computer on such as breadboarding, wire wrap, and point to point protoboards. I have used

those techniques and they do work fine although I think they tend to be for "one off" and

temporary projects. The tend to devolve into a "rats nest" over time or develop other issues

with reliability. For this project, I am going to try the custom manufactured PCB approach.

Although initially more expensive, it promises to make for a much more reliable product and

tremendously reduce the work necessary to build the device. In addition, with recent

developments in free software tools and low cost PCB manufacturing, the cost associated with

this approach has come down dramatically.

Finally, there has to be software for the machine. My goal for this project is standard CP/M

2.2 booted from a ROM drive and using a RAM drive for storage. This is doable since I have a

custom CP/M build with CBIOS for my previous Z80 home brew project. This machine would

be similar to the existing design and require some changes to the code. Most generic CP/M

applications should run unmodified. As with any CP/M platform, some hardware specific

programs are required such as debugger, format utility, RTC application, etc.

Andrew Lynch

Hello Andrew,

Thank you so much for all the detailed descriptions. The above paragraph is the

core of your present design, and it would be very helpful if you would kindly

explain what goes on when you turn the circuit on. If you could provide a flowchart

or something, it would be even more educational.

Thank you very much

ziloo

Hi,

Well, I can try to explain. Basically when the CPU is reset there are two MPCLs. One is

attached to an EPROM and the other to a SRAM. The default memory configuration (ie, MPCL

74LS273 latches are both set to $00) there is a 32K ROM page at $0000 to $7FFF and a fixed

32K RAM page at $8000 to $FFFF. The upper RAM page is fixed and can never be changed.

-1-

However the lower ROM page can be switch into any of 32 different ROM pages (1MB) or

switched out entirely and replaced with one of 16 different RAM pages (512K).

When the CPU boots, it starts executing at $0000 as per every Z80. The first thing it does is

"toss" the program it is running (aptly named "loader") into upper memory and transfers

control to the newly installed "RAM monitor" running at $F800-$FFFF. The RAM monitor

continues with the rest of the hardware initialization which includes switching out the lower

ROM page and creating a full 64K of RAM. The RAM monitor gives several monitor like

functions you'd expect like "display" "load Intel hex format" "go" "fill" "substitute" and the

like. The last command it has is the "c" command which is basically a CP/M boot loader. Press

c and almost immediately a CP/M prompt appears with A: being a RO ROM drive (32K soon to

be 996K) and B: RW RAM drive (448K).

The first 32K of the ROM is sneakily formatted as a 32K CP/M disk complete with boot tracks

(where loader and dbgmon are stored). I forget the exact format right now but the ROM is

divided up into 128 byte sectors, tracks of some size, and the whole thing is 32K long. When

CP/M is running it mounts A: as the block device in the CBIOS and you can do all the normal

disk functions except write. You can get a directory of the three programs I placed into the

ROM image. If I recall correctly, they are gm (go monitor), RTC (real time clock) and XM

(XMODEM). There are supposed to be a bunch more but since I have to hand code the

directory entries into the ROM image I have only done those few programs.

Hopefully this helps explain how the TP boots. Maybe you could ask a more specific question

if there is something else you'd like to know? This is intended to be a open and public project

so the details are all out in the open. I will be posting the software on the website once I have

some confidence it more or less works.

BTW all the software is assembled from source, including CP/M 2.2 using TASM301. It is a

free (as in beer not as in speech) DOS based assembler. In keeping with the open and public

and free themes I'd like to convert to development environment similar licensed to KiCad for

the hardware assembly but just haven't gotten that far yet. Similarly I would like to transition

to a free OS like ZCPR or whatever it is called. Somebody still retains the rights to CP/M but

have made it available for usage.

When you say RAM monitor I assume you mean a monitor in ROM that uses RAM,

or?

Are images (or, even better, sources) for these ROMs available anywhere?

Instructions for the monitor?

Hi Mike,

The RAM monitor is one that runs entirely in RAM, starting at $F800. It is stored in ROM and

loaded into the high page as part of the boot process. Once the RAM monitor starts, it

initializes the hardware and switches out the ROM page. Its actually called "dbgmon-e" but I

call it the RAM monitor to distinguish it from the ROM monitor which used to run entirely in

ROM. It is a similar monitor of an earlier generation.

The ROM images are available on my workbench. :-) I will be publishing the sources of the

assembler on the website along with links to the tools I am using. Basically you don't need the

ROM images if you have access to a DOS PC since TASM301 generates the necessary binary

image (ROMIMAGE.BIN) from the assembler sources.

What is the address range for this newly established 64k RAM?

Hi! Excellent questions!

After the boot process is completed (ie, the RAM monitor is running) there is RAM at $0000 to

$7FFF and at $8000 to $FFFF. CP/M theoretically has access to a full 64K of RAM, however,

the TPA is somewhat less than that since it shares the RAM with CP/M itself and 2K for the

RAM monitor.

-2-

What address range the CP/M is residing on?

CP/M loads at $D400 and uses up to $F2FF. CP/M is composed of three parts, the CCP, BDOS,

and CBIOS. The CBIOS I wrote starts at the somewhere near the end but I don't remember

the exact location. It is in the source. I seem to recall the TPA is 56K(?) or so. I don't

remember the exact number but it is in the CP/M 2.2 source included.

How are these ROM and RAM units addressed? Z80 can only address 64K of

memory and

how is the bank switching implemented? (Do I understand it correctly?)

The regular $0000-$FFFF memory map is accessed normally. The extended RAM and ROM

are accessed by switching in the lower 32K memory page by writing to the various MPCLs.

They appear as write only IO ports. I think they are $78 for the RAM MPCL and $7C for the

ROM MPCL. Since they initialize to $00 upon reset, writing 1s to any of the latch bits cause

address lines to be set high. The RAM MPCL has extended address lines (A15, A16, A17, A18)

and the ROM MPCL has extended address lines (A15, A16, A17, A18, A19). The ROM MPCL

also has a ROM_ENABLE line at bit 7. Note the address lines are local to the specific MPCL

and its memory device. The CPU can only indirectly access the extended memory address

lines via its MPCL.

All the hardware information is contained in the schematic and PCB layout on the N8VEM

website. Soon I will be publishing a ZIP file of all the software and make files. It is all pretty

crude stuff and DOS based for easy usage. It all probably needs a serious rewrite but the

intent is/was to just show viable operation of the concept.

One curious artifact of the original design is that the RAM chip has its highest 32K page

"pinned" to A15 by a 74LS32. Whenever the CPU sets the A15 high, all the SRAMs extended

address lines (A15, A16, A17, A18) are forced high. That way there is a "permanent" 32K RAM

memory reference for running programs which manipulate the memory map. The original

design did not have this and I discovered the hard way that if you are going to change the

memory map, the CPU needs a source of permanent context for reference. Otherwise context

gets lost and the CPU goes into LA-LA-LAND.

...The first 32K of the ROM is sneakily formatted as a 32K CP/M disk complete

with boot tracks (where loader and dbgmon are stored). I forget the exact format

right now but the ROM is divided up into 128 byte sectors, tracks of some size, and

the whole thing is 32K long...

Would you please explain more details about addressing the sectors and tracks?

How are the information stored on these tracks/sectors: as linked lists, some kind

of an allocation table...etc?

OK, well really the real tracks and sector information is contained in the CBIOS design. It

views the data contained in the ROM as a 32K block device "disk". The CBIOS has an

algorithm which when you tell it load track 00, sector 00, it knows to go get the first 128

bytes of the ROM. Depending on what track/sector combination you request, it returns

different 128 ROM memory regions as a sector. It really is a kind of neat trick.

The ROM itself does not contain any disk meta-data like sector/track information like you'd

find if you used a Catweasel to do a raw read of a soft sector floppy disk. It is more like a dataonly

disk image where the disk imaging program knows which data goes with which

track/sector based on the data's relative position within the image file.

The ROM is formatted in such a way that the CBIOS can parse it out using its track/sector

block device read (and write in the case of the RAM drive). You can literally see the 32K disk

structure in the layout of the ROM. It follows the CP/M DPB values in the CBIOS.

-3-

I think goes something like this...

each track is 4K long and is composed of 32 sectors each 128 bytes in length. Within the 32K

ROM there are 8 tracks. Track 0 and 1 are reserved as "system" tracks to contain the loader,

dbgmon, & CPM boot image. Starting on track 2 is the directory structure which is like four

sectors long or something. Actual disk data starts someplace after the end of the directory

and goes to the end of the 32K ROM.

There is a similar concept for the RAM disk but with a different set of DPB values. Eventually

I will convert the 1M ROM into a format similar to the RAM drive and include an entire CP/M

set of utilities and some development tools, applications and the like. Of course this is user

customizable so anything can go in there but right now you have to format the ROM image by

hand which is a real PITA.

One of the things I put on the "help needed" section of the N8VEM website is for some

programming whiz to make a DOS program which given a set of files and a DPB, will create a

formatted ROM image. The program would not be that hard to write (I think) but would

require some fairly detailed knowledge of how CP/M disk layout and formatting. I am doing

that by hand now but it would be highly useful for others to have a utility which could do this

automatically. All the necessary technical information is available online in the CP/M

documentation and I can help point out where if anyone is interested.

CP/M loads at $D400 and uses up to $F2FF.

This is about 8k of program code; where is the rest of CP/M?

The CP/M EPROM actually contains many programs such as a loader,

the RAM monitor, the CP/M image, XMODEM, and RTC utilities....

...You can transfer programs into the RAM drive by XMODEM (included in the

ROM drive)

great? Well, I wouldn't go that far... Wait until you see the source code ;-) I am sure you'll

come up with some other adjectives.

Yes, I seem to recall the TPA is 53K in length for some reason. 2K is used for the RAM BIOS.

CCP and BDOS uses 5.5K, if I recall correctly. I think the CBIOS and disk buffers use up the

remainder. The CBIOS supports an IDE interface as well which chews up quite a bit of RAM

and also requires a 512 byte deblocking buffer someplace up in high RAM.

The IDE interface is on the Test Prototype machine I built last year. The IDE portion works

great. It could easily be converted to a CF drive with an adapter, I think. I used a small 1.2GB

IDE hard disk but it really only used like three 8MB partitions.

Later I built a floppy disk interface onto the card but it had issues with grounding and I ran

out of time to work on it. It was completed but I never got a chance to test the software for it

even though it was largely already written. I still have all the schematics and intend to

incorporate them into the disk IO board later on. I will probably have to design out an

obsolete part (SMC FDC9229 data separator) that has become unobtainium and replace it

with a SMC FDC9216 or UM8326. That is an other story for a different day though.

I think I bought a broken NorthStar Horizon about then and became obsessed with fixing it

and ended up putting the home brew computer "on hold" until that passed. I fixed the Horizon

and it is a great machine but now I am finally ready to return to finish this home brew

computer.

One of the reasons I transferred the design to manufactured PCBs is to fix the root problem of

the grounding on the Test Prototype. Since it used prototype boards with point to point

wiring, after a few generations, it began to resemble a ball of wire that you could occasionally

glimpse a component in. It was rather difficult to work on. The new PCBs are MUCH nicer to

assemble!

-4-

1- Is "loader" part of ROM monitor or a separate program.

From a source perspective, the loader is its own program. As a binary, it is combined into the

same ROMIMAGE.BIN as the RAM monitor and the CPM boot image. The latter two programs

are just data fields loader transfers to their appropriate places in memory. Loaders last job

task is to jump to the cold-start vector on the RAM monitor, who in turn swaps out the ROM

and loader disappears from the CPU address space entirely. You can boot CP/M from the RAM

monitor if desired. Or not. Frankly, I find the RAM monitor just as useful as CP/M is for the

most part. I split my time between the two.

2- Are both ROM monitor and CP/M on the same EPROM?

Yes, the RAM monitor and CP/M boot image are in the ROMIMAGE.BIN stored in the first 8K

of the 32K ROM page. The CP/M boot image is only the CCP+BDOS+CBIOS. The rest of the

CP/M transient utilities are stored on one of the IDE hard disk partitions. My plan is to move

them and some other stuff onto the ROM drive once it expands from 32K to 992K.

3- Is ROM drive the same as CP/M EPROM?

Yes. The ROM drive (A:) is just like a floppy disk. It currently is the first 32K of the EPROM --

which used to be a 32Kx8 28C256 EEPROM but is now a 1Mx8 27C080 or 128Kx8 27C1001

EPROM. The first two tracks are reserved for system tracks which contains the loader, RAM

monitor, and CP/M boot image. The remaining 6 tracks (24K) are reserved for programs like

GM.COM, RTC.COM, and XM.COM.

I'll post the files tonight in the ZIP file and when you inspect the make files and the resulting

ROMIMAGE.BIN, it will be more apparent how the system is structured. It really is pretty

simple structure but neat how it all works out.

What does "rehosted" mean?

"rehosted" means I modified the source code so that the "new" versions run on the new

hardware and reflects the updated designs. Basically two main software components had to

be changed to reflect the new design has RAM and ROM MPCLs compared to the previous

generation which had only a single MPCL. The RAM monitor hardware initialization routine

and the CP/M CBIOS had to be modified. I haven't located any other necessary changes

although it would not surprise me if there were some others lurking someplace.

...requires a 512 byte deblocking buffer someplace up in high RAM.

The first time I read about "blocking and deblocking", I thought blocking means to

stop/prevent!!! I don't know whether this terminology was coined by Gary Kildall

or it was someone else's idea. As I understand, blocking means "arranging blocks

of data" and deblocking means "removing blocks of data" (or was I right the first

time?!?!).

Would you please give a more detailed explanation as to was goes on in that

buffer...

Yes, "deblocking" in the context of a CP/M CBIOS is an algorithm that converts whatever disk

format sector size to the one that CP/M expects to use, namely 8" floppy disk with 128 byte

sectors. When the CBIOS "deblocks" what it does is take the minimum sector size block from

the native device, say an IDE hard disk minimum which its sector size is 512 bytes, and

-5-

converts it into one to four 128 byte sectors usable by CP/M natively.

The CBIOS I wrote implements a crude deblocker for the IDE interface. Basically it is just one

for one mapper and it horrifically inefficient. However, it does work reliably as far I could tell

and the IDE harddisk is way faster than the Z80 can handle anyway. The more sophisticated

CP/M deblocking algorithms were able to deblock and retain the sector information in a sort

of tiny disk RAM cache for subsequent reads.

1- I see a mixture of ASM programs in both 8080 and Z80 instruction sets in your

ZIP file. Would you please explain about this?

2- I have heard so much about IOBYTE in CP/M; would you please give an

explanation about what it is all about...

Uhhh. Yeah. Not one of my proudest moments, that's for sure. :-)

Actually, it is an artifact of trying to convert the entire code base to allow compiling on the

Test Prototype target itself using the standard CP/M toolset (ASM). I tried to restrict myself to

just the 8080 mnemonics but occasionally a Z80 op code was necessary for some reason or

other. In those cases, I basically forced the assembler to put in the proper op code even if it

didn't recognize the mnemonic. The exact technique is one I learned from Allison. For

example:

LDIR1: .DB $ED,$B0 ; Z80 "LDIR" INSTRUCTION (REMOVE)

Of course, there is no 8080 equivalent to LDIR and I needed it for some block transfers in

loader-a and the CBIOS. I suppose I should just convert it all back to Z80 and just accept the

Z80 as a requirement but "true" CP/M portable applications are written using only the 8080

instructions. There are a few exceptions to the rule.

My goal was to remove all the Z80 peculiar instructions and have "pure" 8080 only

instructions but that got to be increasingly difficult and when other problems developed, I

pushed the project to the back burner. There are 8080 only equivalent subroutines and

macros to help Z80 -> 8080 conversion and some of those are in the source, I think.

Some files in the ZIP file are all Z80 mnemonic and others are 8080. You can tell which is

which by reading the buildTP2.bat file and which TASM commands require -85 (for intel 8085)

and those for -80 (for zilog Z80).

My hope for publicly posting the Test Prototype project online, warts and all, is to keep the

information from being lost entirely. It is possible that when/if people start making these SBCs

for themselves that some of this code will get better testing and maybe even cleaned up a bit.

Certainly there are many hours of work needed

Regarding the IOBYTE; in essence that is a tool where the CP/M CBIOS allows some IO

abstraction and redirection. The IOBYTE allows switching between CP/M devices such as

CON:, PUN:, LST:, PRN:, etc with minimumal impact to the CBIOS. The Andrew Laird

"Programmer's Guide to CP/M" does a great job explaining what and how this works. It was

my intention to support IOBYTE in the CBIOS but again, it got sidetracked. My CBIOS does

not support IOBYTE in its present form.

You'll find there are a great many rabbit trails to follow in the source code. Some actually go

someplace and others just trail off into the weeds. Like I said, the test prototype software

surely isn't the prettiest thing you'll ever read but it more or less works.

You remembered to have your aspirin and glass of water ready before you started reading it,

right? :-)

PS, Check out the silliness in the dbgmon-e source. It was originally for an SBC-200 and

"adapted" for new use on the Test Prototype. It is rather ghastly and even includes boot code

for FDC1793 disk controller. The only problem with that is the actual disk IO board uses the

NEC765 FDC. :-)

Originally, I was going to use a WD2797 FDC chip but later changed my mind. I even have a

-6-

WD2797 still sitting here just waiting for a PCB to put it in.

Do I understand correctly then that:

1- TASM takes the 8080/8085 code and assembles it into a form that is executable

on a Z80 CPU?

2- Probably most vintage computers with Z80 CPU were using CP/M versions

written entirely for 8080 CPU?

Yes, TASM is a Table Assembler and is able to cross assemble for many targets including

8080, 8085, and Z80. Not that TASM can translate assembler mnemonics between CPUs

though but the Z80 and 8085 have backwards compatible opcodes with the 8080 so it sort of

appears like it.

The Zilog Z80 is opcode compatible with 8080. Zilog published a new set of assembler

mnemonics for Z80 very different than the Intel 8080 mnemonics but the resulting machine

language is a backwards compatible superset of the Intel 8080 opcodes.

The confusion arises because Zilog came up with a new mnemonic format which was

improved over the much older Intel mnemonic format. A lot of assemblers support one or the

other and sometimes both. TASM supports both Intel and Zilog mnemonics and has rather

conveniently facilitates my bad habit of switching randomly between the formats.

The Intel 8085 is essentially the same as the 8080 except for a couple of new instructions (not

supported on Z80) and uses identical mnemonics.

CP/M was originally written on an 8080 and all the documentation are Intel 8080 specific. I

believe all the CP/M tools are in Intel mnemonic format as well. The 8085 and Z80 both run

8080 opcodes and are both far more common CPUs. As a result most CP/M machines are not

8080 but use the Z80or 8085 instead. I am pretty sure the majority of CP/M computers are

Z80 though.

There are some CP/M applications which use Z80 specific opcodes like Borland Turbo Pascal

but they are very few. I cannot think of another example of Z80 dependent CP/M code except

for possibly some CBIOS versions.

Here is great site to sort through the wreckage of old CBIOSs. I have gotten some really great

ideas sifting through these:

http://www.speakeasy.org/~rzh/bb.html

Actually there are not all that many 8080 machines left due to their early technology and

unusual voltage requirements. The Z80 machines are far more common. Intel 8085 is also

very popular but more so in industrial embedded applications than in microcomputer because

the chip set is specially designed for easy integration and low part count. You can run CP/M

on 8085's but they are a less common than Z80 regarding microcomputers.

If you are considering designing your own SBC you should consider using the 8085 as the

CPU since it is possible to make very low chip count machines with them. I hope this helps

explain things. Feel free to ask if there is anything I can better explain.

.. CP/M loads at $D400 and uses up to $F2FF...

... I seem to recall the TPA is 53K in length for some reason. 2K is used for the

RAM BIOS.

CCP and BDOS uses 5.5K, if I recall correctly. I think the CBIOS and disk buffers

use up the remainder. The CBIOS supports an IDE interface as well which chews

up quite a bit of RAM and also requires a 512 byte deblocking buffer someplace up

in high RAM...

-7-

1- Is CBIOS included in the $D400-$F2FF address interval?

1- How much memory is available for an application program?

2- Is there any unported portion of CP/M still left in the EPROM?

Yes, the CP/M boot image includes CCP+BDOS+CBIOS. The loader copies a memory image

range of $1EFF in length (a little bit less than 8K) although the actual length of the CP/M

binary boot image is somewhat less than that. CCP+BDOS are 5.5K and the remainder is the

CBIOS.

1- How much memory is available for an application program?

I am not certain but I think it is 53K. After a quick review of the CPM22-d.asm code, I believe

transient program area (TPA) = (MEM -7) * 1K where MEM = 60 in this case. For the most

part, that is sufficient. I have found CP/M TPA 48K or greater to be pretty usable.

In theory, I could boost MEM to 62 but it'd cost the RAM monitor and since I use both about

the same amount, I'd rather keep it. Also the CBIOS could probably be rewritten to be lot

tighter code which would shrink it some too. However, more likely is that the CBIOS will grow

not shrink since I do intend to add support for an FDC eventually which will further shrink the

TPA probably another 1K or so.

Now this design is largely out in the public, there is nothing stopping anyone from creating

their own ROM images and custom CBIOSs. In fact, I rather encourage it. I will speak with my

friend to see if he can add support for the N8VEM hardware into a simulator. It should be

fairly easy as there are only 5 simple IO devices.

2- Is there any unported portion of CP/M still left in the EPROM?

No, it is all converted as best I can tell. The rest of CP/M ia/are transient programs which are

identical for all CP/M distributions. Those include STAT, ASM, DUMP, PIP, LOAD, etc. Those

are currently stored on an IDE HD partition which I haven't attached yet but will be in the not

too distant future. However, if anyone wants to use them now, they can boot the computer,

start CP/M and use XMODEM to transfer the files to the RAM drive where they'll reside as

long as power is applied.

1- Please explain in more details about communication between N8VEM board ;)

and something like Hyperterminal.

Yes, I use Hyperterminal to communicate with the SBC over the serial port. There is a custom

serial cable required and I suppose I need to publish the plans for it as well. I'll do that. Funny

you should ask about Hyperterminal though as I have been working on the serial connection.

Up until today, the SBC used 3 wire serial connection with no flow control at all. That is really

not my preferred approach but I never could figure out how to make hardware flow control

work properly.

So this morning I got out the RS-232 serial break out box and the pin outs for the PC serial

port and the 16C550 datasheet. I think I have fixed the problem so now the SBC appears to be

using hardware flow control. Still, I need to verify it is working. The custom serial cable is

pretty easy to make and when I confirm it is working I will post how to make it.

2- Can you download a file from a PC to N8VEM board?

Yes, you can use XMODEM to send and receive files from the SBC.

-8-

3- If so, which software is responsible for communication: Ram Monitor or

Xmodem?

You can use either to transfer a file from a PC to the SBC. Using XMODEM is probably easier

or you can use the Intel Hex transfer utility in the RAM monitor. To send a file from the SBC

to the PC just use the XMODEM or text capture.

1-Upon starting the SBC, under which supervisory program does the N8VEM

board eventually end up...the Monitor or CP/M?

After pressing the RESET button and waiting a few seconds, the SBC comes up in the RAM

monitor mode. You can boot into CP/M by pressing the "c" key and waiting another few

seconds. It is not instantaneous because the initialization routines clear all the RAM to a

known state and format the RAM drive which takes a few seconds. It is quiet though...

2- How do you transfer operation from one to the other?

From the RAM monitor to CP/M, press "c" to boot CP/M

From CP/M to the RAM monitor, type the "gm" command for "go monitor".

You can switch in between the two quite easily.

3- Xmodem is a whole separate program, and CP/M is not aware of its presence;

because Xmodem is the communicating program for CP/M, it could not be called in

by CP/M like some other utility programs on the HD/FD/RamDrive. So it is kind of

a CBIOS extension...Do I understand this correctly?

Well ... not quite. XMODEM is a CP/M program in its own right although it does have its own

unique CONIN, CONST, and CONOUT routines instead of using the ones provided by the

BDOS or CBIOS.

You call up the XMODEM program by typing "xm" at the CP/M prompt. It is just like any other

CP/M program for the most part. It uses BDOS routines for its file access for instance. The

RTC also uses some BDOS routines. I suppose they could be stand alone programs but why

rewrite all those file IO routines when CP/M provides them so nicely?

According to buildTP2.bat file:

Xmodem is assembled and linked to CP/M and few other programs to create a

binary file to be downloaded as Rom image.

Was it possible that Xmodem could have been treated like any transient program

that could be loaded by CP/M into Ram, but for now it is manually linked to the CP/

M program. If so, then the "XM" command has been manually added to CP/M (in

the absence of an storage device for Xmodem program)?

Oh, I think I see the misconception here... XMODEM is not linked to the CP/M boot image. It

is a transient program like RTC and GM or any other CP/M transient program. XM is in the

same ROMIMAGE binary because the ROMIMAGE is basically just like a miniature disk

image. They are together like various programs would be on a regular disk but XM is not

linked to CP/M. It is written in pure assembler and only called into RAM when the CCP

requests it. It does use BDOS calls but so does almost every CP/M program.

You'll notice that the loader, dbgmon, and CPM boot image are all on the first five 2K system

tracks which are $0000 - $27FF (10K) in the ROMIMAGE. The CP/M directory sectors are at

-9-

$2800-$2BFF (1K) and the programs themselves are stored in the data sectors $2C00-$7FFF

(21K).

I have been testing XMODEM as part of my attempts to get a documented serial cable. I think

I have a working prototype cable that works with hardware handshaking. One thing I have

noticed is that the new PCB seems a lot more solid and reliable than the previous prototype

board version. It used to be that XM was rather flaky but now it seems rock solid. I can load

XM in to RAM, run it, pull data files from the PC and back again without the slightest hiccup

or even a retry. That is quite different than before. I've been doing the transfers with large ZIP

files as they are easy to detect if there is file corruption being introduced.

Thanks and let me know if this helps explain how this all works. Just try to think of

ROMIMAGE.BIN as a miniature disk image, not an executable. Really the only thing in

ROMIMAGE.BIN which actually executes in place is the loader. Everything else is just so

much data -- just like on a floppy disk. Not until the OS pulls the data into RAM does it

become real executables.

...the programs themselves are stored in the data sectors $2C00-$7FF...

Now, what is the use for the higher EPROM address range, namely $8000-$FFFF?

You can get a directory of the three programs I placed into the ROM image. If I

recall correctly, they are gm (go monitor), RTC (real time clock) and XM

(XMODEM). There are

supposed to be a bunch more but since I have to hand code the directory entries

into

the ROM image I have only done those few programs.

Would you please explain about "hand coding"...

Now, what is the use for the higher EPROM address range, namely $8000-$FFFF?

In its current implementation, the ROM drive is only a single 32K page so there is nothing in

outside the first page (ROM page 0, $0000-$7FFF). It is an artifact from the original design

that used a 28C256 EEPROM (32K). However when I get the CBIOS updated with the new

design, the ROM drive will have 32 32K pages for 1MB total capacity from the 27C080

EPROM.

From a CPU perspective, the ROM only appears as $0000-$7FFF in its lower memory page

window. The ROM never appears in $8000 or above. The MPCL set the upper address lines so

that you can see one of the 32 32K "windows" into the ROMs address space.

Would you please explain about "hand coding"...

Yes, the "hand coding" is literally typing in the characters for directory entries manually. If

you'll look in the ROMFRMT.ASM file you'll see the data entries of the three CP/M transient

programs. Making manual entries is pretty labor intensive compared to just letting CP/M

BDOS do it automatically for you. If you want to add a program, ROMFRMT.ASM has to be

updated as well where ever the data image would reside in the ROMIMAGE.BIN.

I have really enjoyed our "Socrates dialogs" ... :argue:

You might have noticed that this thread has had hundreds of readers over the past

few days, so there must be great interest in learning about SBCs running CP/M.

Now, why not getting into more details:

... the "hand coding" is literally typing in the characters for directory entries

manually. If you'll look in the ROMFRMT.ASM file you'll see the data entries of the

-10-

three CP/M transient programs...

org $2800

.db $00,"GM COM",$00,$00,$00,$01

.db $01,$00,$00,$00,$00,$00,$00,$00

.db $00,$00,$00,$00,$00,$00,$00,$00

.db $00,"RTC COM"...

Would you please go over the entries and explain what they are all

about...:winking:

Hi! Sure, no problem. I am glad you enjoy it and I look forward to helping you and others as

much as I can. All I did with the ROMFRMT.ASM program is what BDOS normally does when

it creates a file in the block device. Each file has a 32 byte entry with various pieces of

metadata such as user, filename, the number of records, number of extents, where the file is

on the disk, etc. CP/M has a very straight forward file system so doing this is much easier

than it may sound. Here is a link with a good explanation although there are more detailed

explanations in the CP/M documentation. I think the CP/M Alteration Guide is pretty good and

the Andrew Johnson-Laird book "CP/M Programmer's Guide" has an excellent description.

http://www.geocities.com/homeofoscarvermeulen/cpm.html?200811#Directory

Please bear in mind though, I am not a CP/M guru or even an expert on vintage computers or

electronics. I am but a child student at the feet of the real masters. Allison, Chuck, Mike,

Howard, Dave, et al, have probably forgotten more about CP/M and vintage computers than

I'll ever know.

One of the benefits of building your own computer from scratch is it forces you to learn the

practical aspects of those theoretical concepts of computing you probably learned in college. I

know I have and that is why this hobby has paid for itself many times over for me. I can only

recommend diving in and building something. In my engineering day job, we tend to focus on

the more business aspects of things, however, I am expected to keep technically current and

there is nothing better than grabbing the hot tip of a soldering iron to remind you which is the

business end...

At any rate, things are going well today. I contacted my friend who is a simulator expert and

he has a preliminary version of the N8VEM coded up in a popular computer simulator. I tried

a pre-release version already and it works so well I was able to code up a revised CBIOS to

support the 1MB ROM as the F: drive without ever touching the SBC itself. Now I can run the

simulator and do all the programming on the nice PC in a comfortable chair. When I am

satisfied it is working, take the resulting ROMIMAGE.BIN on a floppy disk downstairs, burn

an EPROM, plunk it into the SBC and presto! instant working program.

Normally debugging the CBIOS on target hardware can be a chore but now it is a breeze. I

updated the CBIOS and now the F: drive contains the CP/M transient programs. I am going to

upload a new set of N8VEM software tonight. Once I get clearance from my friend to release

the simulator, I will do that as well assuming he will release it. I am pretty confident he will

but just in case, I will hold off until he gives explicit permission to publish.

Soon you'll probably be able to take the N8VEM SBC out for a test drive on your PC to see

how it works for you. Literally its "try before you buy" to see how the system works before

investing in the PCB or the parts needed to build it.

Which brings up another point, it is way off topic but please let me digress; if you had a nearly

empty 1MB ROM disk on a SBC what sort of programs would you put on it? My thinking was

the basic CP/M transient programs would be cool. Now that those are there though I

recognize that takes up practically no space at all. Of the 992K available, the CP/M transient

programs only take up about 56K leaving 926K available for other programs. Got any ideas?

Probably a good start would be a utility tool set with a decent editor. ED is *not* your

friend. ;-)

Regarding my curiosity about ROMIMAGE.BIN file, I noticed that there are rows

-11-

after rows of

$0 zerrrros there that reminded me so much of "my own bank account"!! :violin:

I guess it hit a nerve in me or something...:happy7:

Yes, that is correct. Most of the 1MB ROMIMAGE.BIN is empty. It is just waiting for some

worthwhile information to add to the F: drive and essential utilities for the A: drive as well. I

still have to hand code the tiny utilities into the A: ROM drive. I was thinking I would add the

IDE drive format utility and maybe a utility to get at the NVRAM in the DS1302. There is no

hurry right now though.

As for the bank account, I think we can all appreciate that feeling from some time or another...

:-) My goal is to keep the cost as low as possible and just offer the PCB. The rest of the parts

can be obtained in many ways to keep costs down. My recommendation is to raid the junk box

first, then obsolete/junk PCs and/or scrap electronic equipment. I suspect an enterprising

person could recover most if not all the parts necessary from scrap recovery of a few PC

boards. All of the components were selected with that idea in mind. I admit the 512Kx8 SRAM

will be a little more difficult.

Would you please take your time (????) and explain a bit more about addressing on

your N8VEM board?

1- Signals such as CS_CFG, and CFG...

2- Logic to ensure upper Ram is always enabled

The signals with the CS_ prefix are used for IO decoding and stands for Chip Select. There is

some IO address decode logic which detects when the CPU is requesting the onboard IO

devices. Specifically, any time the CPU is requesting IO (/IORQ low) and the address on the

lower 8 bits of the address bus are in the $60-7F range.

When those conditions are met, the 74LS139 demultiplexer narrows it down further into

specifically what IO device is being requested. It generates "Chip Select" signals for the 8255

PPI if the address is $60-$67, the 16550 UART for $68-$6F, the RTC for $70-77, and the

MPCLs for $78-7F. The "Chip Select" signal is normally high but when the CPU wants to

connect to a specific IO device, it pulls the devices "Chip Select" pin low to force the device

out of "tristate mode" and actively on to the buses. Each of the CS_* lines go to the chip select

pins on the various IO devices.

The normal state for IO devices when not being specifically accessed is to be in tristate mode.

They are physically connected but all the inputs are in a very high impedance state so they act

like they are not present in the circuit.

Regarding the logic to ensure the Upper RAM is always selected is something different and

relates only to memory mapping. One thing I found during the design phase is the CPU has to

have some region of memory which is essentially permanent so it can retain its own context.

There are two memory pages, the lower 32K and the upper 32K, and the lower 32K page is

switchable. As a result, the 74LS32at U15 ensures the upper 32K page ALWAYS goes to the

same region of the 512K SRAM (A15, A16, A17, A18 all high). No matter what the CPU does

to the MPCLs to reconfigure memory, it is ensured that the program actually making the

changes (assuming it is in the upper 32K RAM page) is always present in the address space. It

may seem silly but you'd be surprised at how easy it is for a CPU to manipulate memory and

suddenly it loses all context and crashes.

After reviewing the schematic, I noticed the terminology I used during the hardware phase is

not the same as what I described during the software phase. I'll update the schematic to make

sure it is more consistent with the terms used in the software source code. It is confusing

when I use two different terms to refer to the same item.

Would you please explain about "ECB data flow direction control"?

-12-

How does it switch direction?

The ECB bus control is in two parts; the address/control lines and the data lines. I'll explain

the address/control lines first since those are easier.

The address/control lines are "export only" from the SBC perspective virtually all the time. In

other words, the address/control lines are repeated from inside the SBC onto the ECB but not

vice versa. The only exception to that is when something on the bus asserts bus control by

lowering the /BUSRQ line. In that case, the CPU goes into BUSRQ mode and the ECB places

the address/control lines into the SBC. Again, this is a pretty rare scenario but it is possible

and the SBC supports it if and when a "bus mastering" peripheral is ever made. Possibly

another CPU card could do this.

The SBC data lines are "import and export" depending on the situation. Normally, the SBC

exports the data lines onto the ECB and does not import them. There is two exceptions

though; first is the /BUSRQ being pulled low by a yet undesigned peripheral which is pretty

rare, and more likely is the SBC CPU has made a IO request READ (/IORQ goes low and /RD is

low) AND the IO address is outside of the internal SBC IO range ($60-$7F). In other words,

the CPU is requesting to IO reads to IO address EXTERNAL to the SBC.

In all cases, it is fairly rare for the SBC to be pulling information (address, control, or data) in

from the ECB. Normally, it just transmits the internal CPU bus onto the ECB for peripherals to

observe and act on.

Now you may have noticed one peculiarity about this implementation of the ECB. The SBC

supports CPU MEMORY WRITES (/MERQ low and /WR low) onto the ECB but it does NOT

support CPU MEMORY READS from memory on the ECB. The address, control, and data lines

are all there to perform the task but the SBC internal bus control logic is limited for the sake

of simplicity. Also, the 1M ROM and 512K RAM is likely sufficient for actual real memory for a

relatively simple CP/M or monitor based system. More than that would probably go to a

secondary store like a disk drive.

If and when there is ever a next generation SBC, I will probably change the bus control logic

to allow CPU MEMORY READS across the ECB. The modification would require changes to

the RAM/ROM memory selection logic to allow RAM disabling in order to leave the lower 32K

page fully deselected (ie, nothing is there at all, no internal RAM nor ROM) so the ECB

peripheral memory would have a "hole" in the CPU address space to exist in. Also, the bus

control logic would be changed to allow changing the data bus direction flow in to the SBC

from the ECB whenever the SBC requests a memory write from the lower 32K memory page

AND the lower 32K memory page has been disabled.

Probably, I could have made those modifications in the initial design but I put them off to

lower the risk down on this SBC design. I had strayed off my prototype already in a few areas

and I wanted to make sure the PCB version was fairly close to prototype to increase the

likelihood it would work. PCB respins are expensive in terms of time and money so risk

introduced by "feature creep" is highly undesirable.

In practical terms, having an IO only ECB is not a limitation for all the peripherals I would like

to make. Virtually all of the Z80 style peripherals communicate via a IO ports. Even the "pipe

dream" video cards (SY6545 and TMS9918) use IO ports only. What would be more difficult to

implement would be ECB memory expansion (RAM/ROM) or memory mapped peripherals like

a 6845 VDU. However, even those are possible by just using IO ports and latches to simulate

the memory accesses. In other words, we are a LONG WAYS away from ever encountering

this theoretical limitation and if and when it ever does get realized, there are relatively simple

fixes to either get around it or resolve it as needed.

1- what is the role of A1 and A2 in extended Ram/Rom addressing and why?

2- Who/What is taking care of stack manipulation when in extended addressing

mode?

The A1 and A2 are used in the IO decoding of the RAM or ROM MPCLs. Remember, Z80

-13-

circuits and peripheral chips are all active low logic (ie, when high = not enabled, when low =

enabled) The OR gate acts like an AND gate in "active low" logic mode.

If A2 = 0 and A1 = 0 and /CS_CFG = 0 then /CS_CFG1 = 0 (ie, enable the chip select on the

RAM MPCL chip.)

If A2 = 1 and A1 = 0 and /CS_CFG = 0 then /CS_CFG2 = 0 (ie, enable the chip select on the

ROM MPCL chip.)

The "active low" logic has a nasty tendency to turn all of what you learned in school on its

head but after you work with it a while it starts to make sense.

Regarding the CPU STACK while in extended addressing; the stack is set in the upper 32K

memory page because it is permanent. This is one of the many reasons why the upper 32K

*must* be fixed is that the CPU has to be able to depend on being able to correctly access its

stack during memory map manipulations. If the stack is $FF00-$FFFF and that 32K RAM

page is permanently fixed to the same physical RAM 32K block then the CPU is assured that

when it pulls its context off the stack (ie returns from an interrupt or subroutine) it gets the

right stuff and not some random garbage that just got paged in.

You'd be surprised at how hard it was for me to learn that particular lesson. Lose the stack

and the CPU quickly goes insane! CPU context bugs are tough and can be hard to get your

head around all the permutations and combinations it can manifest itself. Stack loss is just

one of many... accidentally trashing a good stack is another as is changing the RAM context in

midstream due to a memory page switch (ie, never execute code in the lower 32K memory

page while switching memory page context!). Hopefully, this clarifies things a bit!

1- what is the role of A1 and A2 in extended Ram/Rom addressing and why?

...The A1 and A2 are used in the IO decoding of the RAM or ROM MPCLs.

My bad...and thank you for clarifying it Andrew! I was under the impression that

you will be using the Data lines to enable and establish the Ram/Rom page, but

you are actually using the Address lines in addition to Data lines. So you would be

using:

Out Ad, Da

where, Ad represents A7 A6....A2 A1 A0 and Da represents D7 D6....D0 .

Why aren't you using A0?

Well, sort of. Yes, the address lines are used by the IO decoding circuit to identify the

appropriate MPCL (RAM or ROM) and the data lines set the values in MPCL. However, the

CPU address or data lines do not explicitly set the extended address lines on the RAM or the

ROM, the CPU only tells the MPCL to do it.

It is a subtlety but an important one; the MPCLs act effectively as an extension of the CPU for

higher memory accesses and they are accessed as IO port devices. Otherwise the CPU would

have no way of controlling the memory in excess of 64K using its 16 address lines.

In other words, the CPU manipulates the MPCLs and the MPCLs control the RAM and ROM

extended addressing. It is an indirect relationship but it works. Of course a Z80 with a 20, 24,

or 32 bit address bus would make this unnecessary but then you'd have an 8088, Z8000,

etc. :-)

PS, I am not using A0 as part of the IO decoder as each device is allocated an 8 address range

for IO ports. It is unnecessary as the MPCLs each have their IO address mirrored across 4

addresses (RAM MPCL is $78-$7B, ROM MPCL is $7C-7F). The reason is the UART requires 8

addresses for control and to keep the decoder logic simple and small, I allow a 32 address

range of IO ports dedicated to the "on board" IO devices (PPI, UART, RTC, and MPCLs).

-14-

...the address lines are used by the IO decoding circuit to identify the appropriate

MPCL (RAM or ROM) and the data lines set the values in MPCL...

The point I am making is that by using an "Out Ad, Da" command you would be

placing the appropriate signals on the lines for the decoding section (MPCL) to

access the IO device. It is the Out instruction that is doing the job.

...I am not using A0 as part of the IO decoder as each device is allocated an 8

address range for IO ports. It is unnecessary ...

I am saying that you could have used A0 & A1 instead of A1 & A2, but you just

chose A1 & A2 instead.

Oh, I see what you are saying... yes, the OUT instruction is used for setting the extended

addressing. The CPU uses data and address lines to with the OUT instruction accessing the

MPCLs.

I could have used the A0 address line as part of the decoding and it would have worked. My

thought was to keep the RAM MPCL IO port in on region ($78-$7B) and the ROM MPCL in

another ($7C-$7F). Using A0 would have caused the IO ports to alternate on even/odd

addresses but since practically speaking you really only access a single IO port how they are

mirrored is not much of an issue.

If I had more PCB room, I would change the IO decoding logic to be a lot more specific and

only the minimum necessary IO ports and reduce the usage of IO address space. However, in

order to keep the design simple there was some trade off with efficiency. Its design artifacts

like this which make using large PCBs and/or custom chips so appealing but of course that

drives cost. Its all a trade off in the end...

Great questions and good observations! Thanks and please let me know if there are any other

aspects I can help with!

Looking at the schematics for your N8VEM board, some clarification would be very

helpful regarding the role of A15:

1- whenever A15=1 (high) --> Ram is selected

2- whenever A15=0 (low ) & Rom is NOT enabled (Rom_Enable=1) --> Ram is

selected

3- whenever A15=0 (low ) & Rom is enabled (Rom_Enable =0) --> Rom is selected

4- whenever A15 = 1 --> we are in the higher 32k

5- whenever A15 = 0 & Ram is selected --> we are in the lower 32k

Higher 32k, one page only

A15 A14 A13 A12 A11 A10 A9 A8 A7 A6 A5 A4 A3 A2 A1 A0

1 - - - - - - - - - - - - - - -

1 1 1 1 - - - - - - - - - - - - - - -

A'18 A'17 A'16 A'15 A14 A13 A12 A11 A10 A9 A8 A7 A6 A5 A4 A3 A2 A1 A0

Lower 32k, 8 pages

A15 A14 A13 A12 A11 A10 A9 A8 A7 A6 A5 A4 A3 A2 A1 A0

0 - - - - - - - - - - - - - - -

- - - 0 - - - - - - - - - - - - - - -

A'18 A'17 A'16 A'15 A14 A13 A12 A11 A10 A9 A8 A7 A6 A5 A4 A3 A2 A1 A0

where, A' is A_Ram in schematics

- can be any binary value.

-15-

Generally speaking, stack pointer SP has no idea which page we are in, and I

assume it

always refers to the higher 32k where our main program is located. Thus any line

of

program placed on other pages that uses Call or RET would end up in the LA-LA

land unless

we can devise a very sophisticated stack manipulation manager.

Any comment would be much appreciated...

Yes, I think you have it regarding A15 and the memory paging circuit. Thanks, yours is an

excellent description and that was probably one of the more challenging aspects of getting the

home brew prototype to work.

While CP/M is running, the only RAM pages that should have any programs executing in them

are the very top (upper 32K; A15, A16, A17, A18 all high) and the very bottom (lower 32K;

A15, A16, A17, A18 all low). That is where CP/M has its TPA and main memory. The rest of the

RAM is basically just a block device (RAM drive).

The design theory is CP/M and the stack would exist in the upper 32K so that in any event, the

CPU would retain proper context information. There is no guarantee though as programmers

could write programs to run *ANYWHERE*, even from within the ROM (which isn't a bad idea

either, it sure would save TPA space by shrinking the CBIOS). The only program that exploits

this ROM "execute in place" feature is the loader but it is theoretically extendable to any

program. Similarly programs could execute in the other RAM pages as well but stack

management becomes an issue.

However, *in theory* it is possible to have programs executing anywhere in the RAM but as

you pointed out it is the responsibility of the program designer to keep track of CPU and

memory context. That is the hazard of executing any program in bank switched memory and

not unique to this SBC design.

If any advanced operating systems come out with support for this platform, they'll have to

take this fundamental design approach into account. I am pretty sure there are some Z80 real

time OS's around so it is possible but fairly unlikely. I suspect most people will be thrilled to

run the monitor and CP/M (I know I am!) although you never know what people will do. :-)

Well, since you are helping create some great detailed technical documentation (theory of

operations) for the "N8VEM" by extracting this information out of my brain maybe there are

some other angles people would like to try?

I got asked a question about the "parts list" for the SBC which might be helpful. My plan was

that the schematic and the PCB layout were sufficient to select parts but maybe people would

be more comfortable with a formal Bill Of Materials? Detailed building instructions wouldn't

hurt either but I think we need to get some PCBs out there to do that...

I don't know where I should post this, but for the sake of consistency,

I go ahead and post it here :) !

I have always had this question about handshaking procedure for terminal

emulators; some SBCs use only null cables and some others use standard serial

cables. Would you please explain about the handshaking procedure for an

emulator such as Hyperterminal?

There is a similar thread on the N8VEM discussion board. Seth was able to get his SBC to

work using his serial cable like this:

[N8VEM -------- 9-pin DSUB]

2 (DSR) ------- 4

3 (RX) -------- 3

5 (TX) -------- 2

-16-

7 (DTR) ------- 6

9 (GND) ------- 5

Seth posted photos of his serial cable so you can see it up close.

http://groups.google.com/group/n8vem/t/8730736c05641986

My cable is a bit different since I am using HyperTerm and like to use hardware handshaking.

PC DB25 (9 to 25 pin cable) SBC (25 pin female)

2 TD----------------------RD

3 RD----------------------TD

7 GND---------------------GND

6 DSR---------------------DTR

20 DTR----+----------------DSR

5 CTS----+

It is the same as what you have except pin 20 DTR and 5 CTS are wired

together. This allows hardware handshaking using HyperTerm.

As to whether it is actually using hardware handshaking is probably a

matter for debate but at least it doesn't hang anymore...

Making serial connections between computers, especially the older ones, is a complicated

subject. I can usually make something work with a RS-232 breakout box but I am no expert on

the subject that is for sure. I like to use hardware handshaking whenever I can but sometimes

it isn't an option.

Source:

www.vintage-computer.com

-17-

Comments (0)