VxD-s technically allowed virtualizing devices, but only in a very limited way. The port IO instructions were easily intercepted but not much else. VxDs could use page protection tricks to redirect MMIO but this was used sparingly.
Really the only serious "virtualization" was in the interrupt handling. Code in Win9x that handles interrupts had to be 16-bit and located in the lower 640kb of RAM.
Most VxDs worked like classic drivers, they encapsulated device-specific interfaces and provided more abstract application-level interfaces.
Not for C++ code generated by whole program optimizing compilers. Your "human entered" is doing the heavy lifting. Now that AI is writing code your assertion might be on shaky ground.
C++ can be slow to compile, but as I said, parsing is not the bottleneck. Even for really huge automatically generated C++ files, or old-school concatenated "unity builds", the parsing step is generally tiny compared to everything else.
Coroutines, cooperative threading using fibres, type classes, generics, type deduction, easy interface with C++. The functional style, pattern matching. Flow based programming using 'chips and wires' abstraction.
It has many other interesting capabilities, for example, the ability to change its own grammar, that is rather too much, not for a pleb like me. It has unique (linear and affine) types too. It is really quite a handful.
Go did bring coroutines back into limelight but Felix predates Go by a margin.
Skaller, Felix's author, used Felix as a playground for novel language design ideas, so it was always in a state of flux.
Huh, that does sound like quite the grab bag of features. Think I'll have to find time to further investigate. Thanks for taking the time to elaborate!
I thought it was funny that the author used a variety of OCR tools with mixed success before spending a lot of time manually fixing up the output from the best one, rather than just typing it in
That was also my thought… but I grew up mashing rubber keys for hours copying “games” out of magazines and books! Then hours after fixing all the typos!
I ran it through paddle paddle OCR and it flawlessly did it.
Google's OCR through my phone's Google lens had also worked at getting a very good extraction but not 100% correct. Definitely would spend less time fixing it than hand copying.
IDK what the author was using but I feel like he could have shared how his OCR attempt went, but I am thinking he tried some naive OCR tools.
Author here - that's a good idea actually, it shouldn't be too hard to compare the various attempts. The tools I used were whatever my Android built-in is (likely Google Gemini, but I can't tell whether this is something Samsung has replaced in OneUI); tesseract; tesseract with various tweaks and charsrt restrictions; Claude; and finally, manual fixes based on disagreements between all the previous.
Took me almost 2 minutes for 4 lines (and I missed a character in one of them!).
I would opt for OCR too, obviously so I'm prepared for the next bash t-shirt I'd come across...
I think this is a case where two people can successfully complete the task manually faster than one attempting to automate it. Get a ruler, read five centimetres of characters to your colleague, have them type it in as you go, then repeat that five centimetres back to you. Correct as you go. Format your string with the same line-breaks as the t-shirt, and remove them at the end, so you can be sure you've got the correct length on each row. Trial-and-error adjust the five-cm distance depending on your success rate as you go along
All in, you should have a non-corrupted string in 10-15 min.
Feels like my experienced reality of task automation in corporate environments. We routinely have engineers spend 40+ hours automating tasks that an entry level person can do manually in 10 minutes and only need to be done weekly. Automation at all costs seems to be the future
It’s certainly not a new phenomenon. I appreciate this XKCD [1], with a chart of “How long can you work on making a routine task more efficient before you’re spending more time than you save”
It’s not the final word, since automation has other benefits: documenting the procedure’s steps, reducing human errors, increasing consistency, etc.
Not really. Transcribing long sequences of nonsense is annoying but quite easy to do without error as long you're patient enough to follow a simple process of reading, typing, and double-checking character-by-character.
Gemini3.5 Flash didn't have a problem OCR'ing and base64 decoding it, despite the OCR step having errors, it just fixed them in the base64 decoding step.
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.
> I'm not saying Windows 9x in particular had anything super interesting going on.
Oh it did though, it is a very interesting OS. Much more interesting than it usually gets credit for.
It's a proper 32 bit OS with pre-emptive multitasking and demand paging that is enough of a chimera with DOS that it still supports DOS programs, 16 bit Windows apps, and even your old DOS drivers - side-by-side with all the new 32 bit stuff.
This is correct. Win9x did have memory protection, it just made an intentional choice to set up wide open mappings for compatibility reasons.
WSL9x uses the same Win9x memory protection APIs to set up the mappings for Linux processes, and the memory protection in this context is solid. The difference is simply that there is no need to subvert it for compatibility.
doslinux is some tricky sleight of hand where it looks like Linux is running inside DOS, but it's actually the other way around (even though DOS boots first).
WSL9x takes quite a different approach. Windows boots first, but once Linux starts both kernels are running side-by-side in ring 0 with full privileges. They are supposed to cooperate, but if either crashes then both go down.