
Did you ever need to run a piece of C# code on Windows 3.11? - lelf
https://twitter.com/MStrehovsky/status/1215331352352034818
======
Dutchie2020
Love this guy, make sure you check out his 8kb C# game:
[https://medium.com/@MStrehovsky/building-a-self-contained-
ga...](https://medium.com/@MStrehovsky/building-a-self-contained-game-in-c-
under-8-kilobytes-74c3cf60ea04)

~~~
zip1234
It really is a great article and truly interesting techniques to get the size
down.

~~~
rafaelvasco
That's like gold to me. Really useful tips right there. At the end things went
crazy haha. I'm satisfied with 1MB size hahah.

------
protastus
"Turns out the object files produced by the CoreRT ahead of time compiler from
2020 can still be linked with the linker that shipped with Visual C++ 2.0 in
1994."

This really blew my mind.

~~~
gambiting
Yeah, for all the shit that Microsoft gets, their backwards compatibility
efforts are extraordinary. I work in games and we recently dug out a project
from 1998, last built using Visual Studio 5, and everything just compiled,
linked and ran using Visual Studio 2019 with some extremely minor changes in
project config.

------
amluto
For what it’s worth, CPU compatibility with old segmented code (like Windows
3.11) is a bit iffy these days for a silly legacy reason. The old x87 floating
point coprocessor had two registers FCS and FDS — they’re the CS and DS
segments at the time of the last x87 data instruction. This was used for the
386’s asynchronous FPU exception handling. Fast forward to the ultramodern
486, and floating point exception handling was cleaned up and FCS and FDS
became unnecessary, but they were kept for compatibility. All was well.

Unfortunately, AMD made a mistake in AMD64: the new 64-bit floating point
context switching instructions couldn’t switch the FCS and FDS registers. This
not only broke some very old software when run on a new kernel or hypervisor,
but it also created a potential information leak.

Sadly, new CPUs “fix” this in an unfortunate way. Trying to read FCS or FDS
gives zero. Now some very old software is broken.

