• Please review our updated Terms and Rules here

Anomolies around STAT - and the meaning of certain displays.

Based on the DPB data you showed (which does not appear to match how your custom BDOS views things) the first file in your example directory data should take up only one entry and look like:
Code:
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++++++++++++++++++++
 
Regarding the STAT issue, one possibility is that your BDOS is trashing 0080H, for example using that for I/O when the user program has changed it via BDOS function 26.
 
Hi Doug - I don't think that it's trashing 0080 - I used your emulator as a a control for that, and that much appears to be working correctly.

Also a monitor dump post-execution before returning to the CCP confirms the strings are all still as expected -

0000 C3 03 FC 00 0C C3 00 F0 00 00 00 00 00 00 00 00 ├+³++├+++++++++ 0010 00 00 00 00 00 00 00 00 C3 7D D4 00 00 00 00 00 ++++++++├}È+++++ 0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ++++++++++++++++ 0030 C3 69 D1 00 00 00 00 00 C3 BC D3 00 00 00 00 00 ├iÐ+++++├╝Ë+++++ 0040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ++++++++++++++++ 0050 00 00 00 00 00 00 00 00 00 00 00 00 00 44 53 4B +++++++++++++DSK 0060 20 20 20 20 20 20 20 20 00 00 00 00 00 20 20 20 +++++ 0070 20 20 20 20 20 20 20 20 00 00 00 00 00 00 00 00 ++++++++ 0080 05 20 44 53 4B 01 20 44 53 4B 01 4D 00 2B 00 01 + DSK+ DSK+M++++ 0090 9E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ×+++++++++++++++ 00A0 44 5A 45 58 44 4F 43 20 20 43 4F 4D 00 0B 00 44 DZEXDOC COM+++D 00B0 E2 00 27 01 28 01 29 01 2A 01 00 00 00 00 00 00 Ô+'+(+)+*+++++++ 00C0 00 43 43 42 41 53 49 43 20 43 4F 4D 00 00 00 7C +CCBASIC COM+++| 00D0 1D 01 1E 01 1F 01 20 01 21 01 22 01 23 01 24 01 ++++++ +!+"+#+$+ 00E0 00 53 54 41 54 20 20 20 20 43 4F 4D 00 01 00 29 +STAT COM+++) 00F0 27 00 28 00 29 00 00 00 00 00 00 00 00 00 00 00 '+(+)+++++++++++

Also, if that wasn't working, then something like STAT A: DSK: would also fail, and that works perfectly. The error only occurs when making a recursive scan of all DPBs. Stat first calls BDOS to get the logged disks, then only gets the DPBs for those disks. I've been watching the code traces for hints to figure out what it's doing when things fail... What I think I need is some emulated hardware breakpoints I think so I can check memory as the STAT routine appears to be scanning past the end-of-string at 0080 when the error occurs, resulting in picking up characters that weren't in the original string, but as I noted, this only happens with recursive listing of drives statistics - not with specified drive statistics.

I also probably need to assemble a real DR BDOS/CCP and see what that does.
 
Based on the DPB data you showed (which does not appear to match how your custom BDOS views things) the first file in your example directory data should take up only one entry and look like:
Code:
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++++++++++++++++++++
Is it a combination of the EX and RC that is used to track record then, and that there is no extent with EX=0? ( except when the extent is not full ) - Am I understanding that correctly?

Thanks
David
 
RC tells the BDOS how many records are in the *last* extent. "80" means that the entire last extent is full. The EX field is anded with EXM (or ~EXM) to determine various things. For example, when opening a file, "(EX & ~EXM) == 0" identifies the first directory entry for a file (extent 0). There is another byte in that section that is used to extend a file beyond the limits of CP/M 2.2, essentially containing higher order bits for the extent number. Also, I believe CP/M 2.2 only has 5 bits valid in the EX field (max file size 512K = 16K * 32). As a file is read or written, the EX field in the FCB is incremented and then a matching directory entry located in order to read/write the next data. This is called "opening the next extent". Likewise, there is "closing the current extent" which mainly pertains to writing files, where the allocated blocks list (map area) needs to be written back to the directory (includes RC and EX and possibly other bytes).
 
Regarding the STAT DSK: problem, it may be the case that something is corrupting the variables (memory) in the STAT memory image. Does your BDOS switch stacks on entry? If not, it could be overflowing the STAT stack and corrupting memory.
 
Regarding the STAT DSK: problem, it may be the case that something is corrupting the variables (memory) in the STAT memory image. Does your BDOS switch stacks on entry? If not, it could be overflowing the STAT stack and corrupting memory.

That.... Is a very real possibility... Seems I should fix that first before I get back to dealing with the problem at hand.
 
Nope, it wasn't the stack. Having watched the code execute, it seems that it's related to the STAT application reading beyond the character buffer at 0080 - So it's reading positions that don't exist... I'm still not sure why.
 
I suspect that he's setting EXM to 0.

Hi Chuck, I was setting EXM correctly in the DPB, and using it in calculations, but failed to understand what it represented in CP/M 2.2 - From what I could tell, up until CP/M 2.0 there were only logical extents and both logical and physical were the same. ( CP/M 2.0 interface manual only talks about logical extents ) - In CP/M 2.2, they talk about Logical and Physical extents... I had assumed Logical and Physical were still the same in 2.2 and was not aware of 3.0 so didn't check further - and had no idea that a single directory entry could contain up to 32 logical extents.
Thanks for that - I will remake my file routines to use the full data table.

