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.