A Better CCPPATCH for CP/M 2

A patch was developed many years ago to cause CP/M 2 to look on drive A: if it couldn’t find a .COM file. This is probably a precursor to the Windows and MSDOS search PATH command, though unix may have already had a PATH variable.

You can find a copy of the patch to search drive a at: www.classiccmp.org.

BUT it has some side effects.

It worked great for me; until I mistyped a command.

This is what you get normally:

B>dir
NO FILE
B>stat
A: R/W, Space: 372k
B: R/W, Space: 490k


B>

This is what you get with a mistyped command:

B>stap
Bdos Err On C: Bad Sector

I have two disks in the system (A: and B:) and the patch tries to access drive C.

Here’s the text of the patch:

; This patch causes the CCP of a cp/m 2.x system to look on drive A
; when you are logged into a drive other than A and call for a .COM
; file that does not exist on that drive.  Giving an explicit drive
; reference overrides this feature, so that you can always force
; the file to be loaded from a specific drive.
;
msize	equ	60		; set this to your nominal system size
;
cpmb	equ	(msize-20)*1024+3400h	; start of CCP in given sys size
;
	org	cpmb+6dbh
	jz	patch		; replaces "jz cpmb+76bh"
;
	org	cpmb+7f2h	; replaces an unused area of NOP's
patch:
	lxi	h,cpmb+7f0h	; get drive from current command
	ora	m		; accum was 0 on entry, so this fetches drive
	jnz	cpmb+76bh	; command has explicit drive...give error
	inr	m		; force explicit reference to drive A
	lxi	d,cpmb+7d6h	; we need de set up when we
	jmp	cpmb+6cdh	; re-enter ccp
;
	end


The idea is good: if open fails for the .COM file you jump to a patch area, change the drive specifier from 0 (default) to 1 (drive A), and then redo the process. It has enough smarts to exit if there is already a drive specifier (eg if we typed B:PROG). This also prevents loops if the .COM file isn’t on drive A either (because we now have a drive specifier).

If you look at the code in the CCP that this is patching, you’ll notice that it is changing a drive setting for the CCP; not just for the .COM file we are trying to run. The ‘inr m’ seems to be causing a broader impact (like accessing one more than the current drive – C: when we are on B:).

I found an alternative approach to work better. For a 64K system (cpmb equ 0E400H, CCP at E400-EBFF) it looks like:

EADB:  CAF2EB  JP Z,EBF2

EBF2:  1A      LD   A,(DE)
EBF3:  B7      OR   A
EBF4:  C26BEB  JP   NZ,EB6B ; to the original error msg
EBF7:  3C      INC  A       ; fcb[0] to 01, ie A:
EBF8:  12      LD   (DE),A
EBF9:  CDD0E4  CALL E4D0    ; retry the open that failed last time
EBFC:  C3DBEA  JP   EADB    ; back to just after last time
EBFF:  00      NOP


For other memory sizes, subtract 4 from the “E4”, “EA” and “EB” values, for each 1K less. This is what the original “cpmb …” line does.

The CCP is the first thing on a bootable disk after the boot sector. On an 8″ SSSD or DSSD system it is in track 0 sector 2 to sector 17 so use a disk editor to patch sectors 15 (EA80-E400=680=13 sectors) and 17. DD sectors are 200H each so if you’re using DD disks, both parts will be in sector 5.

I tend to edit disk images directly, using a hex editor in Windows. You could use GETSYS / PUTSYS and DDT/ZSID within CP/M to make the same changes.

This is what I get normally:

B>dir
NO FILE
B>stat
A: R/W, Space: 372k
B: R/W, Space: 490k


B>

This is what I get with a mistyped command:

B>stap
STAP?

B>


The difference is I use the FCB address in DE and check and change the drive specifier for the .COM file instead of for the CCP.

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 *