Looking at the code for PDPCLIB and PDOS,...
it seems that when a program does a:
system("fred abc");
that the maximum length of "abc" is governed
by what can fit in the PSP, starting at 0x80,
which means from 128 bytes you need to
subtract 1 byte for the length indicator itself,
and 1 byte for a compulsory '\r', so there are
126 bytes for the caller, and that is what is put
in the first byte.
I'd like to support more than that. Actually the
limit of a single byte is enough for me at the
moment, ie 254, but maybe it should be extended
even further, ie if someone puts 255 in that spot,
it means that the real length is in cmd[1] and
cmd[2]. And if both of those are x'FF' then the
real length is in cmd[3..6].
Any suggestions on the best way forward?
I see there is already an extension for PDOS/386,
and it is isolated in the AH=F6H for PDOS/x86
extensions. Maybe that's where it should stay.
Any suggestions on the best way forward?
Is there any prior art for this? Maybe I can just
copy an existing solution. Unless it has some
disadvantage.
MS-DOS 7.x already specify a standard for this via CMDLINE environment variable. It's also supported by the already popular 4DOS software. So, it should be supported by all new DOS compatible OS projects.
Ok, thanks. I found that referenced here:
https://en.wikipedia.org/wiki/Environment_variable
But I haven't yet found the rules for setting the PSP.
BFN. Paul.
But I haven't yet found the rules for setting the PSP.
Ralf Browns's PSP table described it in details.
But who is responsible for setting this?
I'm guessing system() needs to allocate a new area
of memory for environment variables, copy the old
environments, add/replace CMDLINE, and put the
segment into the parameter block.
But who is responsible for setting this?
It's COMMAND.COM, actually - and unfortunately.
Don't know why it's not implemented within the DOS interrupt service itself. Probably because it's problematic enough, or it was a rushed solution.
Could you please explain what you think would
have been a better design?
But implement the code which prepare the CMDLINE variable in the DOS interrupt service itself (i.e. in Int-214B), rather than the command interpreter, so that it's OS native. Otherwise, if the user decide to use other command interpreter which doesn't support the CMDLINE environment variable. Long command line won't be available for programs which already support the CMDLINE variable.
If the change was made in the MSDOS interrupt itself,
the calling program's system() would STILL need to
do something special, to invoke the new functionality
of Int-214B, and the called program would STILL need
to do something special to receive it, AND you need
to be on a particular version of MSDOS that knows
about this new facility.
How would this be better? Or am I missing something?
On Fri, 30 Apr 2021 05:34:54 -0700 (PDT), muta...@gmail.com wrote:
If the change was made in the MSDOS interrupt itself,
the calling program's system() would STILL need to
do something special, to invoke the new functionality
of Int-214B, and the called program would STILL need
to do something special to receive it, AND you need
to be on a particular version of MSDOS that knows
about this new facility.
How would this be better? Or am I missing something?
Aw, crap. I overlooked the fact that Int-214B separates between the program name and (the limited) command tail.
I'm beginning to believe that Microsoft's implementation is actually a
rushed solution. They should really have added an additional field in the Parameter Block for the full command line or extended command tail. Albeit requires that other programs handle program execution differently.
Once again, an additional field in the parameter
block would require all 3 components (caller, OS
and called)
I'm thinking 32-bit should drop the fcb1/2, as they seem
to be outdated, and specify that the cmdtail doesn't have
a length in the first byte, and just relies on NUL-termination.
And no '\r' either.
Add a "give me a pointer to the extended command-tail string"
Once again, an additional field in the parameter
block would require all 3 components (caller, OS
and called)
Why do you think so ?
AFAIKS the *pointer* field doesn't care how long the
pointed-to string is ...
Add a "give me a pointer to the extended command-tail string (INT)" for the called
program (the PSP can only hold 126 chars so it needs to be stored somewhere else) and it should be enough - if it fails than there is no support. It
can be used by the caller, to determine if it should apply the CMDLINE environment variable hack, as well as by the callee, for the same reason.
I'm thinking 32-bit should drop the fcb1/2, as they seem
to be outdated, and specify that the cmdtail doesn't have
a length in the first byte, and just relies on NUL-termination.
And no '\r' either.
As long as you're busy upgrading stuff, do consider changing 2109 to a zero-terminated string too.
Hi Rudy. Are you going to answer my question about
the technical barrier to ctrl-c checking for programs
that loop without doing output? I'd really like to know
that.
Once again, an additional field in the parameter
block would require all 3 components (caller, OS
and called)
Why do you think so ?
For the same reason I gave before?
So both caller and called require two techniques
instead of one, and the OS indeed can have 0 or 1.
As long as you're busy upgrading stuff, do consider changing 2109 to a
zero-terminated string too.
Currently I can go:
PosDisplayString("Hello$");
and it will work on both 16-bit and 32-bit MSDOS.
More code to achieve what?
Did I already mention that I regard the CMDLINE method to be an hack (and an ugly one to boot) ? And have you ever thought about how clumsy changing
the environment and retrieving from it is for a to-be-executed program is in a plain DOS version ?
PosDisplayString("Hello$");
and it will work on both 16-bit and 32-bit MSDOS.
Yeah, it does. You know what /won't/ work ? Displaying the current, or
your proposed extended command-tail that way.
But lets put it differently : you're introducing a /third/ string form. Why
?
And of you think that a zero-terminated string works better than why not update that ancient '$' ended string too ? Better yet, change all three to the same, zero-terminated form.
Than again, if you would do that you would lose compatibility with all of
the other DOSes ... so maybe don't.
More code to achieve what?
Nope, less code. One set of functions that will handle the single string form, instead of having three different ones. Also, no permutations needed
to combine/append one string form with/to another.
I think we need to distinguish between:...
1. How MSDOS would ideally have been written starting with version 1.0.
3. What alternative could have been chosen knowing the
"mistakes" of 1.0 and before the 7.0 solution has been
set in stone.
2. How to maintain compatibility with the CMDLINE
solution introduced in MSDOS 7.0.
Sure. This is not the function for that. There isn't any
choice but to use an alternative. Is that a problem?
Because the '\r' is useless either way and needs
to be removed.
There's no need for the CMDLINE kludge either in
the 32-bit version.
If we (as I do) theorize that Microsoft had created
a nice C API like the Pos* functions, instead of only
providing an assembler interface, what would that
API actually look like?
I guess we need to ask what a sensible objective is in
the first place. I just have a vague idea of "32-bit MSDOS".
I am not providing an API to print a NUL-terminated
string.
I'm just setting rules for INT 21H 4BH.
Once again, an additional field in the parameter block
would require all 3 components (caller, OS and called)
to be aware of the additional field.
How is that better than CMDLINE?
Regardless, for PDOS/386 there is an opportunity for a
fresh start. The "environment" field, a 2-byte segment,
cannot be used by hook or crook, and needs to be a
4-byte pointer instead. And everything necessarily needs
to be recompiled for 80386 anyway, so there is no harm
in doing it differently.
But the objective is still to make it easy for programmers[snip]
to target both 16-bit MSDOS and a theoretical 32-bit
MSDOS.
I'm thinking 32-bit should drop the fcb1/2, as they seem to
be outdated, and specify that the cmdtail doesn't have a
length in the first byte, and just relies on NUL-termination.
And no '\r' either.
I think we need to distinguish between:
1. How MSDOS would ideally have been written starting with version 1.0....
3. What alternative could have been chosen knowing the
"mistakes" of 1.0 and before the 7.0 solution has been
set in stone.
No, definitily not. I have no wish to talk that way about stuff I cannot alter. Also, it would be bashing those thanwhile choices with our current knowledge. Thats simply not fair.
Sure. This is not the function for that. There isn't any
choice but to use an alternative. Is that a problem?
Lol. *you* are introducing a new sting type, and than claim you have no choice to use another function ? What about *NOT* introducing a new
string type ?
Because the '\r' is useless either way and needs
to be removed.
The same goes for that '$' terminating a string. Your point ?
But as I already mentioned, such a change (for either or both of the above strings) would have dire consequences. Which might easily be prohibitonary.
If we (as I do) theorize that Microsoft had created
a nice C API like the Pos* functions, instead of only
providing an assembler interface, what would that
API actually look like?
Nope, not going to engage in that. For several reasons.
One question though : whats, according to you, the difference between the above "C API" and "assembler interface" ?
I am not providing an API to print a NUL-terminated
string.
Which makes the problem bigger. Introducing something new, but not adding support for it.
I'm just setting rules for INT 21H 4BH.
And I've mentioned (and explained!) to you that changes to support an extended command-tail are not needed . If you think otherwise I would like
to hear why.
How is that better than CMDLINE?
It's not. That isn't the point. It's a better way (than what MS-DOS 7.x) to implement the code which provide CMDLINE. So that it doesn't depend on the command interpreter to do it. It also off-load the code to the DOS kernel, making programs a bit smaller. Yes, it does require the 3 components. That can not be helped.
Regardless, for PDOS/386 there is an opportunity for a
fresh start. The "environment" field, a 2-byte segment,
cannot be used by hook or crook, and needs to be a
4-byte pointer instead. And everything necessarily needs
to be recompiled for 80386 anyway, so there is no harm
in doing it differently.
If backward compatibility is not kept, it'll add more work to port existing softwares.
But the objective is still to make it easy for programmers[snip]
to target both 16-bit MSDOS and a theoretical 32-bit
MSDOS.
I'm thinking 32-bit should drop the fcb1/2, as they seem to
be outdated, and specify that the cmdtail doesn't have a
length in the first byte, and just relies on NUL-termination.
And no '\r' either.
Yes, but that only applies to programs which are created from scratch. It doesn't apply to existing programs.
It can be helped. You can avoid the middle component,
the OS, needing to be changed.
If you don't want to offload the code to the kernel, then yes.
And the command interpreter is not necessarily on
either side of that exec() call either.
Not the command line interpreting part. That's irrelevant. It's the program executing part.
There is a reasonably clean PosExec() for 16-bit MSDOS,
but the caller and called will both need to adjust for
32-bit MSDOS. I don't see any reasonable way of avoiding
that, and I don't know what the proposed alternative is
anyway.
The pointer interpretation is entirely different for both platforms. You'll juat have to treat pointers differently for each platform. e.g. for 16-bit DOS, HiWord of the pointer is the Segment, and LoWord of the pointer is the Offset; and for 32-bit DOS, HiWord is the upper 16 bits of the 32-bit flat address, and LoWord is the lower 16 bits of the 32-bit flat address.
Assuming that pointer for the 32-bit DOS is a flat address.
It can be helped. You can avoid the middle component,
the OS, needing to be changed.
And the command interpreter is not necessarily on
either side of that exec() call either.
Going from 8080 CP/M to 8086 MSDOS required conversion
of code at the assembler source level.
How do you propose doing a transition from 16-bit...
MSDOS to 32-bit theoretical MSDOS?
Starting with applications that are calling exec()
in either assembler or C.
Ok, I forgot to mention something there.
I am talking about 16-bit MSDOS programs that were
written with a reasonably clean (I'm willing to negotiate,
nothing is set in stone) Pos* interface, and then
porting those to 32-bit MSDOS.
There is a reasonably clean PosExec() for 16-bit MSDOS,
but the caller and called will both need to adjust for
32-bit MSDOS. I don't see any reasonable way of avoiding
that, and I don't know what the proposed alternative is
anyway.
The entirety of the code can't be offloaded from
either the caller or the callee.
The only thing you
can entirely offload is the kernel, and that
actually maximizes the usefulness of it.
I'm talking about the program execution.
PROGA can exec() PROGB without either the kernel
or command.com being involved.
There is no LoWord in the existing 16-bit MSDOS
exec() parameter block.
Starting from the above, how do you minimize the
amount of changes required to support a future
32-bit MSDOS? ie the year is 1986. MSDOS 3.2
was just released, and so was the 80386. Gates
just announced he will produce a 32-bit version
of MSDOS, but the exact details haven't been
announced yet.
The entirety of the code can't be offloaded from
either the caller or the callee.
Not the entire code. Only part of it. The CMDLINE creation part.
The only thing you
can entirely offload is the kernel, and that
actually maximizes the usefulness of it.
That would be no different that a bootable application which use its own private OS. Basically an OS, but isolated.
I'm talking about the program execution.
PROGA can exec() PROGB without either the kernel
or command.com being involved.
Offloading the CMDLINE creation code to the kernel which makes the kernel part of the components, was just a suggestion. It's up to you to decide whether to choose bigger kernel, or bigger applications; because the code
has to be placed somewhere.
There is no LoWord in the existing 16-bit MSDOS
exec() parameter block.
I was referring to your PDOS' pointer type in general.
Starting from the above, how do you minimize the
amount of changes required to support a future
32-bit MSDOS? ie the year is 1986. MSDOS 3.2
was just released, and so was the 80386. Gates
just announced he will produce a 32-bit version
of MSDOS, but the exact details haven't been
announced yet.
It's why I asked about the pointer type of your PDOS.
Ok, true, you can do that. But if you do that, you can
avoid the CMDLINE altogether and just create a new
INT 21H function, can't you? And maybe that is the
superior solution, so that we can fix this "envseg"
issue in the parm block at the same time.
I don't care about the size of either. What I care about is
compatibility.
Well, I'm willing to negotiate, but my opening offer, which
is what the PDOS/386 source code currently in sourceforge
does, now that I have fixed binutils 2.14a to stop stripping
relocation information, so that I could disable the VM code
that Alica wrote, is at the same level as 16-bit MSDOS - the
OS and applications all see the exact same flat memory
space, starting at location 0 (ie where you will find real
mode interrupt vectors, which are not the protected mode
interrupt vectors, which are currently not in a fixed location
so can't be directly manipulated by applications - but that's
not necessarily a bad thing).
Very simple. No memory protection. You can write directly
to 0xb8000 and the SVGA graphics card without any fuss
at all. As you can in 16-bit MSDOS if you make it
0xb800:0x0000
This is 32-bit MSDOS, not 32-bit Windows.
Actually I have a 32-bit Windows proposal too, but forget
about that for now, and let's agree what 32-bit MSDOS
should look like.
Ok, true, you can do that. But if you do that, you can
avoid the CMDLINE altogether and just create a new
INT 21H function, can't you? And maybe that is the
superior solution, so that we can fix this "envseg"
issue in the parm block at the same time.
Sure, the CMDLINE can be omitted and be replaced with a more elegant method, but didn't you said you want to make it easy to port programs to your OS? If you remove CMDLINE, you'll have more work porting those programs.
I don't care about the size of either. What I care about is
compatibility.
In your case, there's no way to keep 100% compatibility due to platform difference. What you can do is to minimize the incompatibilities due to that
Very simple. No memory protection. You can write directly
to 0xb8000 and the SVGA graphics card without any fuss
at all. As you can in 16-bit MSDOS if you make it
0xb800:0x0000
This is 32-bit MSDOS, not 32-bit Windows.
Actually I have a 32-bit Windows proposal too, but forget
about that for now, and let's agree what 32-bit MSDOS
should look like.
OK.
So, what if you treat segment fields as the upper 16-bit of the 32-bit flat address?
I really don't care how difficult it is for a C runtime
library author to convert from 16-bit MSDOS to
32-bit and 64-bit. I only care about the application
programmer.
Is this just for exec() or in general?
It's a lot of work to go to just for exec(), and it still won't
work anyway. Because if you only provide the upper
16 bits, it means you need to be able to allocate memory
on a 64k boundary, requiring a non-standard call.
I really don't care how difficult it is for a C runtime
library author to convert from 16-bit MSDOS to
32-bit and 64-bit. I only care about the application
programmer.
Well you can't have both an entirely different specification, and compatibility. You'll have to choose one and sacrifice the other. Whichever is easier for software developers.
Is this just for exec() or in general?
I meant DOS data structures which have segment fields instead of pointer fields. IOTW, special handling for those type of DOS structures only.
Nothing more.
It's a lot of work to go to just for exec(), and it still won't
work anyway. Because if you only provide the upper
16 bits, it means you need to be able to allocate memory
on a 64k boundary, requiring a non-standard call.
That is the downside, unfortunately.
Either way, it's like what I've mentioned earlier. You can't have both. You'll have to choose one. Do you want to keep DOS compatibility, or (third party) software compatibility? Whichever it's easier for the software developer.
It depends what you mean by "DOS compatibility".
I'm not expecting 32-bit software to run on 16-bit
hardware, and vice-versa.
If you think "DOS compatibility" is a hardware related, then I give up.
It depends what you mean by "DOS compatibility".
I'm not expecting 32-bit software to run on 16-bit
hardware, and vice-versa.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 417 |
Nodes: | 16 (2 / 14) |
Uptime: | 11:34:43 |
Calls: | 8,759 |
Calls today: | 2 |
Files: | 13,286 |
Messages: | 5,963,481 |