Last modified on 12 May 2018, at 09:49

CP/M 2.2

Revision as of 09:49, 12 May 2018 by Arnoldemu (Talk | contribs) (Amstrad's implementation of CPM 2.2)

CP/M 2.2 after boot

Operating system for the Intel 8080 and Zilog Z80 based computers by Digital Research

CP/M 2.2 was the first CP/M avaiable for the Amstrad CPC. A minimum requirement to run CP/M was a disc drive therefore CP/M 2.2 came bundled with the Amstrad DDI-1 discdrive with the BIOS in the AMSDOS ROM, making it possible to run CP/M 2.2 on the Amstrad CPC 464. Later when the Amstrad CPC 664 was released, CP/M 2.2 came together with this machine as the 664 had a built in discdrive. With the CPC6128 it was on one of the two system discs, with CPM+ on the other.

Implementations

Vortex's implementation of CP/M 2.2

Amstrad's implementation of CPM 2.2

CP/M 2.2 was distributed with the DDI-1 disc interface, the CPC664, and on side 1 of the CPC6128 system discs. It provided 41K TPA. Details of the implementation are in the DDI-1 Firmware SOFT158A. The following attempts to give more detail than described there.

Serial number

The CPM2.2 serial number appears to be stored on the disc. This is the number that is in the box on the label. Not the one with "serial number" next to it.

It's a 6 byte number stored after 'USER' on the disc. D0 seems to be Amstrad's manufacturer code.

MOVCPM

MOVCPM is used to change the size of the TPA which is the area used by programs. This relocates CCP and BDOS. SYSGEN then writes this to a disc so that when this disc is booted CP/M has a different sized TPA. By reducing the TPA, memory is freed up which is not touched by CPM and which can be used by the user.

CPM 2.2 is generated using MOVCPM on the CPM 2.2 disc as follows:

MOVCPM 179 *

Which reports a 44KB CPM (Which is TPA+CCP+BDOS).

If you wish to reduce the TPA you need to use a smaller number. e.g.

MOVCPM 160 *

Which reports a 40KB CPM.

Once done, then use SYSGEN * to write it to a new disc.

Contents

CPM 2.2 with DDI-1

  • Single 3" disk, two sides.
  • CPM 2.2 only
  • Side A is bootable, starts CPM 2.2 but stops at command prompt, and has AMSDOS.COM, ASM.COM, BOOTGEN.COM, CHKDISC.COM, CLOAD.COM, COPYDISC.COM, CSAVE.COM, DDT.COM, DISCCHK.COM, DISCCOPY.COM, DUMP.ASM, DUMP.COM, ED.COM, FILECOPY.COM, LOAD.COM, MOVCPM.COM, PIP.COM, ROINTIME.DEM, SETUP.COM, STAT.COM, SUBMIT.COM, SYSGEN.COM, XSUB.COM
  • Side B is bootable, starts CPM 2.2 and automatically starts LOGO and has AMSDOS.COM, LOGO.COM, SETUP.COM

Details of files:

  • AMSDOS.COM will reset the CPC and return back to BASIC.
  • ROINTIME.DEM is a demo of "ROLAND IN TIME" from Amsoft.
  • LOGO.COM is Logo v1.1
  • the AMSDOS rom contains part of LOGO

Technical information

CP/M 2.2 uses the firmware. There are 2 BIOS jumpblocks in RAM and the "ENTER FIRMWARE" which can be patched. The normal CPM BIOS jumpblock and an extended one.

CP/M uses the firmware extensively and enters it via "ENTER FIRMWARE".

The BIOS is in the AMSDOS ROM, and this uses the jumpblocks in RAM.

The AMSDOS ROM also uses part of the RAM for XDPB storage and a sector buffer. (The BASIC facing side of AMSDOS is not active.)

The TPA is limited because the CCP, BDOS and firmware jumpblocks are in main RAM. The result is a ~33KB TPA for a CPC system which is OK.

  • Amstrad CPM2.2 uses Amstrad's "System" format. This is 40 tracks, 1 side, 9 sectors per track numbered &41-&49. Each sector holds 512Bytes. There are two reserved tracks, then the directory which has 64 entries, and then the data area.
  • CP/M is booted by a RSX command "|CPM" which is implemented by the AMSDOS ROM (the standard disc ROM in the DDI-1, CPC664, CPC6128 and 6128Plus).

1. The |CPM command loads track 0, side 0, sector 41 into ram at &100 and jumps to it. This is the boot sector. (The boot sector occupies &100-&2ff).

2. The boot code copies the BIOS jumpblock from the AMSDOS rom to &500. (In the AMSDOS ROM this is located at &C17F. The actual address is passed to the boot rom in BC).

3. The boot code then loads track 0, side 0, sector 42 into ram at &300 which is the "configuration" sector which defines colours, mode, and keyboard translation tables. (The configuration sector occupies &300-&4ff). The configuration sector sets the mode and displays the start up text.

4. Finally the boot code calls CPM "WBOOT".

  • WBOOT loads 1 sector from track 0, side 0, sector 48 to the sector buffer. This is the first sector of platform independent part of CPM.
  • It then peeks into the sector buffer and reads from offset 1,2 the address of the first JP of the CPM code. This is normally JP &9A5C.
  • It adds &FCA4 to this address to get the start loading address for CPM CCP/BIOS which becomes &9700. Then it copies the sector into RAM. Therefore this address is used to relocate CCP/BIOS. This address can be indirectly defined using MOVCPM utility.
  • It now loads 10 further sectors (of the platform independent CPM) to start + &200 (normally &9900). This goes up to &AD00.
  • It adds &EA00 to &AD00 to get back the original start of &9700. It remembers this.
  • It adds &F206 to start (&9700) to get the start of the BDOS (normally &9F06) and stores this address in the JP at &0005.
  • It recalculates the BDOS jumpblock (normally at &AD00 and stores the address of the WBOOT)
  • Next it copies the bios jumpblock from the ROM to this address.
  • Finally it jumps into CCP and starts it (&9700).

Memory Map

Small memory map of CP/M 2.2

CP/M runs with ram selection 0 (i.e. LD BC,&7FC0:OUT (C),C ) and assumes the upper ROM is enabled and is the one with the CPM BIOS in it (i.e. AMSDOS.)

Therefore if you patch CPM you need to:

  • ensure the RAM selection state is as expected
  • the upper ROM is enabled and AMSDOS ROM is selected (this can be done using firmware functions to get the current rom state and number and restore it).
  • avoid touching AMSDOS/firmware areas unless you are also patching it.
  • restore the alternative registers if you modify them.

The lower firmware jumpblock exists at &0000-&0040 because it is needed by the firmware jumpblock to call into the OS rom. The following changes are made for CP/M 2.2:

  • &0000-&0002 => WBOOT (JP &AD03)
  • &0003 => IOBYTE
  • &0004 => user number/drive number
  • &0005 => &0007 - BDOS (JP &9F06)

TPA is from &100-&96ff (38400 bytes, 37KB TPA). Then:

  • &9700 - &acff => CPM 2.2 CCP/BDOS (This can be moved with MOVCPM.)
  • &ad00 - &ad32 => CPM BIOS jumpblock. (This can be moved with MOVCPM.)

Each entry is a JP instruction. (The address of this can be calculated from CP/M if you need to patch it. Take the address at &0001/&0002 and subtract 3 to give the address of the boot JP instruction). These jumps including enter/exit firmware can be patched.

If you plan to patch it for additional hardware and need memory then you will need to use MOVCPM to reduce the TPA size.

The memory allocated by MOVCPM follows the CPM BIOS jumpblock up to &ad33 in RAM.

For CPC AMSDOS the BIOS jumpblock has the following addresses in it:

boot - C1B2
wboot - C2BE
const - C2E1
conin - C2C3
conout - C2C8
list - C2D2
punch - C2D7
reader - C2DC
home - CDE9
seldsk - c2f2
settrk - c524
setsec - c529
setdma - c51a
read - c2f7
write - c2fc
listst - c2cd
sectran - c55a
  • &ad33 - &ad36 => "enter firmware" jump. This doesn't move when MOVCPM is used.
  • &ad37 - &ad42 => used by "enter firmware" for storage of registers etc for transitioning to firmware and restoring back.
  • &ad43 - &bb00 => used by AMSDOS.
  • &b900 - &be00 => main firmware jumpblock
  • &be40 - &be7f => used by AMSDOS and locates the XDPB for each drive.
  • &be80 - &bebf => CP/M 2.1 BIOS extended jumpblock. (functions here used by conin, conout, lstst, list, punch, reader, const and action depends on iobyte. )
  • &bec0 - &bfff => stack
  • &c000 - &ffff => screen

When MOVCPM is used the memory looks like this:

low firmware jumpblock, &100..<top of TPA>, CCP/BDOS, BIOS jumpblock, <free space>, &AD33 "enter firmware", firmware etc.

Patching the BIOS jumpblock

The BIOS jump block can be patched.

Note that the default boot and wboot call into the ROM and they are effectively a JP. They don't return.

  • WBOOT re-reads the CCP and BDOS from the system tracks and re-initialises the jumpblocks. It doesn't re-initialise ENTER FIRMWARE.

WBOOT is triggered when a transient CP/M program is quit. (e.g. run CLOAD and then press ESC to return back to CP/M). Therefore it's problematic if patched.

  • BOOT effectively performs a |CPM command from the beginning, re-loads the boot sector, re-loads the configuration sector and then re-runs WBOOT. This is also problematic to patch.

Both WBOOT/BOOT may not be patchable (to be confirmed) and if they are you need to use very specific firmware related hacks or quite involved hacks.

XSUB.COM

X-Sub is a persistent program which is loaded at the top of TPA. This is how it works:

  • X-Sub patches the BDOS jump to it's own JP.
  • The relocated X-Sub module starts with a JP and has 'xsub' immediately after it.
  • X-Sub detects if it's installed by reading the BDOS JP and searching for 'xsub'. If found it is already installed, otherwise it's not. Based on this method it uses it assumes it has been installed last.
  • It assumes that the address of the JP defines the top of TPA memory (the start of CCP). It then takes the address and subtracts it's size to allocate space, copies itself up to this memory and relocates the code, and then executes it's startup code.
  • The startup code installs it's own wboot JP and it's own bdos JP.
  • It then returns back to CCP.
  • X-Sub's wboot restores the dma address and jumps back to CCP.
  • X-sub's bdos jump filters the BDOS calls. It also remembers the dma address when used.

Installing persistent programs

There are various ways to install persistent programs but they are all specific to the CPC version of CP/M 2.2.

Method 1

This method installs a persistent program outside of CP/M.

  • Use MOVCPM to allocate some RAM - TPA will always be reduced even when your program is not running.
  • When your COM program is loaded locate the BIOS jumpblock.
  • Add &33 to this to get the first byte of useable RAM - the last byte is &AD32. You can use this to check if there is enough free space for your program to be installed. There doesn't seem to be a way to determine if there is a program installed already so it looks like only 1 program at a time can be put here.
  • Your program can then patch the BIOS jumpblock and re-direct to it's own functions. It is best to keep a copy of the functions you patched so that you can call them.

File:Driver.zip template for a device driver.

Method 2

This method installs a persistent program inside CP/M and uses TPA when it's installed.

See above how XSUB installs itself.

Links

Download

Manual