Showing posts with label DOSBox. Show all posts
Showing posts with label DOSBox. Show all posts

Sunday, February 16, 2014

Patching DOSBox by a Beginner for Beginners

In order to apply a patch to DOSBox, you must first be able to compile DOSBox from its source.  Start with this tutorial :

http://www.dosbox.com/wiki/Building_DOSBox_with_Visual_C_2008_Express

The link for Visual C++ 2008 Express given in that tutorial is out of date, you can obtain the downloader from here :

http://go.microsoft.com/?linkid=7729279

When you can compile a binary using the current SVN, then you are ready to begin patching DOSBox.

Patching DOSBox means you are making changes in the existing source code and recompiling DOSBox with those changes into a new binary.  First you need a copy of the source code you are modifying.  DOSBox is written in C++ and the source code is in almost plain text.  You can find the latest source here : http://source.dosbox.com/dosboxsvn.tgz.  Decompress it with a program like 7zip (it is doubly compressed), and look at the files.  The .cpp files contain most of the code you may be modifying.  

Next you need a good text editor, preferably one that supports line numbers.  Notepad just does not support enough of the formatting these files need.  Wordpad does, but you would do better with an editor like EditPad Lite 7, which supports line numbering.  Line numbering is very useful to determine which lines of code you need to modify.  

Finally, you need a patch file.  Patch files often use the .diff extension because they show the differences between two files or two sets of files.  If the patch is just code posted in a forum, you should copy and paste it into a new file opened in Wordpad or EditPad or something similar.  Maintaining the spacing in these files is important.  

Here is a sample patch file against the current DOSBox SVN (r3858) :  

