• Please review our updated Terms and Rules here

CP/M 2.x directory structures, boot strapping, etc.

bakemono

Experienced Member
Joined
Jan 19, 2020
Messages
294
Location
USA
So I've written (most of) a CBIOS, with the goal of bringing up CP/M on my Z280 board. I have it configured for 32 sectors per track, so that one track corresponds to a 4KB memory page. The plan is to load a disk image into RAM, and have the BIOS disk routines temporarily swap MMU pages to read/write 128-byte sectors in the disk image / ramdisk.

What I've read is that CCP, BDOS, and BIOS go into the first two tracks. I found a dump which appears to have a base address of $DC00, and I think patching in my BIOS, putting it in a disk image, and making a boot loader should be straightforward.

The rest of disk image I'm not sure about. I've seen some info on how directory entries are laid out, but I'm not sure if I have all the details to make a disk image from scratch. I'd want to compare it with an existing disk to check that things are correct, but I haven't seen any disk images in a raw format. They are in some other format and when I look at one in a hex editor it doesn't make a lot of sense. If I have CP/M in RAM and running, is it possible to initialize a blank disk from there? Would it be enough to have the image full of $E5 or something, and then use the SAVE command to start adding files? Or is there a different process for turning a blank disk into a CP/M disk?
 
There is usually an option on the disk imaging tools (not sure what you are using) to extract the image in a raw format. Just watch out for any 'skew' factor.

Dave
 
Disk images are quite common, in purely binary format. Daver2's suggestion is that beware of formats that Skew the data (ie, logical sectors do not match physical sectors - done to improve loading times on slower systems.)

First, BOOT mapping does not exist in CP/M outside of the BIOS. It is the BIOS job to load CP/M and start execution, no matter the distribution, with the only exception I've seen being the Amstrad, where the boot process happens in hardware, and they load the BIOS from the boot sector also.

I run my BOOT from a BIOS chip, which is in directory format, so although I include a boot sector for the BIOS/BDOS, As long as your BIOS can stuff itself, the BDOS and the CCP into memory and perform a warm boot, you're good to go.

the BDOS cares about the file system after that, but only after that, and it will look to the tables in the BIOS to get enough information on how to access the disk system, which it does through the BIOS. You don't need a boot sector at all if your BIOS has another way of loading in the CCP/BDOS but it's convenient to have a boot sector. I did it by loading the BDOS/CCP from ROM - then I just reboot from files using the OS if necessary as a part of the process. I can also boot my system from other BIOS roms as my boot system looks for valid file systems on ROMS in BIOS locations like the PC does, and executes files in them. That's as far away as you can get from a normal CP/M system, but it still works well.

I've never tried a z280 board, but I'll treat it like a z80 system since you're talking about a standard CP/M image. Also, as long as you can boot, it doesn't even matter if there are *any* working or valid disks - you will still get a prompt. I may fail after that, but you will still get that far. If you have a working disk of a bad format, it will cause issue, but again, you can still try to work the CCP.

So here's an example of a functional CP/M directory structure. In this case, It's my memory manager, as I map a disk over my RAM to allow me to use the BDOS as a defacto memory manager - Ignore that it - it's the structure you want.