------
jugg1es
His twitter feed is pretty interesting. He's a damn wizard.
[https://twitter.com/MStrehovsky/status/1214542538079690757](https://twitter.com/MStrehovsky/status/1214542538079690757)

------
vortico
It's funny that someone else on HN just managed to run a Java program on Amiga
1000.
[https://news.ycombinator.com/item?id=22011199](https://news.ycombinator.com/item?id=22011199)

~~~
paulddraper
[https://www.xkcd.com/801/](https://www.xkcd.com/801/)

------
ComputerGuru
Holy backwards compatibility, Microsoft!

~~~
egdod
Raymond Chen has lot of good stories about the lengths Microsoft would go to
to ensure old programs still worked.

[https://devblogs.microsoft.com/oldnewthing/tag/history](https://devblogs.microsoft.com/oldnewthing/tag/history)

~~~
ComputerGuru
Yes, one of my favorite bloggers for more years than I can count. What is
crazy isn’t just how crazy the stories he has to share are but also just how
many of them he has. You’d think with the craziness bar set so high he
wouldn’t have this much content, but he still manages to be one of the most
prolific bloggers!

------
fuball63
I've been seeing a lot of stuff about Windows 3.11 lately, did they release it
free recently? Like they did early versions of MSDOS?
[https://github.com/microsoft/MS-DOS](https://github.com/microsoft/MS-DOS)

~~~
Macha
The author mentioned in a reply that they got their copy with a VS
subscription.

~~~
sebazzz
Yes, and until about a year back Windows 95 and 98 were available also but
they have been taken offline. If I recall it correctly it is due to some
copyright issue.

~~~
zozbot234
Didn't Windows 95 and Windows 98 include Java by default? Probably yet another
side-effect of the Oracle-Google thing.

~~~
pram
Microsoft Java (lol) and they already were sued about it ;P

~~~
stkdump
Oh, I remember J++! The glorious embrace and extend days...

~~~
WorldMaker
J++ is a big part of why C# exists today.

~~~
Nitramevfank
Isn't that a back backwards? Isn't it more like: Microsoft wanted a more
modern language and they weren't allowed to use Java so they created c#?

~~~
WorldMaker
Microsoft thought Java was a good idea in that they liked the JVM a lot, but
the language itself they saw as flawed and missing key features that would
make it a truly modern language, in particular they heavily disagreed with
Sun's approach to FFI (foreign function interface) [Java's slow, laborious
efforts eventually building JNI, the Java Native Interface], because of their
many years of experience for better and worse with COM (component object
model).

J++ was never meant to be "Java", and never technically was even in branding,
it was essentially a second language (that Microsoft saw at the time as C++ is
to C, it was to Java, and that's very clearly represented in that brand name)
that also targeted the Microsoft version of the JVM, and used a couple
Microsoft-specific escape hatches for FFI and COM.

(So it absolutely was an "embrace and extend", but it wasn't of the Java
language itself so much as it was the JVM that Microsoft wanted to embrace and
extend that seemed to fright Sun so badly. That's probably why so much of the
legal drama and the consequent blows to the rest of the Java ecosystem at the
time was Sun withdrawing JVM licenses from just about everyone as a part of
that battle. Originally Sun seemed rather happy licensing the JVM to whoever
wanted to implement it, which is why Microsoft had a JVM in the first place,
thinking controlling the Java language was enough. Sun worked to put that
genie back in the bottle and move everyone back to mostly a single JVM again.
There's no lack of irony in the exact same battle playing out between Oracle
and Google decades later in the battle of Dalvik [Google's JVM] and Android.)

It wasn't that Sun didn't want Microsoft using Java, they didn't want
Microsoft using the JVM any longer, and without a license to build their own
JVM, J++ wouldn't run on any other JVM and wasn't a useful language.

When Microsoft lost their JVM they decided to start from scratch, moved the
J++ team (including and particularly Anders Hejlsberg, C# lead) to a new VM
that they could control from top to bottom (including its FFI mechanics), and
much of what had directly been the J++ team used what they learned from the
whole mess to create C#.

------
yread
How come there are so many Slovak and Czech people working on .NET Core at MS?
Tomas Petricek, Karel Zikmund, Jan Kotas, Jan Vorlicek, Tomas Matousek,...

~~~
JoeMayoBot
Great minds - Microsoft is an increasingly diverse company and you'll see
smart people from everywhere in the world there.

~~~
DaiPlusPlus
Aye. My team in DevDiv (home of .NET) had a Brit (me), a Turkish lady, two
Russians, two Canadians (one French), three Indians, my lead was Mexican, and
only 1 American.

------
userbinator
Oh... Win32s. For a moment, I was wondering how he got the C# compiler to
generate 16-bit code.

------
pixelpoet
As much as I needed to run Java on an Amiga, at least.

------
mmoez
Truly mind-boggling!

------
thrownaway954
the last 2 articles from this dude have amazed me. he is a NINJA!!!

------
leeoniya
> This will produce a single EXE file that has whopping 65 MB. The produced
> EXE includes the game, the .NET Runtime, and the base class libraries that
> are the standard part of .NET. You might say “still better than Electron”
> and call it good, but let’s see if we can do better.

Perhaps a better JS baseline would be QuickJS [0].

Once 1.2MB was reached:

> Now we’ve reached the end of what’s possible with the .NET SDK and we need
> to get our hands dirty. What we’re going to do now is starting to be
> ridiculous and I wouldn’t expect anyone else to do this. We’re going to rely
> on the implementation details of the CoreRT compiler and runtime.

QuickJS is 620K.

I guess that doesn't include any kind of facility for rendering to the screen
(besides basic barfing to stdout) or interacting with keyboard/mouse. i wonder
how much code would be needed to add support for a basic canvas pixeldata api
& keyboard event handling.

[0] [https://bellard.org/quickjs/](https://bellard.org/quickjs/)

~~~
int_19h
Very little, actually. You'd need CreateWindow to get a surface to render
onto, and from there you have access to GDI, GDI+, OpenGL, and D3D via
P/Invoke

If by "basic Canvas pixelData" you mean blitting an array of pixels in a loop,
that would require a grand total of 4 API calls: CreateWindow, GetDC,
CreateBitmap, BitBlt. Keyboard and mouse handling would be a dozen lines of
code to process the corresponding window messages in the event loop.

I bet this would all still fit in under 64Kb.

