Hardware Design

A project log for My CP/M Single Board Computer

A simple computer based on the CP/M OS and flash chips for disk drives

agp.cooperagp.cooper 10/12/2019 at 14:080 Comments

Hardware Design

To keep things simple I am using what I have in my box of electronic spares.

I have a heap of 32k x 8 RAM and 32k x 8 Flash ROM.

I may even have an 8085 chip somewhere?! I will order some anyway.

Once I get the prototype working I will upgrade the Flash ROM from 32kb to 256kb.

For CP/M the O/S resides in top of RAM and programs are executed near the bottom of RAM (after 100h). Any ROM has to be above the RAM.

But for boot up, at least initially the ROM need to start at 000h.

To do this I designed a boot flipflop that set A15 high on reset. Upon accessing an address above 32k, the A15 line can go low.

The flipflop uses a quad NOR gate:

And here are the signals:

I will come back to the hardware design later.

As CP/M uses a console to communicate to the outside world the simplest answer is serial. So I have used a USB to Serial converter for communications and power. The USB port has enough power for CMOS versions of the chips. The main power hog is the RAM at 140 ma. Next is the AT29C256 at 50 ma and then the MSM80C85A-2 at 20 ma.

I decided to use the 8085 SID/SOD signals (i.e. SIM/RIM opcodes) for serial communications rather than the 82C51A-2. Probably a mistake but I can use it for the next prototype if it was a mistake.

Here is the full schematic:

And the PCB (currently been made):

The interrupt jumpers (left) and expansion jumpers (right) are really just test points. I don't intend to use them.

8085 Code

I have not done much assembler coding before so this was a bi of a challenge.

My first attempt was pretty inefficient. So I stopped and examined the opcode more carefully. The trick seems to be to understand the flow of the 16 bit opcodes for the hl, de and  bc pairs. After that coding is much more constrained (i.e. it become obvious the best way to do something).

The first bit of code is the boot sector code to load the operating system:

;   boot.asm: Load CP/M from ROM
    org 8000h                           ; executed in ROM
    jmp 8003h                           ; reset bootstrap

;   Calc CPM addresses
msize       equ     32                  ; 32k RAM
sectors     equ     16                  ; sectors per track for my system
systrks     equ     4                   ; my boot system has 4 tracks =-int(-52/16) 
bias        equ     (msize-20-1)*1024   ; adjusted for my system =int((52+4-4*16)/8)
ccp         equ     3400h+bias
cstart      equ     4a00h+bias

    lxi     sp,ccp-0080h                ; convenient place
    lxi     d,ccp-0080h                 ; start of boot dst
    lxi     h,8000h                     ; start of ROM (boot src)
    mvi     c,sectors                   ; sectors per track
    mvi     b,systrks                   ; sytem track count
    push    b                           ; save 
    mvi     b,128                       ; sector size
    mov     a,m
    inx     h
    stax    d
    inx     d
    dcr     b
    jnz     boot$copysect
    dcr     c
    jnz     boot$nextsect
    pop     b
    dcr     b
    push    b
    jnz     boot$nextsect
    hlt                                 ; halt for testing
;   Cold boot
    jmp     cstart
I am currently using a85 from

It compiles (and runs) with no problems under linux. I only produces hex output so later I will have to convert this to a com file for CP/M.

The next assembler task is cbios. Too big to show here, it is in my file area.

Next Steps

Next steps is the test the codes in a simulator. Now I have to find one that is suitable.