0000 - 00 52 4F 4F 54 5F 43 50 4D 49 4D 47 03 00 00 80 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 - +ROOT_CPMIMG++++++++++++++++++++
0020 - 00 56 49 44 45 4F 4D 45 4D 49 4D 47 03 00 00 80 C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF - +VIDEOMEMIMG++++++++++++++++++++
0040 - 00 56 49 44 45 4F 4D 45 4D 49 4D 47 07 00 00 80 D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF - +VIDEOMEMIMG++++++++++++++++++++
0060 - 00 42 4F 4F 54 5F 52 4F 4D 44 53 4B 03 00 00 80 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF - +BOOT_ROMDSK++++++++++++++++++++
0080 - 00 52 53 54 2D 23 30 38 48 49 4E 54 00 00 00 20 01 00 00 00 00 00 00 00 00 00 00 00 00 00 0F 10 - +RST-#08HINT+++ ++++++++++++++++
00A0 - 00 52 53 54 2D 23 31 30 48 49 4E 54 00 00 00 20 01 00 00 00 00 00 00 00 00 00 00 00 00 00 0F 10 - +RST-#10HINT+++ ++++++++++++++++
00C0 - 00 52 53 54 2D 23 31 38 48 49 4E 54 00 00 00 20 01 00 00 00 00 00 00 00 00 00 00 00 00 00 0F 10 - +RST-#18HINT+++ ++++++++++++++++
00E0 - 00 52 53 54 2D 23 32 30 48 49 4E 54 00 00 00 20 01 00 00 00 00 00 00 00 00 00 00 00 00 00 0F 10 - +RST-#20HINT+++ ++++++++++++++++
0100 - 00 52 53 54 2D 23 32 38 48 49 4E 54 00 00 00 20 01 00 00 00 00 00 00 00 00 00 00 00 00 00 0F 10 - +RST-#28HINT+++ ++++++++++++++++
0120 - 00 52 53 54 2D 23 33 30 48 49 4E 54 00 00 00 20 01 00 00 00 00 00 00 00 00 00 00 00 00 00 0F 10 - +RST-#30HINT+++ ++++++++++++++++
0140 - 00 52 53 54 2D 23 33 38 48 49 4E 54 00 00 00 20 01 00 00 00 00 00 00 00 00 00 00 00 00 00 0F 10 - +RST-#38HINT+++ ++++++++++++++++
0160 - 00 56 49 44 45 4F 52 4F 4D 44 53 4B 00 00 00 80 E0 E1 E2 E3 00 00 00 00 00 00 00 00 00 00 00 00 - +VIDEOROMDSK++++++++++++++++++++
0180 - 00 44 49 53 4B 5F 52 4F 4D 44 53 4B 00 00 00 80 E4 E5 E6 E7 00 00 00 00 00 00 00 00 00 00 00 00 - +DISK_ROMDSK++++++++++++++++++++
01A0 - 00 55 4E 41 53 53 49 47 31 44 53 4B 00 00 00 80 E8 E9 EA EB 00 00 00 00 00 00 00 00 00 00 00 00 - +UNASSIG1DSK++++++++++++++++++++
01C0 - 00 55 4E 41 53 53 49 47 32 44 53 4B 00 00 00 80 EC ED EE EF 00 00 00 00 00 00 00 00 00 00 00 00 - +UNASSIG2DSK++++++++++++++++++++
01E0 - 00 4E 56 4D 65 6D 6F 72 79 44 53 4B 03 00 00 80 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F - +NVMemoryDSK++++++++++++++++++++
0200 - 00 4E 56 4D 65 6D 6F 72 79 44 53 4B 07 00 00 80 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F - +NVMemoryDSK++++++++++++++++++++
0220 - 00 4E 56 4D 65 6D 6F 72 79 44 53 4B 0B 00 00 80 A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF - +NVMemoryDSK++++++++++++++++++++
0240 - 00 4E 56 4D 65 6D 6F 72 79 44 53 4B 0F 00 00 80 B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF - +NVMemoryDSK++++++++++++++++++++
0260 - 00 56 49 44 45 4F 20 20 20 44 52 56 00 00 00 80 01 11 12 13 00 00 00 00 00 00 00 00 00 00 0F 10 - +VIDEO DRV++++++++++++++++++++
0280 - E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 - ++++++++++++++++++++++++++++++++
02A0 - E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 - ++++++++++++++++++++++++++++++++
02C0 - E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 - ++++++++++++++++++++++++++++++++
02E0 - E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 - ++++++++++++++++++++++++++++++++
0300 - E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 - ++++++++++++++++++++++++++++++++
0320 - E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 - ++++++++++++++++++++++++++++++++
0340 - E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 - ++++++++++++++++++++++++++++++++
0360 - E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 - ++++++++++++++++++++++++++++++++
0380 - E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 - ++++++++++++++++++++++++++++++++
03A0 - E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 - ++++++++++++++++++++++++++++++++
03C0 - E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 - ++++++++++++++++++++++++++++++++
03E0 - E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 - ++++++++++++++++++++++++++++++++
 
