• Please review our updated Terms and Rules here

CP/M 2.2 Source Code

Today, I'm working on the CBIOS. Looking at the Operating Manual and the Skeletal CBIOS example, there is a table called TRANS, which has defined bytes in it. I figure this is a table of interleave sectors on the disk. It seems to imply an interleave of 6:1, Sector 1 is followed by Sector 7, then 13. When I copied CPM20.COM to an IMD image, I used an interleave of 1:1. Is this a problem? Should I recopy the image with a 6:1 interleave? Thanks Mike
 
Well, if you want standard DRI SSSD 8" "A1" format, you do have to logically interlace the sectors using the translation routine.

You have to realize that this comes from a time when not all systems could "low level" format media--you bought formatted media. See, for example, the DEC RX01 drive. Later, may systems simply resorted to a physical interleave which did away with the need for a translation routine.
 
I formatted the disk using Dunfields IMD program. I used 26 sectors, starting with sector 1, 128 bytes per sector, 500K FM and 1:1 interleave. I think I want the standard DRI SSSD 8" A1 format. I assume that with this format, the physical Sector 1 on the disk is followed by Sector 2,3,4,....., is that right? Thanks Mike
 
I formatted the disk using Dunfields IMD program. I used 26 sectors, starting with sector 1, 128 bytes per sector, 500K FM and 1:1 interleave. I think I want the standard DRI SSSD 8" A1 format. I assume that with this format, the physical Sector 1 on the disk is followed by Sector 2,3,4,....., is that right? Thanks Mike

It will likely work, but it will be slow.

Disk interleave is a way to compensate for the timing delays inherent in real world hardware. In a perfect world your processor would request a sector from the disk subsystem, call this logical sector n, process it, and request the next sector, call this logical sector n+1, just as the physical media rotates logical sector n+1 under the head and the data is read with no wasted motion. But what can happen in the real world, especially with vintage hardware, is that logical sector n+1 has already gone by and the processor has to wait while the disk goes around again. Worst case scenario is that the processor has to wait nearly a full disk revolution and only snags one sector per lap. In other words, you can set the interleave too high by a sector or two and not notice much decrease in drive throughput. Get it off by one sector too low and your system slows way down.
 
Mike_Z,

After reading the thread, I realise that we didn't actually answer your questions in post #1.

As you have probably realised by now - you don't need the CP/M source code to re-size the system. DRI never real released the source code to CP/M (unless you were in a very small group of companies that probably paid a lot of $ for it). Various source codes have since surfaced since the demise of DRI.

All the user had to do was to invoke MOVCPM with the appropriate parameters and save the resulting code (in memory) to disk.

As to the mnemonics you referred to ("MOV E,A", "MVI C,2" and "JMP ENTRY") they are decoded as follows:

The 8080/8085/Z80 has a number of 8-bit registers named A, B, C, D, E, H and L. These can be combined to form 16-bit registers (BC, DE, and HL).

The MOV mnemonic is short for MOVE - so the first instruction (MOV E,A) transfers the 8-bit A register to the 8-bit E register.

MVI is short for "MoVe Immediate" so "MVI C,2" loads the 8-bit C register with the 8-bit value 2.

Finally "JMP ENTRY" does what you surmise and should JuMP to a label called ENTRY somewhere else either within the program (or externally if defined to be external). You have only provided a small source code fragment, so I assume ENTRY is somewhere within the bit you haven't provided.

Note that the mnemonics for the INTEL 8080 and 8085 differ to those of the ZILOG Z80 - even though the Z80 is sort of upwardly compatible to the INTEL chips (although with subtle differences in the use of flags). The equivalent mnemonics for the Z80 would be "LD E,A", "LD C,2" and "JMP ENTRY".

Dave
 
Dave, hasn't all that been said? I believe that "ENTRY" in sample involved is either location 5 or what the jump in that location refers to the BDOS request entry point. In this case, the call is to output the character in register E to the console.

Since Mike_Z wrote his own assembler, I was under the impression that he knew the standard 8080 mnemonics.
 
Daver, thanks for the help. The problem is that I do not have a running CPM system and can not run MOVCPM.COM, yet. I have a homemade 8080 machine that can read and write to an 8" disk. I have converted a CPM20 file into an IMD image which I can get onto an 8" disk tracks 0 & 1. I'm attempting to get a CPM 20k system together on my 8080 machine. Once this works, I'll have a CP/M system that works, then I can think of resizing the code. At the moment I'm attempting to get a CBIOS to work with the CPM20 code that I can read into my 8080. Thanks, Mike
 
