DOS in the browser: FreeDOS, MS-DOS and why any of it still runs
DOS was a program loader with a filesystem attached — no protection, no scheduler, one API. That is exactly why it boots in a browser tab in under a second.
The thing worth understanding about DOS is how little of it there is. It schedules nothing, because only one program runs at a time. It protects no memory, because there is nothing to protect it from. It has no drivers in the modern sense, no users and no concept of a process. What it has is a way to find a file on a disk, a way to load a program and jump to it, and one interrupt — INT 21h — through which that program asks for everything else. Strip a modern operating system of everything DOS lacks and almost nothing is left, which is why DOS still boots on hardware that exists only as JavaScript.
A program loader with a filesystem attached
When DOS runs a .COM file it reads the whole thing into memory at offset 0x0100 of a free segment, points all four segment registers at that segment, and jumps. The 256 bytes below the program are the Program Segment Prefix: the command-line tail, the environment pointer, and at offset zero an INT 20h, so a program can exit by jumping to address zero. A .COM file is therefore limited to one 64 KB segment, code, data and stack included. .EXE files add a header and relocation entries so a program can span segments, and that is the whole difference.
Everything else goes through INT 21h, with the function number in AH: 09h prints a $-terminated string, 3Dh opens a file, 3Fh and 40h read and write handles, 4Ch exits with a return code. There is no privilege boundary here. A program that decides to write directly to the video buffer at 0xB8000, reprogram the timer chip or replace an interrupt vector simply does so, and DOS never finds out. Terminate-and-stay-resident utilities are built out of that freedom: hook an interrupt, exit with function 31h so the memory is not reclaimed, and you have a background program on a system with no multitasking.
Where it came from
In 1980 Tim Paterson at Seattle Computer Products needed an operating system for a new 8086 board and wrote one in about six weeks. QDOS — Quick and Dirty Operating System, later 86-DOS — copied the shape of Digital Research's CP/M and added a FAT filesystem. Microsoft licensed it, bought 86-DOS outright in July 1981 for $25,000, and IBM shipped it that August as PC DOS 1.0 on the 5150. Version 2.0 in 1983 added subdirectories and file handles; 3.3 in 1988 supported larger disks; 5.0 in 1991 moved most of the kernel out of precious low memory. MS-DOS 6.22 in 1994 was the last standalone retail release; 7.x lived under Windows 95 and 8.0 under Windows Me.
Some of it is now free software. Microsoft published the MS-DOS 1.25 and 2.0 sources on GitHub under the MIT licence in 2018, and on 25 April 2024 added MS-DOS 4.00 — the 1988 release, contributed jointly with IBM. That is the version in this catalog as msdos4: a floppy that boots to A:\> and whose source you are now allowed to read, modify and redistribute.
| Name | Origin | Licence | Status |
|---|---|---|---|
| 86-DOS (QDOS) | Tim Paterson, Seattle Computer Products, 1980 | Sold to Microsoft, 1981 | Ancestor of everything below |
| PC DOS | IBM's branded MS-DOS from 1981 | Proprietary | Ended with PC DOS 2000 |
| MS-DOS | Microsoft, 1981–1994 standalone | Proprietary; 1.25, 2.0 and 4.00 are MIT | Three versions open-sourced |
| DR-DOS | Digital Research, 1988, from the CP/M lineage | Proprietary | Still sold |
| Novell DOS 7 / OpenDOS | Novell 1993, then Caldera from 1996 | Source published for non-commercial use, 1997 | Discontinued |
| FreeDOS | Jim Hall, 1994 | GPL, mixed for utilities | Active; 1.4 released April 2025 |
FreeDOS, which never stopped
On 29 June 1994, after Microsoft made clear DOS had no future as a product, a student called Jim Hall announced PD-DOS: a free replacement, built in the open. The name changed to FreeDOS, Pat Villani's DOS-C became the kernel, and the project has been shipping ever since — 1.0 in 2006, 1.2 in 2016, 1.3 in 2022 and 1.4 in April 2025, a strange and rather cheering schedule for software whose commercial competitor was discontinued while its author was still at university. It is no museum piece either: a great many BIOS-update floppies and vendor firmware tools still boot into it.
The memory model everyone remembers with pain
DOS runs in real mode, where a segment and an offset combine as (segment << 4) + offset and the reachable address space is one megabyte. When IBM designed the 5150 it reserved the top 384 KB for video buffers — colour text lives at 0xB8000 — plus adapter ROMs and the BIOS. What was left for programs was the first 640 KB, and that number became the defining constraint of a decade of software.
Three workarounds accumulated. EMS, the Lotus/Intel/Microsoft Expanded Memory Specification of 1985, bank-switched extra memory through a 64 KB window in the reserved area, four 16 KB pages at a time. XMS, driven by HIMEM.SYS, made memory above the megabyte available through a driver interface and, as a side effect of the A20 line, exposed the high memory area: the first 65,520 bytes above 1 MB, reachable in real mode from FFFF:0010. From MS-DOS 5.0 you could write DOS=HIGH and move most of the kernel there, freeing up to about 46 KB below 640 KB. UMBs filled the unused gaps in the reserved 384 KB with usable RAM, so drivers could be loaded with DEVICEHIGH and LOADHIGH.
All of that was configured in two files read at boot: CONFIG.SYS, which loads drivers and sets kernel limits, and AUTOEXEC.BAT, which the command interpreter runs afterwards. Getting them right was a genuine skill; getting them wrong meant a game refusing to start.
REM ---------- CONFIG.SYS ----------
REM XMS driver: extended memory, and with it the 65,520-byte HMA.
DEVICE=C:\DOS\HIMEM.SYS
REM Kernel into the HMA; allow upper memory blocks to be created.
DOS=HIGH,UMB
REM Provide EMS pages and fill the holes in the 384 KB upper area.
DEVICE=C:\DOS\EMM386.EXE RAM
REM ANSI driver goes upstairs, not into the precious first 640 KB.
DEVICEHIGH=C:\DOS\ANSI.SYS
FILES=40
BUFFERS=20
SHELL=C:\DOS\COMMAND.COM C:\DOS\ /P /E:512
REM ---------- AUTOEXEC.BAT ----------
@ECHO OFF
PATH C:\DOS;C:\UTILS
SET TEMP=C:\TEMP
PROMPT $P$G
REM LH is LOADHIGH: the mouse driver goes into an upper block too.
LH C:\DOS\MOUSE.COM
REM Every game of the era read this variable to find the sound card.
SET BLASTER=A220 I5 D1 T4
MEM /C /P
This is why a machine with 8 MB of RAM would still tell you there was not enough memory. Only the first 640 KB is directly usable by an ordinary program; everything above it has to be reached deliberately, through EMS or XMS calls the program must have been written to make. What matters is not how much memory the machine has but how much of the first 640 KB is free after the drivers and TSRs have taken theirs — which is what MEM /C reports:
C:\>mem /c
Memory Type Total Used Free
---------------- -------- -------- --------
Conventional 640K 72K 568K
Upper 155K 155K 0K
Extended (XMS) 7,397K 3,301K 4,096K
---------------- -------- -------- --------
Total memory 8,192K 3,528K 4,664K
Total under 1 MB 795K 227K 568K
Largest executable program size 568K (581,632 bytes)
Largest free upper memory block 0K (0 bytes)
MS-DOS is resident in the high memory area.
FAT, and names with eight letters
The File Allocation Table is a linked list kept outside the files it describes. A directory entry records a file's first cluster, and the FAT holds one entry per cluster giving the number of the next, or an end-of-file marker. A 1.44 MB floppy — 80 cylinders, 2 heads, 18 sectors of 512 bytes — uses FAT12, one sector per cluster, and a fixed root directory of 224 entries. Each entry is 32 bytes: eleven for the name, an attribute byte, a timestamp, the starting cluster and the size. Those eleven bytes are where 8.3 comes from — eight for the name, three for the extension, uppercase. There is nowhere in those 32 bytes for an owner or a permission, because there was never going to be more than one user. The filesystems guide covers what later designs did with that space.
Why DOS is the ideal guest for a browser
Every heavy system in this catalog fights the emulator: a graphical OS wants paging, an APIC, ACPI tables, a disk controller that behaves under load, and hundreds of megabytes streamed before it shows anything. DOS wants a processor in real mode, a BIOS that answers INT 13h for disk and INT 10h for video, a timer and a keyboard. That is all of it. The bundled FreeDOS image is 1.44 MB, the machine has 32 MB of RAM, and the prompt appears in well under a second — no snapshot trickery, just a tiny system doing a short amount of work. It is the one place here where emulation feels like the real thing rather than a slow approximation.
What to do once you are at the prompt
DIR /W /Plists a directory in columns, a page at a time;CD,MDandRDmanage directories.TYPE FILE.TXTdumps a file to the screen;COPY,REN,DELandXCOPYdo the obvious things;ATTRIBshows and sets the read-only, hidden, system and archive bits.EDITis a full-screen text editor with menus, which was a considerable novelty in 1991.VERprints the version,MEM /Cthe memory map above.FDISKpartitions a disk andFORMATwrites a filesystem onto one. Both are safe to experiment with here, because the disk is a copy in page memory.- Batch files are a real if primitive language:
ECHO,SET,IF EXIST,GOTOandFOR %%f IN (*.TXT) DO.AUTOEXEC.BATis just one of them.
DEBUG, the back door
DEBUG has shipped with DOS since version 1.0 and is the shortest route to the bare machine. It assembles, disassembles, dumps and patches memory, runs code step by step, and reads and writes raw disk sectors. Magazine listings in the 1980s were often published as DEBUG scripts because every reader already had it. Here is a complete program, typed by hand, that prints a string and exits:
C:\>debug
-a 100
0AF0:0100 mov ah,9
0AF0:0102 mov dx,10c
0AF0:0105 int 21
0AF0:0107 mov ah,4c
0AF0:0109 int 21
0AF0:010B
-e 10c "Hello from real mode." 0d 0a 24
-u 100 10a
0AF0:0100 B409 MOV AH,09
0AF0:0102 BA0C01 MOV DX,010C
0AF0:0105 CD21 INT 21
0AF0:0107 B44C MOV AH,4C
0AF0:0109 CD21 INT 21
-g
Hello from real mode.
Program terminated normally
-q
Five instructions, thirteen bytes. AH=09h prints the string at DS:DX, which must end in a $ — the 24 at the end of the e command, with 0d 0a for carriage return and line feed before it. AH=4Ch returns to the command interpreter. Nothing checked whether that address was yours to write to, and nothing would have stopped you if it had not been.
The honest limits here
- No sound. There is no Sound Blaster and no AdLib, so period games that expect one run silently or refuse to start. The
SET BLASTERline above is authentic history, not working configuration. - Timing-sensitive software misbehaves. Emulated CPU speed depends on the machine you are sitting at, so anything calibrated against a loop counter will show it.
- Nothing persists. Writes go to a copy of the image held in page memory; reload the tab and every file you created is gone.
- FreeDOS here is a boot floppy, not an installation. You get the kernel, the shell and a set of utilities, but not the full
HIMEM.SYSandEMM386.EXEarrangement described above. - FreeDOS is bundled; MS-DOS 4.00 is not. The FreeDOS floppy ships with the site and boots with no network. The
msdos4image is fetched from the image host, so it needs a connection and correct CORS headers.
Start FreeDOS from the machine list, type MEM /C, then DEBUG, and you are looking at a processor with no supervisor and nothing between your instructions and the hardware. It is the last widely used system of which that was true.