Rendered at 17:38:22 GMT+0000 (Coordinated Universal Time) with Cloudflare Workers.
fao_ 17 hours ago [-]
People who are interested in DOS software might take note of "Pits", a DOS assembler demo from 2024 which features, quote:
- Multithreading (using all hyper-threads / CPU cores)
- Video mode up to Full HD (1920x1080 / 16 bpp)
- 64-iterative ray-casting
- Pure DOS with Protected Mode (no drivers, no DPMI)
It is a seriously technically impressive demo, if not being the most visually impressive.
HellMood 10 hours ago [-]
Those people should also definitely check out "Mariana" (2024), a 256 byte demo from the same author, using the same techniques, which was even nominated for the Meteoriks Award for that year.
Features:
- Multithreading (using all CPU cores & hyper-threads)
- Full HD / HiColor (1920x1080 / 16 bpp)
- 128-iterative fractal on FPU
- Pure DOS (no drivers, no DPMI)
vintagedave 21 hours ago [-]
So this seems to be a mystery binary someone found on a company DVD, that runs DOS on one core and runs another core with code but no interrupts etc. Fascinating.
The thread later mentions a second way to do it.
In this setup, how would cross-core communication work, including cross-thread? On DOS is there even the concept of threads, or would an app using this have to invent user-mode thread objects and scheduling?
toast0 20 hours ago [-]
> In this setup, how would cross-core communication work, including cross-thread?
Communication via shared memory. DOS and friends run on core 0 more or less normally; core 1 runs your alternate programming. Allocate a shared ring buffer for messages in each direction, core 0 writes messages and updates the written index on one, reads messages and updates the read index on the other; vice version for core 1. Core 1 probably spins on checking the indexes if it doesn't have anything else to do.
Either allocate a big chunk of memory for core 1 work at startup, or let it message core 0 to allocate. Don't let core 1 call into DOS/BIOS syscalls directly or you'll have a big mess.
Next step in efficiency would be letting core 1 sleep when it's bored and use an inter-processor interrupt (IPI) to wake it up as needed.
Stevvo 18 hours ago [-]
Pretty much how its done in TempleOS
mikestorrent 18 hours ago [-]
Post more on this illustrious topic
fredoralive 21 hours ago [-]
DOS barely has any concept of processes, let alone threads.
So it’ll all be very do it yourself. Of course with everything running in ring 0, there’s not much that’s going to get in the way of you.
haileys 20 hours ago [-]
> DOS barely has any concept of processes
That's not true - DOS lacks multitasking but it absolutely has a concept of processes. They're called PSPs (program segment prefixes, a struct containing data about that process) and the OS has a range of syscalls to manage them. Any program can spawn a child program and wait for its completion.
The memory allocation syscalls track which program owns each dynamically allocated block of memory (the block has a header which points to the PSP), and frees the blocks allocated by a program when it exits. The filesystem syscalls deal with file handles opened by processes in just the same way.
The famous "terminate and stay resident" syscall causes a program to exit and return to its parent process while keeping its PSP and dynamically allocated memory blocks intact.
16 bit Windows introduced multitasking but reused DOS's PSP based process model and would allocate a PSP for each Windows task, switching the current DOS PSP when switching between Windows tasks.
kmeisthax 21 hours ago [-]
DOS has no concept of multiple cores, much less threads. Multiprocessing in such an environment "works" mainly for the same reason why pthreads and friends "worked" in the decades before C++11 standardized a memory model for native code. The hardware and your code must conspire to work around the part that isn't thread-aware.
Nothing is really stopping you from using the underlying hardware for concurrent execution, but at the same time DOS (and possibly BIOS/UEFI???) will blow chunks if you don't carefully synchronize access to it. Cross-core communication works exactly the same as it does in kernel-mode systems programming; and you need to bring your own synchronization primitives on top of the ones x86 processors ship with. You're basically writing an OS kernel at that point; one that just so happens to support kexec-ing back into COMMAND.COM and using bits of it as a filesystem driver.
stevefan1999 15 hours ago [-]
Well, even so, multicore nowadays is supposedly just running the kernel over different CPUs by treating each CPU as its independent computer, and use a message box to deliver event messages, that's how x86 works with APIC and SIPI
userbinator 14 hours ago [-]
I wouldn't necessarily call this "support" because DOS itself does nothing for or against; and "all" you need to do conceptually is tickle the APIC to get the other cores running, something that can be done easily even in flat real mode (but this sample appears to use DPMI, so protected mode --- and DPMI itself begins to contain the elements of an OS.)
Not surprised to see the German comments; a lot of low-level PC stuff came from there in the 80s and 90s.
vkaku 12 hours ago [-]
Pastebin links here in case someone's getting Vogons issues.
I seriously wonder how many APICs are exposed in the DOSBOX code even... Would be a fun exercise to do this and wake up real mode on all cores. I know it's easy to get to long mode after that:
Certainly if you do not call out to DOS or the BIOS! All the time with DOS we would write text to the screen by writing it into memory because it was so fast and if you wrote a terminal emulator you would catch the interrupts and write to the UART registers in assembly or C or Turbo Pascal. You only needed DOS for the filesystem otherwise the application could do anything that DOS could do.
Old versions of Linux had a giant lock on the whole kernel which would let only one CPU enter the kernel at once. You could probability protect DOS the same way at the cost of scalability.
It is a seriously technically impressive demo, if not being the most visually impressive.
https://www.pouet.net/prod.php?which=96105
https://2025.meteoriks.org/laureates/#nominees-ota
The thread later mentions a second way to do it.
In this setup, how would cross-core communication work, including cross-thread? On DOS is there even the concept of threads, or would an app using this have to invent user-mode thread objects and scheduling?
Communication via shared memory. DOS and friends run on core 0 more or less normally; core 1 runs your alternate programming. Allocate a shared ring buffer for messages in each direction, core 0 writes messages and updates the written index on one, reads messages and updates the read index on the other; vice version for core 1. Core 1 probably spins on checking the indexes if it doesn't have anything else to do.
Either allocate a big chunk of memory for core 1 work at startup, or let it message core 0 to allocate. Don't let core 1 call into DOS/BIOS syscalls directly or you'll have a big mess.
Next step in efficiency would be letting core 1 sleep when it's bored and use an inter-processor interrupt (IPI) to wake it up as needed.
So it’ll all be very do it yourself. Of course with everything running in ring 0, there’s not much that’s going to get in the way of you.
That's not true - DOS lacks multitasking but it absolutely has a concept of processes. They're called PSPs (program segment prefixes, a struct containing data about that process) and the OS has a range of syscalls to manage them. Any program can spawn a child program and wait for its completion.
The memory allocation syscalls track which program owns each dynamically allocated block of memory (the block has a header which points to the PSP), and frees the blocks allocated by a program when it exits. The filesystem syscalls deal with file handles opened by processes in just the same way.
The famous "terminate and stay resident" syscall causes a program to exit and return to its parent process while keeping its PSP and dynamically allocated memory blocks intact.
16 bit Windows introduced multitasking but reused DOS's PSP based process model and would allocate a PSP for each Windows task, switching the current DOS PSP when switching between Windows tasks.
Nothing is really stopping you from using the underlying hardware for concurrent execution, but at the same time DOS (and possibly BIOS/UEFI???) will blow chunks if you don't carefully synchronize access to it. Cross-core communication works exactly the same as it does in kernel-mode systems programming; and you need to bring your own synchronization primitives on top of the ones x86 processors ship with. You're basically writing an OS kernel at that point; one that just so happens to support kexec-ing back into COMMAND.COM and using bits of it as a filesystem driver.
Not surprised to see the German comments; a lot of low-level PC stuff came from there in the 80s and 90s.
https://pastebin.com/9sgW9dVu https://pastebin.com/3rG2eiWD
I seriously wonder how many APICs are exposed in the DOSBOX code even... Would be a fun exercise to do this and wake up real mode on all cores. I know it's easy to get to long mode after that:
https://github.com/guilt/KOS/blob/master/os/src/x86/realprot...
https://en.wikipedia.org/wiki/MS-DOS_4.0_(multitasking)
Old versions of Linux had a giant lock on the whole kernel which would let only one CPU enter the kernel at once. You could probability protect DOS the same way at the cost of scalability.
Hm?