The last couple of days I've been working on the CBIOS. I didn't write any of the disk stuff, only the console routines and supporting stuff. I tried it this morning and I got an Error Message, 'Bdos Err On A: Select'. Is this what I should expect? I think what happened is that CPM was looking for A: and it didn't respond, is that correct? At least this proves that my CONSOLE routines are working. I suppose the next step is to write the disk routines. Mike
 
With no disk support code yet in the CBIOS, that sounds right. One of the first things that CP/M does is to read the currently logged drive, which, in this case is A:. Mostly, it has to do with constructing the check data for the (non-existent) disks, as the BDOS has to have a means of detecting a disk change.
 
Dave, hasn't all that been said? I believe that "ENTRY" in sample involved is either location 5 or what the jump in that location refers to the BDOS request entry point. In this case, the call is to output the character in register E to the console.

Since Mike_Z wrote his own assembler, I was under the impression that he knew the standard 8080 mnemonics.

Part of the question posted in #1 was "What is the next mnemonic? MOVEA, MVIC, 02, C3 and the address of ENTRY? ". ENTRY was described by yourself in post #2 but, to my knowledge after reading all of the posts again just to make sure I didn't miss any, the mnemonics hadn't.

I couldn't find any reference in the posts to Mike writing an assembler - although it was a bit late in the evening when I was reading the thread and may have missed some key bit of information.

Mike_Z - I understand your issue now in starting off with a larger CP/M software image than you have memory for and trying to make it fit into a smaller memory footprint.

Dave
 
Dave--you're only seeing half the picture in this thread. See the one Mike started on the 8272.

At least Mike is making progress. When he gets his disk routines working in the CBIOS, he's practically home free.
 
Dave, look in the Hardware section. There is long section on 8272 connections to 8" disk. Just finished writing the SELDSK routine for the CBIOS. It sets the current disk drive. The 'Select' Error Message I first got actually meant that a drive number of selected that was greater than that specified. Since SELDSK specifies the number of disks available, and it was missing, there were no drives available and this error occurred. With the SELDSK in place, now it specifies one disk, AND........ now I get the "A>" prompt. Making progress, Maybe tomorrow, I'll have some more. Thanks for the help. Mike
 