The irony is that only using 4 bytes really annoyed me - but I did it for assumed "compatability" - I even considered doing it the way it was supposed to be, but I was completely wrong about what the correct way was. :( It's a pain to change it, but at least I found it early - thanks to both you and Doug.

Very much appreciated -
 
Nope, it wasn't the stack. Having watched the code execute, it seems that it's related to the STAT application reading beyond the character buffer at 0080 - So it's reading positions that don't exist... I'm still not sure why.
That's what I'm having trouble reasoning-out. The only reasons I can think of that STAT would be reading beyond the end of the commandline are: The commandline was malformed by the CCP; the commandline buffer was corrupted later; STAT variables were corrupted to cause reading of invalid data.

If you're able to watch the code execute, where (at what address) is STAT reading the command byte that causes the "Bad Delimiter" and what byte value did it read?
 
That's what I'm having trouble reasoning-out. The only reasons I can think of that STAT would be reading beyond the end of the commandline are: The commandline was malformed by the CCP; the commandline buffer was corrupted later; STAT variables were corrupted to cause reading of invalid data.

If you're able to watch the code execute, where (at what address) is STAT reading the command byte that causes the "Bad Delimiter" and what byte value did it read?
Hi Doug,

That's a 52 Mb text file, so it's slow going through it. What I noticed was that there's a routine that reads from 0080 and it slowly increments as it executes. When I do a single drive, it completes near the top of the process, and doesn't show again, but when it does a recursive lookup of disks, it reads from the bottom as well, and the very last thing it does is show me the final drive, then some basic checks, then it throws the error.

I need to spend a little more time with it to figure out what it's doing and why though. And for the moment it works otherwise...

I'm going to fix my extent packing routines first and load multiple logical extents into a single physical... They probably aren't involved in the STAT error from what I can see though, but it's always possible.

The idea that a variable was being corrupted made sense to me too, but I haven't worked out how STAT's parsing routine works yet, and I'm not sure how it gets from PL/M to Machine Code either.... :(

Seems I have a mystery to solve :)
 
Regarding the STAT DSK: issue, one more thing to check: the DRI CCP not only places the length of the command line in 0080H, but it also places a NUL terminator at the end (length byte does not include NUL). Is it possible you're not putting a NUL at the end of the command line string in 0080H?

Code:
0080: N C1 C2 ... CN \0

STAT parses "A: DSK:" differently than "DSK:", and so does not keep scanning if a drive was specified - therefor does not care about any NUL terminator.
 
Last edited:
The command-line buffer 0080h is 80h =- number of characters in the command tail, followed by the command tail, followed by a carriage return (0Dh). Note that the first character in the buffer is a space and the return at the end isn't counted in the count at 80h. e.g.
Code:
0080  05 20 61 62 63 64 0D 00
Some utilities use the byte count; others scan for the return.
 
The command-line buffer 0080h is 80h =- number of characters in the command tail, followed by the command tail, followed by a carriage return (0Dh). Note that the first character in the buffer is a space and the return at the end isn't counted in the count at 80h. e.g.
Code:
0080  05 20 61 62 63 64 0D 00
Some utilities use the byte count; others scan for the return.
The CCP does not place a CR in the command buffer. only a NUL terminator.
 
Here's an example of how the default FCBs and command buffers are setup in the two cases:

Code:
A>cmdline dsk:

0000 C3 03 EB A9 00 C3 06 DD C3 F6 F3 76 5E 22 D0 64
0010 FB C9 70 00 1A C3 67 01 C3 7D F5 C3 F2 09 97 0F
0020 C3 38 F2 0F 06 1C 3E F1 FB C9 20 C3 09 02 3F 00
0030 FB C9 20 00 00 00 00 00 FB C9 20 C3 21 03 C3 26
0040 00 11 22 01 C3 FC 09 C3 60 78 C3 25 0A F1 00 EB
0050 D1 E1 DD E1 FD E1 D9 08 C1 78 ED 47 00 44 53 4B
0060 20 20 20 20 20 20 20 20 00 00 00 02 00 20 20 20
0070 20 20 20 20 20 20 20 20 00 00 00 00 00 FD E5 DD
0080 05 20 44 53 4B 3A 00 E5 E5 E5 E5 E5 E5 E5 E5 E5
0090 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5
00A0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5
00B0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5
00C0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5
00D0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5
00E0 21 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5
00F0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5

A>cmdline a: dsk:

0000 C3 03 EB A9 00 C3 06 DD C3 F6 F3 FD BE 22 D0 64
0010 FB C9 70 00 1A C3 67 01 C3 7D F5 C3 F2 09 97 0F
0020 C3 38 F2 0E 05 1C 3E F1 FB C9 20 C3 09 02 3F 00
0030 FB C9 20 00 00 00 00 00 FB C9 20 C3 21 03 C3 26
0040 00 11 22 01 C3 FC 09 C3 60 78 C3 25 0A F1 00 EB
0050 D1 E1 DD E1 FD E1 D9 08 C1 78 ED 47 01 20 20 20
0060 20 20 20 20 20 20 20 20 00 00 00 02 00 44 53 4B
0070 20 20 20 20 20 20 20 20 00 00 00 00 00 FD E5 DD
0080 08 20 41 3A 20 44 53 4B 3A 00 E5 E5 E5 E5 E5 E5
0090 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5
00A0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5
00B0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5
00C0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5
00D0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5
00E0 21 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5
00F0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5

A>
 
Could be that my programs stuck a CR at the end for uniformity (with DOS) sake. I can't recall--this was about 40 years ago. In any case, that final character isn't counted in the tail count at 80h.
 
Could be that my programs stuck a CR at the end for uniformity (with DOS) sake. I can't recall--this was about 40 years ago. In any case, that final character isn't counted in the tail count at 80h.
If there's a CR in the buffer, that will trigger the "Bad Delimiter" error in STAT.
 
Back
Top