-
Notifications
You must be signed in to change notification settings - Fork 0
dos
MS-DOS 6.22 can see no more than 1024 cylinders, which is roughly 504 MB with 16 heads (C/H/S = 1024/16/63) and 8032.5 MB with 255 heads (C/H/S = 1024/255/63). Sector size is assumed to be 512 bytes.
A disk image file of 504 MB (with 16 "heads") can be created using the bximage
utility from bochs
. A disk image with 255 "heads" can be created using dd
:
dd if=/dev/zero of=path/to/hda.img bs=512 count=16450560
Don't forget to make the image file sparse:
fallocate -d path/to/hda.img
MS-DOS can be installed using the following [autoexec]
section in dosbox.conf
:
[autoexec]
@echo off
imgmount 2 path/to/hda.img -t hdd -fs none -size 512,63,255,1024
rem Install MS-DOS 6.22, Ctrl+F4 to swap floppy images.
boot path/to/disk01.img path/to/disk02.img path/to/disk03.img
Once MS-DOS is installed, be sure to update the boot command arguments:
[autoexec]
@echo off
imgmount 2 path/to/hda.img -t hdd -fs none -size 512,63,255,1024
cls
boot -l c
If extra partitions (D:, E:, F:) are created in the above 8 GB disk (using DOS
fdisk
), the image file geometry, as reported by Linux fdisk
, will be:
Disk hda.img: 7.84 GiB, 8422686720 bytes, 16450560 sectors
Geometry: 255 heads, 63 sectors/track, 1024 cylinders
Units: cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000
Device Boot Start End Cylinders Size Id Type
hda.img1 * 1 261 261 2G 6 FAT16
hda.img2 262 1024 764 5.8G 5 Extended
hda.img5 262 522 261 2G 6 FAT16
hda.img6 523 783 261 2G 6 FAT16
hda.img7 784 1024 241 1.8G 6 FAT16
Yet, upon the very next reboot, MS-DOS will either hang or run into a "divide
overflow" error.
This problem can be worked around: if MS-DOS setup is re-run from the floppy
disks, D:, E:, and F: drives can be formatted during the setup process,
and MS-DOS reinstalled. A run of scandisk
will be required, as some or all
logical drives will have missing FAT backup copies and/or lost clusters.
Still, such a multi-partition disk image will be impossible to correctly mount as a Linux loop device:
If you have VirtualBox installed, the disk image can be converted to the VHD format:
vbox-img convert --srcformat=RAW --srcfilename=hda.img --dstformat=VHD --dstfilename=hda.vhd
If the VHD image is attached to a Hyper-V virtual machine running Linux, fdisk
will show exactly the same geometry:
Running dosfsck
against /dev/sda1
will report bad file name errors,
consistently with the mounted FAT16 file system view:
Still, after all file system errors are fixed, an attempt to boot MS-DOS from the disk image will hang:
At the same time, if the above VHD image is converted back to RAW and
re-attached to DOSBox, MS-DOS boots just fine,
and scandisk
reports no further errors.
Yet, it may be more practical to use a 2 GB disk image (C/H/S = 261/255/63)
and create just a single FAT16 partition:
dd if=/dev/zero of=path/to/hda.img bs=512 count=4192965
The image file may be later mounted as a loop device (assuming codepage 866 is
compiled into the kernel, modprobe nls_cp866
):
sudo mount -t vfat -o loop,offset=32256,codepage=866,iocharset=utf8,fmask=133,uid=$(id -u),gid=$(id -g) path/to/hda.img mountpoint/
By default, DOSBox emulates S3 Trio64 (86C764) video card, but Windows 3.x
drivers for S3 Trio64V+ (86C765) or Trio64 V2 (86C775 or 86C785)
work just as well (you need a package containing s3trio.drv
).
The driver package from S3 replaces some of the bitmap fonts (*.fon
) files
shipped with a localized (e.g.: Russian) version of Windows 3.x.
This messes up Cyrillic fonts.
Be sure to back up your *.fon
files immediately after Windows installation,
and restore the fonts once you've installed S3 video drivers.
- VBE 2.0.
-
vbetest.exe
runs. -
uvconfig.exe
lists S3 Trio64 family among the supported chipsets, but doesn’t detect it (univbe.exe
unusable).
Version 0.82.0,
installed from Homebrew (Linux),
has problems unlocking the mouse via Ctrl+F10
.
This doesn’t depend on the window manager,
or the driver used (mouse.sys
vs ctmouse.exe
),
or whether the mouse is connected via a COM port, or via PS/2.
Under certain X11 servers (Xvnc, Xnest, XWin,
VcXsrv), the mouse pointer immediately
slides to the bottom-right corner of the window, and setting/clearing
SDL_MOUSE_RELATIVE
flag has no effect.
- VBE 2.0 (upgradeable to 3.0 via UniVBE).
-
vbetest.exe
runs. -
uvconfig.exe
completes successfully. -
univbe.exe
can be loaded as a TSR.
Bochs doesn’t support disk images with 255 heads (its limit is 16 heads maximum). This means that the largest disk image size Bochs can handle when using CHS geometry is 504 MB.
When started with a larger disk image, it prints:
00000000000p[SIM ] >>PANIC<< numerical parameter 'heads' was set to 255, which is out of range 0 to 16
00000000000e[SIM ] notify called, but no bxevent_callback function is registered
00000000000e[SIM ] notify called, but no bxevent_callback function is registered
========================================================================
Bochs is exiting with the following message:
[SIM ] numerical parameter 'heads' was set to 255, which is out of range 0 to 16
If the CHS disk geometry is specified as 16320/16/63, Bochs indeed translates it to 1024/255/63:
00000840362i[BIOS ] ata0-0: PCHS=16320/16/63 translation=lba LCHS=1024/255/63
Under certain X11 servers (Xvnc, Xnest, XWin, VcXsrv), mouse is unusable.
The default VGA ROM image (vgaromimage: file=/usr/share/vgabios/vgabios-stdvga.bin
):
- VBE 2.0 (reported).
-
vbetest.exe
crashes and hangs the OS (even afterunivbe.exe
is loaded). - Other tests of VESA capabilities (
astra.exe
,hwinfo.exe
) hang. -
uvconfig.exe
completes successfully when run for the 2nd time (detects WinBond W9970CF PCI with 1 MB, can handle 800x600x16bpp). -
univbe.exe
can be loaded as a TSR.
The alternative VGA ROM image from SeaBIOS
(vgaromimage: file=/usr/share/seabios/vgabios-stdvga.bin
):
- VBE 3.0.
-
vbetest.exe
crashes and hangs the OS. -
uvconfig.exe
terminates with an "out of memory" message. - Both
hwinfo.exe
andnssi.exe
report a 256 kB VGA card with a VESA 3.0 implementation by SeaBIOS.
Since the amount of video memory is ridiculously small, it is better to proceed with the Cirrus option.
- Cirrus Logic CL-GD5430 with 2 MB of video RAM.
- VBE 2.0.
- Windows 3.x successfully runs with a VESA driver (unless
univbe.exe
is loaded). -
uvconfig.exe
successfully detects Cirrus Logic CL-GD5430 with 2 MB (when run for the 2nd time). -
univbe.exe
can be loaded as a TSR. -
vbetest.exe
crashes and hangs the OS (regardless of whetherunivbe.exe
is loaded or not).
VGABIOS |
---|
![]() |
![]() |
QEMU boots from a raw disk image just fine:
$ qemu-system-i386 -hda hda.img
$ qemu-system-i386 -drive if=ide,file=hda.img,index=0,media=disk,format=raw
In both cases, however, QEMU will assume the number of heads to be 16, effectively lowering the CHS-addressable hard drive size limit to 504 MB, similarly to Bochs.
It is possible to manually specify the CHS geometry via a separate -device
option, but QEMU exhibits the same head limit of 16:
$ qemu-system-i386 \
> -drive if=none,id=hda,file=hda.img,index=0,media=disk,format=raw \
> -device ide-hd,drive=hda,cyls=1024,heads=255,secs=63
qemu-system-i386: -device ide-hd,drive=hda,cyls=1024,heads=255,secs=63: heads must be between 1 and 16
This is because DOSBox and its descendants emulate the BIOS interface, which supports up to 255 heads. Bochs and QEMU emulate the hardware, specifically an ATA interface, and ATA only supports 16 heads.
The discrepancy is supposed to be handled in the BIOS (same as on a real system). For that to happen, one needs to specify a number of cylinders greater than 1024 (16 320 in our case); then the BIOS will increase the number of heads to bring the number of cylinders below 1024 (as supported by the BIOS interface).
See this discussion for reference.
The correct QEMU command line would then be:
qemu-system-i386 \
-drive if=none,id=hda,file=hda.img,index=0,media=disk,format=raw \
-device ide-hd,drive=hda,cyls=16320,heads=16,secs=63
QEMU, among other video cards, can emulate the following:
- Standard VGA with Bochs VBE extensions (
-vga std
, the default) - Cirrus Logic CL-GD5446 (
-vga cirrus
) - VMWare SVGA-II (
-vga vmware
)
In all the above cases, VESA support is provided by SeaBIOS:
- VBE 3.0.
-
vbetest.exe
runs. -
uvconfig.exe
doesn't detect any supported SuperVGA chip (univbe.exe
unusable).
Additionally, in case CL-GD5446 is used, VESA implementation can be replaced with that of UniVBE.
SeaBIOS | UniVBE |
---|---|
![]() |
![]() |
![]() |
![]() |
QEMU version 7.2+dfsg-7+deb12u3, included with Debian Linux 12, has issues
emulating VESA (vbetest.exe
from UniVBE hangs).
Upgrading to 7.2+dfsg-7+deb12u12 results in vbetest.exe
finally running,
but QEMU may now crash with the following messages:
ERROR:../../accel/tcg/tcg-accel-ops.c:81:tcg_handle_interrupt: assertion failed: (qemu_mutex_iothread_locked())
Bail out! ERROR:../../accel/tcg/tcg-accel-ops.c:81:tcg_handle_interrupt: assertion failed: (qemu_mutex_iothread_locked())
In version 9.2.2 (9.2.2+ds-1~bpo12+1), vbetest.exe
switches to the
desired VESA mode but eventually hangs.
In all cases, quake.exe
with any VESA video mode (640x480 and higher) crashes
with message:
Unable: Unable to load VESA palette
Initially, a reasonable config.sys
might look like this:
device=c:\windows\himem.sys /testmem:off /verbose
dos=high,umb
device=c:\dos\emm386.exe min=0 noems novcpi verbose highscan
buffers=15,0
fcbs=4,0
files=40
lastdrive=Z
stacks=9,256
switches=/F
devicehigh=c:\dos\setver.exe
country=007,,c:\dos\country.sys
devicehigh=c:\dos\display.sys con=(EGA,866,1)
installhigh=c:\dos\nlsfunc.exe c:\dos\country.sys
devicehigh=c:\dos\ramdrive.sys 8192 512 1024 /E
devicehigh=c:\dos\ansi.sys
Note, however, that himem.sys
alone retains the CPU in Real Mode,
while emm386.exe
, even with EMS disabled (noems novcpi
), switches to
Virtual 8086 Mode,
which may cause compatibility issues with certain software.
autoexec.bat
:
@echo off
prompt $p$g
path c:\dos
set TEMP=c:\tmp
loadhigh c:\windows\smartdrv.exe /X /V
mode con codepage prepare=((866) c:\dos\ega.cpi)
mode con codepage select=866
chcp 866
loadhigh keyb ru,866,c:\dos\keyboard.sys
loadhigh c:\dos\doskey /insert
After memmaker
runs, it adds /L
(and, sometimes, /S
) arguments to
devicehigh
, installhigh
, and loadhigh
commands.
Note, however, that I=...
and X=...
switches of EMM386
are not portable
(hardware-dependent).
config.sys
:
device=c:\dos\emm386.exe min=0 noems novcpi verbose highscan I=B000-B7FF X=C800-C9FF
devicehigh /L:1,12048 =c:\dos\setver.exe
devicehigh /L:1,15792 =c:\dos\display.sys con=(EGA,866,1)
devicehigh /L:1,5888 =c:\dos\ramdrive.sys 8192 512 1024 /E
devicehigh /L:1,9072 =c:\dos\ansi.sys
autoexec.bat
:
loadhigh /L:0;2,45456 /S c:\windows\smartdrv.exe /X /V
loadhigh /L:2,16208 keyb ru,866,c:\dos\keyboard.sys
loadhigh /L:1,6384 c:\dos\doskey /insert
Now, since loadhigh
directives in autoexec.bat
can be mirrored with
installhigh
in config.sys
, it's possible to move most of the autoexec.bat
content (except for built-in shell interpreter commands) to config.sys
.
If the goal is to minimize the number of drivers loaded
(either for compatibility reasons or to conserve conventional memory), then the
reduced version of config.sys
might look like this:
device=c:\windows\himem.sys /testmem:off /verbose
dos=high
buffers=15,0
fcbs=4,0
files=40
lastdrive=Z
stacks=9,256
switches=/F
set prompt=$p$g
set temp=c:\tmp
set comspec=c:\dos\command.com
set path=c:\dos;c:\windows
shell=c:\dos\command.com /P
country=007,866,c:\dos\country.sys
devicehigh=c:\dos\display.sys con=(EGA,866,1)
devicehigh=c:\windows\ifshlp.sys
installhigh=c:\dos\mode.com con codepage prepare=((866) c:\dos\ega.cpi)
installhigh=c:\dos\mode.com con codepage select=866
installhigh=c:\windows\smartdrv.exe /X /V
The above will both select the console code page and install the console font, so that non-ASCII characters are displayed correctly, and Windows no longer complains about missing code page on start.
Neither nlsfunc
nor keyb
are necessary for correct DOS and Windows
operation, so one may consider moving them to a separate config.sys
entry:
installhigh=c:\dos\nlsfunc.exe c:\dos\country.sys
installhigh=c:\dos\keyb.com ru,866,c:\dos\keyboard.sys
Yet, if one wants to be able to switch the active codepage via
chcp
(e.g.: chcp 866
), it is better to have nlsfunc
loaded.
A structured config.sys
example can be found at this link.
- Файл EMM386.EXE
- Setting Up an "EMS" Configuration with EMM386
- Setting Up a "No EMS" Configuration with EMM386
- The Importance of EMM386
Virtual 8086 mode is a sub-mode of Protected mode. In short, Virtual 8086 mode is whereby the CPU (in protected mode) is running an "Emulated" 16bit Real Mode machine.
- DOS/4GW and Protected Mode
- HX DOS Extender is a free DOS extender with built-in Win32 PE file format support. Usually the purpose of a DOS extender is to make protected-mode features available for DOS applications. HX fully supports this goal, but goes some steps further. A Win32 API emulation layer is part of HX which allows many Win32 console applications to run in DOS. This emulation goes far beyond similiar approaches in other extenders (Borland's PowerPack, WDOSX or Phar Lab TNT). Furthermore HX implements - limited - support for windows, DirectDraw, GDI and even OpenGL graphics. This allows to run "simple" Win32 GUI apps in DOS as well.