All entries are the same. Any entry that starts is E5 is blank. Any entry that starts with 0 to 31 is a used ID. Generally, for your purposes, file locations should start with 0. The next 11 characters are filenames, then you have 4 bytes for file information, such as the file size, and how large it is. For most purposes, you only use the first and last ones, and keep in mind that Bit7 of any bytes in the directory have special meanings.

A file may have more than one entry, if it uses more than a single extent. An extent can use up to 16K, and I map 64K at a time for each entry, so I have 4 extents per entry. Most CP/M systems only have one extent per entry. Also, whether your entries support up to 255 blocks or 65535 blocks will affect whether you have 1 or 2 bytes per allocation. I have single-byte allocations in the above, and each allocation maps to a 4K block on the file system with a single byte.

Unfortunately, you can't tell any of that from this structure alone - you need the BIOS tables to make more sense of it. The BIOS tables tell you the drive structure and are used by the BDOS to understand the DISK data structure. The two critical elements are the Disk parameter Header (from the list of DPBs) and the Disk Parameter Block. Here's both for the above structure. I hope I corrected my source notes !

DP Header.
; DISK 12 (M) - Disk Parameter Header for Disk 0 - DISK M is the FIXED DISK for RAM, starting at 00000, No reserved tracks, and up to FFFFF. 256 allocations.
DW TRANS0 ; No translation, disk is exact.
DW 00 ; Scratchpad.
DW 00 ; Scratchpad.
DW 00 ; Scratchpad.
DW DIRBF ;
DW DPBMAD ; Memory as Disk.
DW CHK0C ;
DW ALLMAD ;

DP Block.

DPBMAD:
DW $20 ; 00,01 ; M drive is 32 sectors per track - DISK 12! is 128 byte "sectors" = records
DB 5 ; 02 ; 5 bits and 0-31 sectors per 4096k allocation.
DB 31 ; 03 ; See above.
DB 3 ; 04 ; Extent mask. Blocks are 4K, so should be 3.
DW 255 ; 05,06 ; This has 256 4K blocks. ( Allocation = 4 K ). Would be a 1024k disk. Lower 1Mb of RAM can be accessed as DISK.
DW 127 ; 07,08 ; 1 x 4k directory allocation = 128 file extents max. (128 total ) I think my format might be a little off though.
DB %10000000 ;09 ; Only set 1 bits so we know 1 allocation is directory
DB %00000000 ;0A
DW 0 ; 0B,0C ; Have set this as removable. Might be necessary to make as 0 for fixed.
DW 0 ; 0D,0E ; 0 track offset. First 4K is Directory Allocation ONLY. Allocation 1 is first memory space.

All of these things need to be correct for the BDOS to function correctly. Though as I note, if you get them wrong, booting is still possible.

Also, my entries are for my own OS, but CP/M reads them just fine.

Of note, you can reserve tracks for boot tracks - the last value in the Disk Parameter Block is the track offset. I have mine set to 0, because I boot differently, but generally a boot disk will show a 1 here or maybe 2. That's how many tracks are reserved for the BOOT system to use. So you might have a 1 in there, which gives you 32 records ( or was it Blocks in your design?) to boot from, which should be enough. Generally, you just lay out the BDOS and CCP, or maybe the BIOS/BDOS/CCP and have your boot rom read the disk and load these into place.

I hope this helps a bit. What do you need to know next? Reading the CP/M documentation is also a great start.

Is your current issue that you want to boot, or that CP/M isn't reading the disks correctly?
 
Last edited:
Just a thought - If you've written the BIOS, can you post your Disk Parameter Header, your Disk Parameter Block and talk about what kind of disk structure you want?
 
Thanks for the detailed info. This is my DPH and DPB:
Code:
dpblock.w:
        dw 32               ; sectors per track  (in 128-byte units)
        db 3                ; block shift
        db 7                ; block mask
        db 0                ; extent mask
        dw 255              ; highest block number  (DSM)  (in clusters)
        dw 63               ; highest directory entry number  (DRM)
        db $C0              ; directory allocation pattern  (bits set according to how many clusters
        db 0                ;        are used for the directory)  (32 bytes per directory entry)
        dw 0                ; directory checksum  (CKS)  (0 for non-removable media, else DRM +1 /4)
        dw 2                ; number of reserved tracks

        alignw

