Did you know Emacs does not only support the full range of Windows operating systems, but even works on MS-DOS? One would have assumed the support for this officially unsupported platform would have been snipped out already, but Eli Zaretskii, a high profile core Emacs developer best known for their contributions to the display engine, is still contributing to it.
The build process is slightly weird. You do need GCC to support the full range of GNUisms the code is riddled with, but GCC surely doesn’t support DOS… or does it? Meet DJGPP!
That being said, msdos.c is surprisingly easy to read compared to the rest I’ve dipped my toes into. Must be the low number of C macro abuse incidents, well commented code and the overall simplicity of the system target, much unlike modern platforms. I urge you to take a look as well, here’s my top ten comments:
/* Note the startup time, so we know not to clear the screen if we exit immediately; see IT_reset_terminal_modes. (Yes, I know `clock' returns zero the first time it's called, but I do this anyway, in case some wiseguy changes that at some point.) */ startup_time = clock ();
/* We only look at the keyboard Ctrl/Shift/Alt keys when
Emacs is ready to read a key. Therefore, if they press
`Alt-x' when Emacs is busy, by the time we get to
`dos_get_modifiers', they might have already released the
Alt key, and Emacs gets just `x', which is BAD.
However, for keys with the `Map' property set, the ASCII
code returns zero only if Alt is pressed. So, when we DON'T
have to support international_keyboard, we don't have to
distinguish between the left and right Alt keys, and we
can set the META modifier for any keys with the `Map'
property if they return zero ASCII code (c = 0). */
/* Emacs calls cursor-movement functions a lot when it updates the
display (probably a legacy of old terminals where you cannot
update a screen line without first moving the cursor there).
However, cursor movement is expensive on MSDOS (it calls a slow
BIOS function and requires 2 mode switches), while actual screen
updates access the video memory directly and don't depend on
cursor position. To avoid slowing down the redisplay, we cheat:
all functions that move the cursor only set internal variables
which record the cursor position, whereas the cursor is only
moved to its final position whenever screen update is complete.
`IT_cmgoto' is called from the keyboard reading loop and when the
frame update is complete. This means that we are ready for user
input, so we update the cursor position to show where the point is,
and also make the mouse pointer visible.
Special treatment is required when the cursor is in the echo area,
to put the cursor at the end of the text displayed there. */
/* Define a lot of environment variables if not already defined. Don't
remove anything unless you know what you're doing -- lots of code will
break if one or more of these are missing. */
/* Time zone determined from country code. To make this possible, the
country code may not span more than one time zone. In other words,
in the USA, you lose. */
/* FIXME: I'm not sure the above will run at all on DOS/V. But let's be defensive anyway. */ if (screen_virtual_segment) dosv_refresh_virtual_screen (0, *cols * *rows);
/* Simulation of X's menus. Nothing too fancy here -- just make it work
for now.
Actually, I don't know the meaning of all the parameters of the functions
here -- I only know how they are called by xmenu.c. I could of course
grab the nearest Xlib manual (down the hall, second-to-last door on the
left), but I don't think it's worth the effort. */
/* In some sense all dos users have root privileges, so... */ setenv ("USER", "root", 0); setenv ("NAME", getenv ("USER"), 0);
/* Don't restore the screen if we are exiting less than 2 seconds
after startup: we might be crashing, and the screen might show
some vital clues to what's wrong. */
/* We have a situation here. ScreenUpdate has just restored the
screen contents as it was before we started drawing this menu.
That includes any echo area message that could have been
displayed back then. (In reality, that echo area message will
almost always be the ``keystroke echo'' that echoes the sequence
of menu items chosen by the user.) However, if the menu had some
help messages, then displaying those messages caused Emacs to
forget about the original echo area message. So when
ScreenUpdate restored it, it created a discrepancy between the
actual screen contents and what Emacs internal data structures
know about it.
To avoid this conflict, we force Emacs to restore the original
echo area message as we found it when we entered this function.
The irony of this is that we then erase the restored message
right away, so the only purpose of restoring it is so that
erasing it works correctly... */