Paul Edwards
2024-09-14 12:42:45 UTC
Hi.
I waited with bated breath for C90 to come out - to see if the
"international community" was going to change anything in C89.
They didn't (quibbling aside).
That was in 1990 obviously.
I then basically froze technology in 1990 and tried to understand it.
A few years later I noticed that MSDOS (io.sys, msdos.sys) was
pretty small, and wondered if it was possible to write a small OS
the equivalent of MSDOS, but on the 80386 instead, and written
in C instead of assembler. Equivalent in functionality bearing in
mind that even on MSDOS I stuck with writing C90-compliant
programs. So I did expect a recompilation.
A few decades later and I have a plethora of things at https://pdos.org
The latest drive has been consolidating mainframe operating systems.
Again - I'm writing C90-compliant programs on the mainframe too.
So what does it take to write an operating system that can run those
programs?
Inspired by the number 4 and other things on the Amiga, I created
a new design of PDOS called PDOS-generic. I basically treat an
existing operating system as a glorified BIOS, and basically run in
userspace - as an option. But the other option is a standalone OS.
It depends on circumstances.
Then there's another factor. While some systems interface with the
OS via DLLs or callbacks (like the Amiga), others issue interrupts
(on the mainframe called SVCs), and I thought that was impossible
to do via userspace.
However, when attempting to port to the Atari which was in the
same boat (interrupts), someone suggested a technique to bypass
the interrupts, and the end result is this line:
__pgparm: .long 0 # This will be zapped by z/PDOS-generic if running under
it
in the below:
PDOS / Git Code / [05d5be] /pdpclib/mfsupa.asm (sourceforge.net)
__crt0:
B skiphdr
# .byte "PGCX" # PDOS-generic (or compatible) extension
# Needs to be in EBCDIC
.byte 0xd7, 0xc7, 0xc3, 0xe7
# .long 4 # length of header data
.DC F'4'
.globl __pgparm
__pgparm: .long 0 # This will be zapped by z/PDOS-generic if running under
it
skiphdr:
L R1,=V(__pgparm)
Using that, the SVC is conditionally bypassed in the C code, like this:
int __svc(int svcnum, void *regsin, void *regsout)
{
if (__pgparm == 0)
{
return (__svcreal(svcnum, regsin, regsout));
}
else
{
return (__pgparm->Xservice(svcnum, regsin, regsout));
}
}
on real VSE, it executes the SVC. On z/PDOS-generic it does a callback.
A similar technique will be used for when it is inspecting low memory
(address 20 decimal - similar to how Amiga address 4 needs to be
overridden).
The mainframe has 3 remaining environments - MVS, CMS and VSE.
For mainly accidental reasons I ended up doing VSE first. But the
technique should work for CMS and MVS too, which I expect to do
in due course.
Now that I have proven one way to skin the cat, I'm wondering whether
there is any superior technique or anything else that I may be missing.
All of this is being done with the benefit of hindsight, obviously.
I'm interested in what a "reboot" starting in 1990 would look like.
Thanks. Paul.
I waited with bated breath for C90 to come out - to see if the
"international community" was going to change anything in C89.
They didn't (quibbling aside).
That was in 1990 obviously.
I then basically froze technology in 1990 and tried to understand it.
A few years later I noticed that MSDOS (io.sys, msdos.sys) was
pretty small, and wondered if it was possible to write a small OS
the equivalent of MSDOS, but on the 80386 instead, and written
in C instead of assembler. Equivalent in functionality bearing in
mind that even on MSDOS I stuck with writing C90-compliant
programs. So I did expect a recompilation.
A few decades later and I have a plethora of things at https://pdos.org
The latest drive has been consolidating mainframe operating systems.
Again - I'm writing C90-compliant programs on the mainframe too.
So what does it take to write an operating system that can run those
programs?
Inspired by the number 4 and other things on the Amiga, I created
a new design of PDOS called PDOS-generic. I basically treat an
existing operating system as a glorified BIOS, and basically run in
userspace - as an option. But the other option is a standalone OS.
It depends on circumstances.
Then there's another factor. While some systems interface with the
OS via DLLs or callbacks (like the Amiga), others issue interrupts
(on the mainframe called SVCs), and I thought that was impossible
to do via userspace.
However, when attempting to port to the Atari which was in the
same boat (interrupts), someone suggested a technique to bypass
the interrupts, and the end result is this line:
__pgparm: .long 0 # This will be zapped by z/PDOS-generic if running under
it
in the below:
PDOS / Git Code / [05d5be] /pdpclib/mfsupa.asm (sourceforge.net)
__crt0:
B skiphdr
# .byte "PGCX" # PDOS-generic (or compatible) extension
# Needs to be in EBCDIC
.byte 0xd7, 0xc7, 0xc3, 0xe7
# .long 4 # length of header data
.DC F'4'
.globl __pgparm
__pgparm: .long 0 # This will be zapped by z/PDOS-generic if running under
it
skiphdr:
L R1,=V(__pgparm)
Using that, the SVC is conditionally bypassed in the C code, like this:
int __svc(int svcnum, void *regsin, void *regsout)
{
if (__pgparm == 0)
{
return (__svcreal(svcnum, regsin, regsout));
}
else
{
return (__pgparm->Xservice(svcnum, regsin, regsout));
}
}
on real VSE, it executes the SVC. On z/PDOS-generic it does a callback.
A similar technique will be used for when it is inspecting low memory
(address 20 decimal - similar to how Amiga address 4 needs to be
overridden).
The mainframe has 3 remaining environments - MVS, CMS and VSE.
For mainly accidental reasons I ended up doing VSE first. But the
technique should work for CMS and MVS too, which I expect to do
in due course.
Now that I have proven one way to skin the cat, I'm wondering whether
there is any superior technique or anything else that I may be missing.
All of this is being done with the benefit of hindsight, obviously.
I'm interested in what a "reboot" starting in 1990 would look like.
Thanks. Paul.