dpheader.w:
        dw 0                ; address of sector number translation table
        dw 0,0,0            ; BDOS scratchpad
        dw dirbuf           ; address of a 128-byte buffer for BDOS
        dw dpblock          ; address of disk parameter block
        dw drive1csv        ; address of CSV scratchpad  (unique to each drive) size = CKS
        dw drive1alv        ; address of ALV scratchpad  (unique to each drive) size = DSM /8 +1
I believe that will allow for a 256KB disk with 1KB blocks. (4KB per track.) I haven't tried to boot yet, because I was unsure what was required to make a valid (raw) disk image. But given your example of what the directory area should look like, I'm now ready to give it a try. Hopefully I'll get a chance tomorrow.
 
Reading it, you have 2K of directory space - so blocks 1 and 2, hence the first allocation in the file system should start with 3. You have 64 directory entries in your directory.

2 reserved tracks = 8K for boot, so you should be able to fit the CCP and BDOS and the BIOS too perhaps ( depending on whether your BIOS is in the boot ROM or the image ).

No translation tables = no skew.
BDOS scratchpad in place.
You don't have the DPB Block in the header pointing to the one in code (dpblock.w) - I assume that's addressed elsewhere via DPBLOCK being a pointer to DPBLOCK.W?

I can't see your checksum vector, and your allocation vector and assume these are OK and set sufficiently for your application.

Looks good to me.

question1. Does your boot room load the BIOS/BDOS/CCP from the boot sectors?

CP/M doesn't care about the structure of boot tracks. it doesn't define them at all. Ideally, your boot rom should know enough to access the disk, load sequential sectors and stick them in memory before resetting via a BIOS jump, and it's reasonable to have the first think the BIOS does as page-out or disable the boot rom.

As for disk structure, well, if you make the disk structure all E5 (blank), you can always boot, use SAVE from the CCP, and then examine the disk image to see what it saved, where and how. It should be in the first 32 bytes of the directory on logical track 3.

So you don't actually need anything in the directory structure of the disk to boot properly.
 
You didn't mention what sort of disk you are using, but I'm guessing it is some modern solid-state type like CF or SDCard. Rather than create your disk images from scratch on the target machine, you might consider getting cpmtools and using that to create the initial image file on your PC. From there, you can write the image file to your media and insert it in the retro computer. The "diskdef" used by cpmtools is roughly equivalent to the DPB used in CP/M, but that won't directly translate. The reserved boot tracks need to be written using some other utility outside of cpmtools, which varies depending on your PC OS and personal preferences.

Your DPB looks a bit odd for a large piece of storage, though. 256K per disk is not very much, even for floppies. You might consider making a larger disk if possible. Be aware, your total disk size defined by your DPB is 270336 bytes (264K) because of the added reserved tracks, and not the 256K defined for CP/M file storage. In case you are partitioning a larger media, you'll want to make certain that partitions don't overlap.
 
I have a small BASIC program that creates a disk from boot sector binaries and files that has 1K blocks. It would probably lend itself with slight modification to automating the task if the OP is interested. It's called LOKIDISK.BAS and is on Github - https://github.com/cj7hawk/LokiOS/blob/main/lokidisk.bas

I use Eprom space for my boot file system, so I create a 64K file system with a little less than 64K available ( making room for a boot sector, which is paged in to execute from $0000 on reset ). 64K is enough for the boot OS, some basic utilities, and a few tools. Also, I leave these accessible and have my OS reference these as a fallback if the called function is not local to the current logged drive.
 
OK, I got it working with a blank disk image. The A prompt comes up, I can issue a SAVE command, DIR, and then if I reset and examine the ramdisk at offset $2000 I can see a directory entry.