--- adlib.cpp.old   2013-01-15 12:10:04 +0000
+++ adlib.cpp   2014-01-19 19:54:06 +0000
@@ -227,10 +227,10 @@
       Bitu i, val;
       /* Check the registers to add */
       for (i=0;i<256 font="" i="">
-         //Skip the note on entries
-         if (i>=0xb0 && i<=0xb8) 
-            continue;
          val = (*cache)[ i ];
+         //Silence the note on entries
+         if (i>=0xb0 && i<=0xb8) 
+            val &= ~0x20;
          if (val) {
             AddWrite( i, val );
          }

The first two lines identify the source file that was modified, in this case adlib.cpp.  Find and open adlib.cpp using your text editor in the DOSBox source directory.  It can be found in \dosbox\src\hardware.  This is what the existing source code looks like :

Bitu i, val;
/* Check the registers to add */
for (i=0;i<256 font="" i="">
//Skip the note on entries
if (i>=0xb0 && i<=0xb8) 
continue;
val = (*cache)[ i ];
if (val) {
AddWrite( i, val );
}

The next line in the patch file, @@ -227,10 +227,10 @@ pinpoints the lines in adlib.cpp that were modified.  Look for line 227 in the source code file or search   Sometimes, depending on the patcher's working source, the line number may not line up exactly with the DOSBox source, but it should be very close to the line.  Sometimes code looks similar, if you are unsure whether you have the right code, then copy as much of the code from the patch file as you can into a find box and search the source code file until you are sure you have the right lines.  

The lines with blank space in front of them show the existing code that will not be modified.  This is important to know where you will begin to modify and where you will end.  Lines beginning a - indicate that that line was deleted by the patch.  Conversely, lines beginning with a + indicate that that line was added by the patch.  From our example above, these lines were deleted : 

-         //Skip the note on entries
-         if (i>=0xb0 && i<=0xb8) 
-            continue;

In the original source file, highlight and delete them.  Remove the lines entirely so the code looks like this :

       Bitu i, val;
       /* Check the registers to add */
       for (i=0;i<256 font="" i="">
          val = (*cache)[ i ];

Now add these lines after val = (*cache)[ i ]; :

          //Silence the note on entries
          if (i>=0xb0 && i<=0xb8) 
             val &= ~0x20;

Copying and pasting usually gives better results than retyping.  Make sure the code fits where it is indicated and does not overwrite any lines without a - in front of them.  Also make sure, since your text editor must be using a fixed-width font, that the lines line up vertically as shown in the patch.  Do not forget the { and }.  The + characters also should be removed, and add an extra space to the line to preserve the code's position on the line.  Here is the code as it should look in the patched adlib.cpp file :

       Bitu i, val;
       /* Check the registers to add */
       for (i=0;i<256 font="" i="">
          val = (*cache)[ i ];
          //Silence the note on entries
          if (i>=0xb0 && i<=0xb8) 
             val &= ~0x20;
          if (val) {
             AddWrite( i, val );
          }

Once you are done, save the modified .cpp file.  There may be more than one place in the .cpp file to patch, so go to the next line indicator, which looks like @@ -227,10 +227,10 @@ and continue patching. .diff files can include more than one source code file to patch, so make sure you patch all source code files indicated by the .diff.  

Go back into Visual C++ 2008 Express Edition, open the DOSBox solution, and build a new binary.  If you have previously built a binary, then it will not take long as only the changes made by the patch need to be recompiled.  

While there are utilities that can do this for you, I have never gotten one to work properly and sometimes the line numbers do not match and you need to manually patch the code.  

More complex patches may require substantial modifications to the code, or may also require adding completely new code files.  They may also require new libraries and includes files, which are beyond the scope of this tutorial.  

Friday, December 13, 2013

Tutorial - DOSBox and Floppy Disk Game Installation

Usually I do not write specifically about DOSBox because my main interest is real hardware, but DOSBox is an invaluable tool for anyone into retro-PC DOS gaming.  DOSBox can play just about any DOS game, and can certainly play all the widely-known classic games.  One of its lesser-acknowledged strengths is its ability to install games from floppy disks, or more usually, from floppy disk images.  In this entry I will describe the ways DOSBox can install games off floppy "disks".

If you have floppy disks, your first task should be to make floppy disk images.  Of course, you can mount a physical floppy disk drive directly with DOSBox, but relatively few people have floppy drives connected to modern systems these days.  Floppy disks should be preserved, so I would always first image the disk, then install it.

A program like Winimage works for unprotected DOS-readable floppy disks, and the resulting image files have a .ima extension.  On older hardware, I use a free program called img2dsk.  If you read original floppy disks in a Windows machine, you should enable write protection on the disks otherwise Windows will make (usually harmless) changes to the first sector of a disk.  Winimage and other simple disk imaging utilities only understands what DOS understands, so you will not be able to make useful backup copies of any game with disk-based floppy protection.  Fortunately, this is almost never a problem with games that were released on high density floppy disks, since no game (except for Lemmings 2 : The Tribes) released on high density floppies is known to use disk based protection.  Hopefully the images will not contained damaged files, but a disk imaging program should be able to report any errors.

Always dump a disk to its right size.  Regular disk images are sector dumps and will dump all the formatted sectors on a disk, whether there is anything in the sectors or not.  Remember that 5.25" double density disks have a hub ring and a rust brown color to the recording media while 5.25" high density disks have no hub ring and a shiny black finish on the recording media.  3.5" double density disks only have a hole on one side of the disk while 3.5" high density disks have a hole on either side of the disk.  The size of the files should be able to tell you what kind of disk is being used.  160K, 180K and 320K disks are usually copy protected.

If you do not have floppy disks or images, it is much harder to find them than "full" installs of games.  Disk images are generally unadulterated, they have not been cracked and can be used to install alternative features to the standard installed versions found everywhere else.  Some games like Wing Commander require a reinstall off the disks to select Tandy or EGA graphics when the standard install or CDs with the game just have a VGA-only installation.

Now that you have some images of your floppy disk install disks, you need to mount them so DOSBox can find them.  There are three ways you can do this.  First, in Windows you can use a program like Virtual Floppy Drive 2.1, which will mount a DOS-formatted disk image of any regular size and emulate one to two floppy drives.  If A:\ is your emulated drive, in DOSBox, you would use mount a a:\ -t floppy.  The benefit to this method is that you can load new floppy disks just by double clicking on them once Windows associates the .ima extension with VFD.  The author of VFD 2.1 doesn't like Windows Vista or 7 or 64-bit Operating Systems, but other users have found way around the program's limitations. There are workarounds, namely signed 64-bit drivers for VFD.   The answers can be found here : http://superuser.com/questions/183335/how-to-create-a-virtual-floppy-drive

If you cannot or will not use VFD or another program like it, DOSBox can mount floppy images directly, but it is a complex process, at least in the official 0.74 version.  If using the latest or recent SVN, the process is much easier.  http://www.emucr.com/ has good basic builds of the current SVN, so let's start with the SVN method. The IMGMOUNT command in SVN supports multiple floppy images, just like it does with CD images in 0.74.  DOSBox, however, does not mount files that do not conform to the 8.3 filename convention, so lengthy descriptive filenames will need to be condensed into disk1.ima, disk2.ima and so on.  Here is a sample mounting command in the [autoexec] section of dosbox.conf :

imgmount a c:\dos\images\disk1.ima c:\dos\images\disk2.ima -t floppy

Images can use an IMG or IMA extension, but each image file must have the full path on the line for it to be recognized.  It does get kind of tedious with a game like Discworld, which came on 15 disks (versus one CD-ROM).  With this method, you can install a game to an ordinary mounted folder.

Some games have installers that do not work with DOSBox's DOS, but will work with MS-DOS.  Dynamix games just don't like DOSBox when it comes to floppy installs.  DOSBox emulates enough PC hardware that you can use it as a virtual machine for MS-DOS or PC-DOS.  I generally see no need to use DOSBox as a virtual MS-DOS machine because getting EMM386 to work is tricky and MSCDEX needs ATAPI emulation not found in the standard SVN.  But for those tricky floppy installation programs, it can be very useful and certainly beats using real hardware and copying floppy drive images to back to real blankdisks.

You will need a hard drive image, and you can make your own with a program called BXIMAGE or  download one from here : https://sites.google.com/site/dotalshoff/games/dosbox  I would not use a disk image size of more than 528,482,304 bytes because you cannot easily make it bootable with DOSBox.  This is not coincidentally the old 520/504MB limit caused by the lowest common denominator between Int 13 and ATA/IDE hard drive size support.  You will also need floppy images for a version of MS-DOS or PC-DOS.  5.0 is the minimum version I recommend, but MS-DOS 6.22 is the most up to date version of pure DOS commonly used.  If you use MS-DOS 6.x, you should install the utilities off the Supplemental Utilities Disk, as they contain some utilities used in some weird game installs that were previously included in DOS 5.0.  Floppy images can be found if you look hard enough.  I do NOT recommend using FreeDOS, since many game installers rely on quirks of MS-DOS that have not been emulated well with FreeDOS.

Assume your hard drive image is named hdd-520mb.img and your MS-DOS 6.22 floppy images are msdosd1.img, msdosd2.img and msdosd3.img.  Here is how your dosbox.conf should look :

imgmount c c:\dos\images\hdd-520mb.img
boot c:\dos\images\msdosd1.img c:\dos\images\msdosd2.img c:\dos\images\msdosd3.img

Note that with the BOOT command, the extension must be .IMG, .IMA will not work.  The file hdd-520mb.img is already partitioned and formatted, so you need not use FDISK and FORMAT to prepare the image file.  Just use the install program or use the SYS command to make the drive bootable and copy all the commands over to c:\dos in DOSBox.  Ctrl + F4 will switch the active disk image.

Ordinary disk images cannot be booted, so you will need an MS-DOS boot disk with the version installed on the hard drive to start the process.  With the boot disk named msdosbd.img, The [autoexec] section may look like this :

imgmount c c:\dos\images\hdd-520mb.img
boot c:\dos\images\msdosbt.img c:\dos\images\disk1.img c:\dos\images\disk2.img

After the boot disk boots, use Ctrl + F4 to switch to the first game disk image and install away.

BOOT should be the last command in the section.  In order to transfer the installed files from the hard disk image to a regular mounted hard drive using a folder on your real hard drive, start with lines like these in your [autoexec] section :

ver set 6 22
imgmount c c:\dos\images\hdd-520mb.img
mount d c:\dos\games

The VER set command will allow you to use MS-DOS 6.22's XCOPY command to copy whole directories from the hard drive disk image to your mounted real folder.  Regular DOSBox does not have an XCOPY command, so with regular DOSBox you will need to manually recreate the directory and subdirectory structure with the md command.  With XCOPY, use the /E switch to copy over subdirectories.

One remaining issue is that you cannot IMGMOUNT floppy images and BOOT to a hard drive image at the same time.  You need to BOOT the MS-DOS boot disk and the disks you wish to install.  The hard drive image becomes a receptacle to hold the installed files, which you can transfer later.