This morning I did some testing on what I have. At the 'A>', I can type letters and numbers and the CCP will respond with the same text followed by a ?, which signifies 'what?'. The control-c will reboot the system, a control u and control x will clear the command line, control r will repeat the command line. A delete will repeat the last character, this must be a very old method for delete, meant for a Teletype machine. I say that because I had a Teletype Model 35ASR at work many years ago and this is how it deleted. A tried some commands (remember I still don't have any disk BIOS routines yet). A ERA x.txt command responds with NO FILE. REN x.txt doesn't do anything. DIR prints a page of four columns of files with names 999 99. There must be a directory table somewhere with 9's in it. I tried to change drives by entering A> B:, and this responded with the Bdos Err On B: Select, then the program hangs. Something must be relying on the CBIOS routines here.

The Console routines are small and fit into the CBIOS areas. I'm going to take some time to look at the initialization stuff and the read/write routines I have and see if I should put them into my EPROM memory at 62-64k. This code is too large to fit into the space allotted. Things are looking up. Thanks Mike.
 
Well...... I've decided to rewrite my Monitor program I have between 62 & 64k. I'm planning on starting this code with all the initialization code for the interrupt controller, the uarts and timers, DMA, FDC, etc. Then ask the user a question, whether to start CP/M or go to the Monitor program. The monitor program will remain pretty much the same as it is now. It may need some reduction in size to get every thing to fit. If the user asks for CP/M, then the program will jump to the Cold Start Loader within the monitor program and then branch to CP/M.

I'm looking for some suggestions as to where to store some memory data needed by the monitor and cold start loader. The cold start loader will also serve as the CP/M BIOS for the FDC commands, read, write, etc. I'm thinking that there is 256 bytes of space in the CBIOS, which was to be used as WaitIO, for these memory storage spots. I only need 30 or 40 memory spaces for both the monitor and CSL routines. I also need a spot for the Stack. I suppose that I could use this same space for the stack. Is there a better place for this? I should not need more than 50 or 60 spots for both the memory storage and stack. One thing I'll have to remember, these addresses will change when I use MOVCPM. But that will be much later. I plan on getting the CPM20 to work first as a 20k system and I plan on using it to learn and practice CP/M use first. Thanks Mike.
 
Well, the area just the first FCB (005CH or so) isn't used by CP/M, so your RAM should be safe there for your monitor. I don't know where you're putting the 8259 IVT, however--but there should be room in that area.

Are you putting your disk and console I/O routines in ROM also, so that they can be called by the CBIOS? That saves some space in upper ROM.

CP/M treats the 7FH Delete/Rubout differently from backspace. 7FH uses the teletype method, but backspace "Delete" (08H) assumes a CRT and issue BS space BS. For most console I/O the effect is the same. Some console CBIOSes even remap DEL/Rubout to BS.
 
Chuck, I'm not sure what 8259 'IVT' is. All the 8259 initialization will be in ROM, along with the Interrupt Service Routine. The FDC is using IR1 at 000 010. The Console routines for CPM are small enough to fit into the CBIOS area so, they will go there. BUT, all the Disk routines will be in ROM. My console is a Tele Video Model 920C. I have always used delete and my monitor and assembler use the DELETE Key for a backspace space backspace. I had to look again at the keyboard to see it there was a back space key, and there is one. So I'll try that key later to see it that works.

I've been laying out the modified monitor code this morning and this should work, but will take some time to get it to work and installed. I think I have what I need, but will ask as I go. Thanks, Mike
 
It just occurred to me what IVT is, Interrupt Vector Table. Well.... until now, when I set up the FDC and DMA, I never had any use for interrupts. I polled everything. The IVT is at 000 000, but only IR1 is used, all the others are masked and disabled. Mike
 
IVT = "interrupt vector table"; the 32 bytes of interrupt jumps for the 8259.

It's not uncommon for DEL and Backspace to be treated differently, particularly on printing TTYs. I've even seen cases where DEL erases in one direcation and BS erases in the other. Worse, in the case of some terminals, the cursor backspace key generates different codes from DEL or BS.
 
This last bunch of days I've been writing my CBIOS and debugging it. I think I have all the bugs out, but I'm still having a problem. Seems I'm having trouble logging drive A in. So I'm looking at the Disk Parameter Block and I need some help understanding what some of these items are.

SECTORS = sectors per track (set at 26)
BLKSHFT = this is block shift, but what is a block? And why is it shifted? (Set at 3)
BLOCK MASK = again what is this? (set at 7)
NULL MASK = what? (set at 0)
DSKSIZE = number of blocks -1 (set at 242) How is this calc'ed
DIRSIZE = directory size (set at 63) does this mean there can only be 63 files in a directory?
ALLOC0 = ??? (set at 192)
ALLOC1 = ??? (set at 0) could be called check size?
TRACK OFFSET = First usable track (set at 2)

Thanks Mike
 
Mike, CP/M is like driving in Boston--if you lived there, you wouldn't be lost...

The basic unit of disk information in CP/M is the 128-byte sector. If your disk uses a different sector size, you must provide the appropriate blocking and deblocking routines to convert physical sectors to 128 byte sectors. In your case, a SSSD 8" drive, your physical sector size is exactly 128, so you don't need to worry about that. Sectors per track is basically a service supplied to the CBIOS that breaks disk addresses down into sectors and tracks (note that there's no specification for sides). In the case of a standard IBM 3740 format SSSD, this is indeed 26.

Block shift deals with the size of the allocation block and specifies the number of places that the number 128 needs to be shifted left to get to that allocation block size. In the case of your SSSD floppy, CP/M will allocate in blocks of 1024 bytes, so 128 shifted left 3 is 1024. Block mask is related to block shift in that it's 2^Block shift -1, or, in this case 2^3 -1 = 7.

I don't know where you got "Null mask". Perhaps you mean extent mask. That's a little more complicated to explain, but suffice it to say that you'll be using zero for your case.

Okay, so you have the block size. Since you're not using the first two tracks for files (system load area), you have 75 tracks for file storage on an 8" SSSD floppy. At 26 sectors per track and 128 bytes per sector, that gives you 75*26*128 = 249600 bytes. A block is 1024 bytes, so 249600/1024. DSKSIZE is the maximum block number (starting with 0) that can be allocated, so 243.75-1 = 242 (you can't have part of a block).

DIRSIZE and ALLOCx are again related. You can have 32 directory entries per 1,024 byte block (each directory entry is 32 bytes long). So, allocating 2 blocks (which seemed like a good compromise with regard to disk size) gives you 64 entries. But like DSKSIZE, we count from 0, so 63. ALLOC0 and ALLOC1 form a 16-bit mask that is a bitmask for blocks allocated to the directory. In this case, we've allocated two blocks to the directory, so the 16-bit mask would be 1100 0000 0000 0000, or C0 00 hex. C0 is 192 decimal. (Observe that you can allocate non-directory, non-file space by adding bits to this mask and using those blocks to store whatever you want).

Track offset is precisely that--tracks reserved for system use--in this case the boot sector, CCP and BDOS and BIOS. or 52 sectors.

The directory size means that at most you can have 64 files. In fact, depending on file size, you can have considerably less. With your definition, every 128 sectors (16KB), CP/M will add another directory entry or "extent" to show allocation for the 2nd, 3rd, 4th, etc. 16KB segment of a file.
 
Last edited:
Back
Top