To summarize, I obtained CP/M 2.2 for the Xerox 1800 (which is on this page http://www.cpm.z80.de/binary.html ). From there I took CPM.SYS, chopped off the last 2KB and substituted my BIOS. The BIOS is assembled with a base address of $F200 and the CCP gets loaded at $DC00.

On my Z280 board, DRAM begins at $40000, and the EPROM code currently uses pieces of $4xxxx and $7xxxx, so I set up a 64KB user-mode at $50000, and leave the space at $80000 and beyond for a disk image. There are no actual disks connected, ramdisk is all I have! I load the disk image and boot loader to start CP/M from the PC via serial null-modem cable.

The next step will be trying disk images that contain files. I also have to find out what all character codes CP/M expects to receive for different keys and key combinations. The obvious ones like alphanumeric keys, backspace, and enter are working at least.
 

Attachments

  • cpm-2.jpg
    cpm-2.jpg
    36 KB · Views: 10
  • cpm-3.jpg
    cpm-3.jpg
    51.7 KB · Views: 10
CP/M itself doesn't use any special character codes, aside from a few control characters for command line editing (CP/M 2 is very limited). Some programs, like editors, may be configured for certain terminal types - which might expect ESC sequences or other characters. But typically that is still just 7-bit ASCII (unless the program was configured for a special machine who's keyboard generates other characters).
 
Yes, there are very few "native" keycodes to CP/M - though they are listed. Crtl-C is a big one of course. You'll find them in the manual. They are also in the CCP in the source. They are just enough to control a basic terminal - eg, Carriage Return and Line Feed, etc. I think TAB is also recognized IIRC. Ctrl-Z for End of file.

Beyond that, you'll find software is written for specific terminal emulators - so they don't use the operating system for any kind of standardisation. ADM-3A is a common limited terminal emulator that is often associated with CP/M. You'll find much software has a configuration utility to change the software - in others, it's hard-coded but they provide information to change it.

Congratulations on getting it running - It's always a good feeling to see the first prompt come up.

What are you plans? Some infocom games? Try out Wordstar and some spreadsheets? ( I booted wordstar and ended up writing a chapter of a story - got a bit carried away ) - Or set up some utilities and an assembler and begin coding in CP/M under assembly? Maybe try some early BASIC?

Did you make the board yourself or are you adapting an existing design?
 
CP/M itself doesn't use any special character codes, aside from a few control characters for command line editing (CP/M 2 is very limited). Some programs, like editors, may be configured for certain terminal types - which might expect ESC sequences or other characters. But typically that is still just 7-bit ASCII (unless the program was configured for a special machine who's keyboard generates other characters).

Yes, this is a good point - make sure that you use 7 bit ASCII and values for most of the directory structure. The 8th bit usually has another meaning where it is used.

@durgadas311 , do you know why they went to 7 bit for CP/M - Was it just for ASCII? I've noticed they use 7 bit for much of the structure - eg, pointers in records etc.
 
7-bit ASCII was the standard character set of the era, so all text in CP/M is that. There are some fields in the FCB or directory entry that can only range 0..127 so only use 7-bits. But there are also many fields that use all 8 bits. 0..127 is used for record counts (128 x 128 byte records) within a 16K logical extent, which is the course-grained allocation. It really doesn't have to do with favoring 7 bits, but rather it is just the original design of the filesystem.
 
What are you plans? Some infocom games? Try out Wordstar and some spreadsheets? ( I booted wordstar and ended up writing a chapter of a story - got a bit carried away ) - Or set up some utilities and an assembler and begin coding in CP/M under assembly? Maybe try some early BASIC?

Did you make the board yourself or are you adapting an existing design?
Board design is described in this thread https://forum.vcfed.org/index.php?threads/z280-homebrew-board-plan.1244657/

I'll have to explore what is available for CP/M since I've never used it before. No particular plans except playing around. At the moment there is still more debugging to be done. It seems that sectors are sometimes being read/written to or from the wrong place.

The way the filesystem is laid out with the block allocations right there in the directory entry is interesting. It's kind of like NTFS in that respect, and unlike FAT which would tend to necessitate another disk seek before a file can be accessed. Or contrast it with Atari DOS, which had a 'sector in use' bitmap, but only specified the first sector in the directory. Each sector of the file contained the pointer to next sector. This was efficient in terms of disk space, but deleting a file required reading the entire thing to know what sectors it was using.
 
Having a linked list for the directory in FAT as DOS does is a great way to create subdirectories.

That's the biggest drawback of the allocations in the filenames IMO - that you can't create subdirectories so easily. The second is that you often need multiple file entries for a single file.

