home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
DRI-archive
/
roche
/
HEADER.TXT
< prev
next >
Wrap
Internet Message Format
|
2009-12-11
|
15KB
From: "French Luser" <Bill.Ga...@microsoft.com>
Newsgroups: comp.os.cpm
Subject: Header Record of CP/M-86 (Plus)
Date: Fri, 26 Nov 2004 12:52:37 +0100
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2800.1158
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165
Lines: 455
Message-ID: <41a71871$0$25111$8fcfb975@news.wanadoo.fr>
Organization: les newsgroups par Wanadoo
NNTP-Posting-Host: APoitiers-106-2-3-49.w81-248.abo.wanadoo.fr
X-Trace: 1101469810 news.wanadoo.fr 25111 81.248.43.49:21824
X-Complaints-To: abuse@wanadoo.fr
HEADER.TXT by Emmanuel ROCHE
----------
Everything you wanted to know about the Header Record, but were
too afraid to ask...
The more I work with CP/M-86 (Plus) ComManD files, the more
often I need to know what is inside its Header Record.
For the record, a CMD file generally has 2 or 3 parts, which can
be described thus:
+---------------+
| Header Record |
+---------------+
| Segments Used |
+---------------+
| Footer Record | (If RSX(s) present)
+---------------+
The Header Record contains a description of the Segments used by
the program, that the loader of the CP/M-86 (Plus) Operating
System will use to allocate memory and load the program in the
TPA. As its name implies, it is 128 bytes long, or one record.
It contains Group Descriptors at the beginning. A first byte of
zero in a Group Descriptor indicates that no more Group
Descriptors follows. The rest of the record is filled with null
bytes (00h), except the 5 last bytes, which will be explained
later.
The Segments Used part of the CMD file are those segments, up to
8.
The Footer Record is a record containing the names or the
addresses/names of the RSXs linked/attached (up to 8) to this
CMD file. This record does not exist if the CMD file has no RSX.
Enough theory, let us see some Header Records.
A>mbasic header
BASIC-86 Rev. 5.22
[CP/M-86 Plus]
Copyright 1977-1982 (C) by Microsoft
Created: 5-Mar-82
62390 Bytes free
HEADER> Enter CMD File Name: ? CMD1
G-Form G-Length A-Base G-Min G-Max
+-------+--------+--------+--------+--------+
(Code) | 01h | 0018 | 0000 | 0018 | 0000 |
+-------+--------+--------+--------+--------+
Offset of Footer Record: 0000
Offset of Fixups Record: 0000
Program Flag: 00
(8080 Memory Model)
Ok
run
HEADER> Enter CMD File Name: ? CMD2
G-Form G-Length A-Base G-Min G-Max
+-------+--------+--------+--------+--------+
(Code) | 01h | 0008 | 0000 | 0008 | 0000 |
+-------+--------+--------+--------+--------+
(Data) | 02h | 0018 | 0000 | 0018 | 0000 |
+-------+--------+--------+--------+--------+
Offset of Footer Record: 0000
Offset of Fixups Record: 0000
Program Flag: 00
(Small Memory Model)
Ok
run
HEADER> Enter CMD File Name: ? CMD3
G-Form G-Length A-Base G-Min G-Max
+-------+--------+--------+--------+--------+
(Code) | 01h | 0008 | 0000 | 0008 | 0000 |
+-------+--------+--------+--------+--------+
(Data) | 02h | 0018 | 0000 | 0018 | 0000 |
+-------+--------+--------+--------+--------+
(Extra) | 03h | 0008 | 0000 | 0008 | 0000 |
+-------+--------+--------+--------+--------+
Offset of Footer Record: 0000
Offset of Fixups Record: 0000
Program Flag: 00
(Compact Memory Model)
Ok
run
HEADER> Enter CMD File Name: ? CMD4
G-Form G-Length A-Base G-Min G-Max
+-------+--------+--------+--------+--------+
(Code) | 01h | 0008 | 0000 | 0008 | 0000 |
+-------+--------+--------+--------+--------+
(Data) | 02h | 0018 | 0000 | 0018 | 0000 |
+-------+--------+--------+--------+--------+
(Extra) | 03h | 0008 | 0000 | 0008 | 0000 |
+-------+--------+--------+--------+--------+
(Stack) | 04h | 0008 | 0000 | 0008 | 0000 |
+-------+--------+--------+--------+--------+
Offset of Footer Record: 0000
Offset of Fixups Record: 0000
Program Flag: 00
(Compact Memory Model)
Ok
run
HEADER> Enter CMD File Name: ? CMDX1
G-Form G-Length A-Base G-Min G-Max
+-------+--------+--------+--------+--------+
(Code) | 01h | 0008 | 0000 | 0008 | 0000 |
+-------+--------+--------+--------+--------+
(Data) | 02h | 0018 | 0000 | 0018 | 0000 |
+-------+--------+--------+--------+--------+
(Extra) | 03h | 0008 | 0000 | 0008 | 0000 |
+-------+--------+--------+--------+--------+
(Stack) | 04h | 0008 | 0000 | 0008 | 0000 |
+-------+--------+--------+--------+--------+
(Aux.1) | 05h | 0000 | 0000 | 0040 | 0000 |
+-------+--------+--------+--------+--------+
Offset of Footer Record: 0000
Offset of Fixups Record: 0000
Program Flag: 00
(Compact Memory Model)
Ok
run
HEADER> Enter CMD File Name: ? CMDX2
G-Form G-Length A-Base G-Min G-Max
+-------+--------+--------+--------+--------+
(Code) | 01h | 0008 | 0000 | 0008 | 0000 |
+-------+--------+--------+--------+--------+
(Data) | 02h | 0018 | 0000 | 0018 | 0000 |
+-------+--------+--------+--------+--------+
(Extra) | 03h | 0008 | 0000 | 0008 | 0000 |
+-------+--------+--------+--------+--------+
(Stack) | 04h | 0008 | 0000 | 0008 | 0000 |
+-------+--------+--------+--------+--------+
(Aux.1) | 05h | 0000 | 0000 | 0040 | 0000 |
+-------+--------+--------+--------+--------+
(Aux.2) | 06h | 0000 | 0000 | 0040 | 0000 |
+-------+--------+--------+--------+--------+
Offset of Footer Record: 0000
Offset of Fixups Record: 0000
Program Flag: 00
(Compact Memory Model)
Ok
run
HEADER> Enter CMD File Name: ? CMDX3
G-Form G-Length A-Base G-Min G-Max
+-------+--------+--------+--------+--------+
(Code) | 01h | 0008 | 0000 | 0008 | 0000 |
+-------+--------+--------+--------+--------+
(Data) | 02h | 0018 | 0000 | 0018 | 0000 |
+-------+--------+--------+--------+--------+
(Extra) | 03h | 0008 | 0000 | 0008 | 0000 |
+-------+--------+--------+--------+--------+
(Stack) | 04h | 0008 | 0000 | 0008 | 0000 |
+-------+--------+--------+--------+--------+
(Aux.1) | 05h | 0000 | 0000 | 0040 | 0000 |
+-------+--------+--------+--------+--------+
(Aux.2) | 06h | 0000 | 0000 | 0040 | 0000 |
+-------+--------+--------+--------+--------+
(Aux.3) | 07h | 0000 | 0000 | 0040 | 0000 |
+-------+--------+--------+--------+--------+
Offset of Footer Record: 0000
Offset of Fixups Record: 0000
Program Flag: 00
(Compact Memory Model)
Ok
run
HEADER> Enter CMD File Name: ? CMDX4
G-Form G-Length A-Base G-Min G-Max
+-------+--------+--------+--------+--------+
(Code) | 01h | 0008 | 0000 | 0008 | 0000 |
+-------+--------+--------+--------+--------+
(Data) | 02h | 0018 | 0000 | 0018 | 0000 |
+-------+--------+--------+--------+--------+
(Extra) | 03h | 0008 | 0000 | 0008 | 0000 |
+-------+--------+--------+--------+--------+
(Stack) | 04h | 0008 | 0000 | 0008 | 0000 |
+-------+--------+--------+--------+--------+
(Aux.1) | 05h | 0000 | 0000 | 0040 | 0000 |
+-------+--------+--------+--------+--------+
(Aux.2) | 06h | 0000 | 0000 | 0040 | 0000 |
+-------+--------+--------+--------+--------+
(Aux.3) | 07h | 0000 | 0000 | 0040 | 0000 |
+-------+--------+--------+--------+--------+
(Aux.4) | 08h | 0000 | 0000 | 0040 | 0000 |
+-------+--------+--------+--------+--------+
Offset of Footer Record: 0000
Offset of Fixups Record: 0000
Program Flag: 00
(Compact Memory Model)
Ok
run
HEADER> Enter CMD File Name: ? CALLVERS
G-Form G-Length A-Base G-Min G-Max
+-------+--------+--------+--------+--------+
(Code) | 01h | 0002 | 0000 | 0002 | 0000 |
+-------+--------+--------+--------+--------+
(Data) | 02h | 0012 | 0000 | 0012 | 0000 |
+-------+--------+--------+--------+--------+
Offset of Footer Record: 0400
Offset of Fixups Record: 0000
Program Flag: 00
(Small Memory Model)
Ok
run
HEADER> Enter CMD File Name: ? ECHOVERS
G-Form G-Length A-Base G-Min G-Max
+-------+--------+--------+--------+--------+
(Code) | 01h | 0006 | 0000 | 0006 | 0000 |
+-------+--------+--------+--------+--------+
(Data) | 02h | 0012 | 0000 | 0012 | 0000 |
+-------+--------+--------+--------+--------+
Offset of Footer Record: 0000
Offset of Fixups Record: 0000
Program Flag: 10
(Small Memory Model)
Ok
run
HEADER> Enter CMD File Name: ? TESTGIOS
G-Form G-Length A-Base G-Min G-Max
+-------+--------+--------+--------+--------+
(Code) | 01h | 0298 | 0000 | 0298 | 0000 |
+-------+--------+--------+--------+--------+
(Data) | 02h | 0058 | 0000 | 0058 | 0000 |
+-------+--------+--------+--------+--------+
(Extra) | 03h | 0006 | 0000 | 0006 | 0000 |
+-------+--------+--------+--------+--------+
(Stack) | 04h | 0094 | 0000 | 0094 | 0000 |
+-------+--------+--------+--------+--------+
Offset of Footer Record: 0000
Offset of Fixups Record: 7300
Program Flag: 80
(Large Memory Model)
Ok
From the above, some things become clear: when there is only one
Code segment, it is a "8080 Memory model CMD file".
When there are 2 segments (but only if they are Code and Data),
then it is a "Small Memory model CMD file".
When there are more than 2 segments, it is a "Compact Memory
model CMD file".
Historically, those were the 3 kinds of Memory Models described
in the CP/M-86 Version 1.x technical documentation by Digital
Research.
Under CP/M-86 Plus, RSXes exist. ECHOVERS is an example of such
an RSX. As you can see, its Program Flag contains 10h.
CALLVERS, the CMD file calling it, has its "Offset to Footer
Record" field containing the value 0400h.
But, what is this "Large Memory model CMD file", TESTGIOS, we
have seen last?
With Concurrent CP/M Version 1.0, Digital Research introduced in
the Summer of 1983 a new kind of CMD file, where each segment
can be up to 1 Megabyte in length... (Previously, they could
only be 64k long, at the maximum.)
But, to be compatible with all the CMD files produced until
then, they had to choose a way to let the CMD file loader of the
operating system knows that this CMD file was of the new kind.
Since they could not modify the format of the Group Descriptors,
they chose to use a byte inside the Header Record.
Over the years, this byte came to be used as flags for 4 things:
Bit: 7 6 5 4 3 2 1 0
+-----------------+
| 1 1 1 1 1 1 1 1 |
+-----------------+
| | | | | | | |
| | | | | | | +--> Bit 0: Not used
| | | | | | +----> Bit 1: Not Used
| | | | | +------> Bit 2: Not used
| | | | +--------> Bit 3: Not used
| | | +----------> Bit 4: RSX Footer Record Flag
| | +------------> Bit 5: 8087 Present Flag
| +--------------> Bit 6: 8087 Support Flag
+----------------> Bit 7: Large Memory Model Flag
Program Flag format
The last 2 CMD files that we examined (ECHOVERS and TESTGIOS)
displayed 10h and 80h; that is to say: Bits 4 and 7 set. But
what is the purpose of Bits 5 and 6?
Searching for clues in later Digital Research guides, I finally
found the following paragraph in the "Concurrent CP/M Release
3.1 Programmer's Reference Guide":
3.1.2 8087 support
------------------
Concurrent CP/M provides optional 8087 support for systems that
use the 8087 processor. This support is indicated by the
Program Flag, byte 127 (7Fh), of the CMD file Header Record.
Setting bit 6 (bit 0 is least significant bit) of the Program
Flag indicates optional 8087 support, which means that, if the
8087 is present, the program uses it; otherwise, the program
will emulate it. If bit 5 of the Program Flag is set, it
indicates that the 8087 must be present in order for the program
to run. If no 8087 is present and bit 5 of the Program Flag is
set, the system returns an error when it tries to load the
program. The CHSET utility can be used to set the program's
header record for optional or required 8087 support.
-----------------
So, you now know what would mean a Program Flag with a value of
20h or 40h.
Now that we have explained everything known about the Header
Record, here is the BASIC program used to learn all this:
list
10 REM HEADER.BAS by Emmanuel ROCHE
20 :
30 PRINT
40 INPUT "HEADER> Enter CMD File Name: " ; file1$
50 PRINT
60 file1$ = file1$ + ".CMD"
70 :
80 group$ (1) = "(Code) "
90 group$ (2) = "(Data) "
100 group$ (3) = "(Extra)"
110 group$ (4) = "(Stack)"
120 group$ (5) = "(Aux.1)"
130 group$ (6) = "(Aux.2)"
140 group$ (7) = "(Aux.3)"
150 group$ (8) = "(Aux.4)"
160 :
170 ruler$ = "+-------+--------+--------+--------+--------+"
180 :
190 PRINT TAB(9) " G-Form G-Length A-Base G-Min G-Max"
200 PRINT TAB(9) ruler$
210 :
220 OPEN "R", #1, file1$, 9
230 FIELD #1, 1 AS gform1$, 2 AS glength1$, 2 AS abase1$,
2 AS gmin1$, 2 AS gmax1$
240 GET #1
250 :
260 gform1 = ASC (gform1$)
270 IF gform1 = 0 THEN GOTO 420
280 NrSeg1 = NrSeg1 + 1
290 PRINT group$ (gform1) TAB(9) "| " ;
300 PRINT RIGHT$ ("0" + HEX$ (gform1), 2) "h | " ;
310 glength1 = CVI (glength1$)
320 PRINT RIGHT$ ("000" + HEX$ (glength1), 4) " | " ;
330 abase1 = CVI (abase1$)
340 PRINT RIGHT$ ("000" + HEX$ (abase1), 4) " | " ;
350 gmin1 = CVI (gmin1$)
360 PRINT RIGHT$ ("000" + HEX$ (gmin1), 4) " | " ;
370 gmax1 = CVI (gmax1$)
380 PRINT RIGHT$ ("000" + HEX$ (gmax1), 4) " |"
390 PRINT TAB(9) ruler$
400 GOTO 240
410 :
420 CLOSE #1
430 OPEN "R", #1, file1$, 1
440 FIELD #1, 1 AS byte1$
450 GET #1, &H7B
460 :
470 PRINT
480 GET #1 : lofo = ASC (byte1$)
490 GET #1 : hifo = ASC (byte1$)
500 fo = hifo + 256 * lofo
510 PRINT "Offset of Footer Record: " ;
520 PRINT RIGHT$ ("000" + HEX$ (fo), 4)
530 GET #1 : lofi = ASC (byte1$)
540 GET #1 : hifi = ASC (byte1$)
550 fi = hifi + 256 * lofi
560 PRINT "Offset of Fixups Record: " ;
570 PRINT RIGHT$ ("000" + HEX$ (fi), 4)
580 GET #1 : fl = ASC (byte1$)
590 PRINT "Program Flag: " ;
600 PRINT RIGHT$ ("0" + HEX$ (fl), 2)
610 :
620 PRINT
630 PRINT "(" ;
640 IF fl > &H7F THEN PRINT "Large" ; : GOTO 680
650 IF NrSeg1 = 1 THEN PRINT "8080" ; : GOTO 680
660 IF NrSeg1 = 2 THEN PRINT "Small" ; : GOTO 680
670 IF NrSeg1 > 2 THEN PRINT "Compact" ;
680 PRINT " Memory Model)"
690 :
700 PRINT
710 CLOSE
720 END
system
A>That's all, folks!
Yours Sincerely,
"French Luser"
EOF