Post by ***@gmail.comWhat I want to know is how MSDOS managed to
we can see a PSP from MSDOS for a .com file
it should have the answer. If we can disassemble
that, anyway.
I wrote this program:
C:\devel\develop>type dumppsp.c
/*********************************************************************/
/* */
/* This Program Written by Paul Edwards. */
/* Released to the Public Domain */
/* */
/*********************************************************************/
/*********************************************************************/
/* */
/* dumppsp - dump a PSP to psp.dat */
/* probably works best for a .com file */
/* */
/*********************************************************************/
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *fq;
fq = fopen("psp.dat", "wb");
if (fq == NULL)
{
printf("failed to open psp.dat\n");
return (EXIT_FAILURE);
}
fwrite(NULL, 1, 256, fq);
fclose(fq);
return (0);
}
And compiled it like this:
C:\devel\develop>wcl -mt dumppsp.c
Open Watcom C/C++16 Compile and Link Utility Version 1.6
Portions Copyright (c) 1988-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.
See http://www.openwatcom.org/ for details.
wcc dumppsp.c -ms
Open Watcom C16 Optimizing Compiler Version 1.6
Portions Copyright (c) 1984-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.
See http://www.openwatcom.org/ for details.
dumppsp.c: 30 lines, included 1349, 0 warnings, 0 errors
Code size: 65
wlink @__wcl__.lnk
Open Watcom Linker Version 1.6
Portions Copyright (c) 1985-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.
See http://www.openwatcom.org/ for details.
loading object files
searching libraries
creating a DOS .COM executable
And you can see it created a .com file automatically.
Running under MSDOS 5.0 gives this PSP:
C:\devel\bochs>hexdump psp.dat
000000 CD20C09F 009AF0FE 1DF0DC01 F70E4B01 . ............K.
000010 F70E5601 F70EF70E 01010100 0203FFFF ..V.............
000020 FFFFFFFF FFFFFFFF FFFFFFFF 0E10A837 ...............7
000030 24101400 18002410 FFFFFFFF 00000000 $.....$.........
000040 05000000 00000000 00000000 00000000 ................
000050 CD21CB00 00000000 00000000 00414243 .!...........ABC
000060 20202020 20202020 00000000 00444546 .....DEF
000070 20202020 20202020 00000000 00000000 ........
000080 0C204162 63204465 66204768 690D726F . Abc Def Ghi.ro
000090 6D0D0000 00000000 00000000 00000000 m...............
0000A0 00000000 00000000 00000000 00000000 ................
0000B0 00000000 00000000 00000000 00000000 ................
0000C0 00000000 00000000 00000000 00000000 ................
0000D0 00000000 00000000 00000000 00000000 ................
0000E0 00000000 00000000 00000000 00000000 ................
0000F0 00000000 00000000 00000000 00000000 ................
The "rom" you see mentioned there is leftover junk from
this in my autoexec.bat:
rem mscdex /d:cdrom
Here are all the PSP offsets from INTERRUP.F:
Format of Program Segment Prefix (PSP):
Offset Size Description (Table 01378)
00h 2 BYTEs INT 20 instruction for CP/M CALL 0 program termination
the CDh 20h here is often used as a signature for a valid PSP
02h WORD segment of first byte beyond memory allocated to program
04h BYTE (DOS) unused filler
(OS/2) count of fake DOS version returns
05h BYTE CP/M CALL 5 service request (FAR CALL to absolute 000C0h)
BUG: (DOS 2+ DEBUG) PSPs created by DEBUG point at 000BEh
06h WORD CP/M compatibility--size of first segment for .COM files
08h 2 BYTEs remainder of FAR JMP at 05h
0Ah DWORD stored INT 22 termination address
0Eh DWORD stored INT 23 control-Break handler address
12h DWORD DOS 1.1+ stored INT 24 critical error handler address
16h WORD segment of parent PSP
18h 20 BYTEs DOS 2+ Job File Table, one byte per file handle, FFh = closed
2Ch WORD DOS 2+ segment of environment for process (see #01379)
2Eh DWORD DOS 2+ process's SS:SP on entry to last INT 21 call
32h WORD DOS 3+ number of entries in JFT (default 20)
34h DWORD DOS 3+ pointer to JFT (default PSP:0018h)
38h DWORD DOS 3+ pointer to previous PSP (default FFFFFFFFh in 3.x)
used by SHARE in DOS 3.3
3Ch BYTE DOS 4+ (DBCS) interim console flag (see AX=6301h)
Novell DOS 7 DBCS interim flag as set with AX=6301h
(possibly also used by Far East MS-DOS 3.2-3.3)
3Dh BYTE (APPEND) TrueName flag (see INT 2F/AX=B711h)
3Eh BYTE (Novell NetWare) flag: next byte initialized if CEh
(OS/2) capabilities flag
3Fh BYTE (Novell NetWare) Novell task number if previous byte is CEh
40h 2 BYTEs DOS 5+ version to return on INT 21/AH=30h
42h WORD (MSWindows3) selector of next PSP (PDB) in linked list
Windows keeps a linked list of Windows programs only
44h WORD (MSWindows3) "PDB_Partition"
46h WORD (MSWindows3) "PDB_NextPDB"
48h BYTE (MSWindows3) bit 0 set if non-Windows application (WINOLDAP)
49h BYTE unused by DOS versions <= 6.00
4Ch WORD (MSWindows3) "PDB_EntryStack"
4Eh 2 BYTEs unused by DOS versions <= 6.00
50h 3 BYTEs DOS 2+ service request (INT 21/RETF instructions)
53h 2 BYTEs unused in DOS versions <= 6.00
55h 7 BYTEs unused in DOS versions <= 6.00; can be used to make first FCB
into an extended FCB
5Ch 16 BYTEs first default FCB, filled in from first commandline argument
overwrites second FCB if opened
6Ch 16 BYTEs second default FCB, filled in from second commandline argument
overwrites beginning of commandline if opened
7Ch 4 BYTEs unused
80h 128 BYTEs commandline / default DTA
command tail is BYTE for length of tail, N BYTEs for the tail,
followed by a BYTE containing 0Dh
It is interesting to see the first 2 of my command line
arguments being converted into FCBs.
Next, an attempt to disassemble!
BFN. Paul.