There are ways to create subdirectories under CP/M, but the most common is to use the user number, so you're just masking the directories you don't want to see.

I create subdirectories by marking contiguous blocks as an image, or subdirectory, and then manipulate the FCB of another drive to access the subdirectory, but that's not efficient in space usage as it requires preallocated space.

The biggest advantage of CP/M's file system is that it lends itself to creating ROM BIOS as a directory, meaning that you can quickly check the availability of the BIOS, what it does etc, and it's all human readable from the command line. For example, my J: drive is the Video Bios, and rather than having an AA55 signature, if the J:VIDEO.COM file exists, my startup routines just execute it at boot time. And I can include video utilities or libraries in the same BIOS and they are all readable from CP/M. Even version numbers and READMEs.

I've been working on an alternative CP/M design written in z80 from scratch, that has some better memory management in it - so my 1Mb of main memory is a drive, and the directory is used to control memory allocations. But it also creates some interesting side effects, such as the video memory can be opened as a sequential file, and written to. It doubles as a RAMDISK in which all the system memory can be randomly distributed between system memory and file use, so nothing is lost preallocating system memory to an empty ramdisk as is commonly the case. The directory structure I showed earlier is my M: drive, so that's how my main memory is allocated in 4Mb chunks. Its kind of interesting from the perspective that I use BDOS as my memory manager, which still works even in normal CP/M.
 
The CP/M manual uses 1-indexed sector numbers when it talks about the SETSEC routine. But it looks like CP/M only calls SETSEC from one place, and before that it calls SECTRAN. The number it passes to SECTRAN is 0-indexed, so if you don't have a sector skew table you still need to add one for the benefit of SETSEC. Now that I've fixed that I can execute programs from the disk image.
That's the biggest drawback of the allocations in the filenames IMO - that you can't create subdirectories so easily. The second is that you often need multiple file entries for a single file.
That's true. When the number of files increases too much, having one monolithic directory becomes clunky to deal with. I remember running CHKDSK on my friend's 386 back in the day, and being shocked that there were over 10,000 files. Modern bloated Windows must be over 100,000 just for the OS (the newest I have is Win 7 and it is at 90,000).
 
What would be considered a practical upper bound for partition size under CP/M 2.2? I plugged in an ISA IDE card with a venerable WD 340MB HDD. Because only 8 bits of the data bus are connected, I can only access 256 bytes per sector, making the usable space 170MB. I added some preliminary code to my BIOS to read and write the IDE drive, and I setup a partition of 80MB with 1536 directory entries. It seems to be working, though very slowly. Certainly there is room to speed up my code, but then again maybe parsing 1536 directory entries is just a lost cause, I'm not sure.

STAT reports only about 16,000KB. Is it unable to display a number higher than 65,535KB?

BTW, is there a sector editor for CP/M?
 
CPM has 128 byte records ( sectors ) with an upper bound on Sectors/Track at 256 and logical tracks/disk of 256, so 128*256*256.

Or 8,388,608 bytes. (8 Mbytes). -128 bytes for the "0" allocation, since allocation 0 must always be a directory block, without exceptions.

This is also limited by the allocations, which are at most 16 bits, so you can also think of it as 65535 * 128.

I don't know why Stat is limited to 16K, perhaps it's a manifestation of the 7 bits limit some CP/M software seems to have, and I've never looked that far into it, but the file system itself should recognize 8Mb. A single file however probably can't exceed 16K due to the 7 bit record counters in the FCB and STAT would be limited by that to an extent also.... (See what I did there?)

You could easily shift CP/M to 32 bits, which would give you access to 500Gb, but that's the next limit, and it's not supported under CP/M presently that I'm aware of, though I'm sure CP/M 4 is possible, and it's not too much of a stretch for me to modify my own CP/M version to do that - but then I'm not sure if that's the best idea, as it may be better to simply shift to a different file system altogether at that point. In the end, CP/M software only cares about the FCB and even then, doesn't really pay attention to the allocation space, which is reserved for the OS, so you could theoretically extend all the records counters in random section which gives you 3 bytes of space, for around 2Gb of file space, but then you're going to have issues with things like the DPB and DPH which are limited to 16 bit file systems in CP/M 2.2
 
Back
Top