Pages

Showing posts with label Tutorial. Show all posts
Showing posts with label Tutorial. Show all posts

Wednesday, July 4, 2012

Tutorial - ArduinoISP Duemilanove with Optiboot

Hey everyone,

This will be technically a few tutorials in one as I intend to not only teach you how to interface two Arduino's together for In-System-Programming but also how to upgrade and change the firmware built in (so it will probably turn out much longer than my Dosbox VGA Tutorial). This method does require a second Arduino board to act as our ISP Programmer but there is another method called Bit-Banging where you connect the 4 pins called the X3 header on the Duemilanove, usually located next to the FTDI chip and hook them to the ICSP pins on the same Arduino, since I won't be using that method in this tutorial feel free to check out this tutorial instead if you only have a single Arduino on hand. I may append the Bit-Bang method to this tutorial or make a new one in the future now that I have the necessary connectors on hand to do it but for now the link will suffice.

I remember reading somewhere on the internet about the overhead of having a boot-loader on your Arduino vs direct upload of a compiled program. The convenience of a boot loader is that it allows you to upload sketches to your Arduino using a USB serial interface while the only down side is less memory for your uploaded project due to the memory requirements of the boot-loader and a delayed start up time for the Arduino. The newer version of the Arduino called UNO comes with a much smaller and faster boot-loader called Optiboot which gives back around 1.5kb's of memory for your projects. Later on I'll teach you how to upgrade your older Diecimila or Duemilanove with this new boot-loader.

The First Part of this tutorial is to teach you how to connect an Arduino to another Arduino by using the In-System-Programming method or ISP for short. One of the Arduino's will be your programmer while the other is the slave that you will be modifying the firmware on. When I first learned how to do this I was using my Arduino Mega 1280 to reprogram my Arduino Duemilanove to both upload raw sketches without a boot loader as well as successfully install the Optiboot loader. After I had worked out all the kinks and solved some problems I decided that it might be beneficial to share my experience and teach others how to use this method too. At first I just had floating wires everywhere connecting the two together but I spent a good afternoon constructing a proper cable that is much more stable for connecting them which you can see here:

















For the time being you can simply connect everything with wires for this tutorial but feel free to use hook up wires with pins if you have any or even make your own cable. I didn't have any header pins available when I made this so I just used pieces of solid wire I cut from a spool which needed a little sanding to remove the outer cover since solder wasn't sticking to it. Depending on what Arduino you use changes which pins we will be using to connect the programmer to your slave board. The 4 main pins that we will be using are listed here:

Master-In-Slave-Out (MISO) = Pin 12 on Duemilanove and Pin 50 for Mega
Master-Out-Slave-In (MOSI) = Pin 11 on Duemilanove and Pin 51 for Mega
Serial Clock (SCK) = Pin 13 on Duemilanove and Pin 52 for Mega
Slave Select (SS) = Pin 10 on Duemilanove and Pin 53 for Mega

If your chosen programmer board is a Diecimila or Duemilanove then connect the wires like this: Connect Pin 10 of the programmer to the reset pin of your slave, connect Pin 11 to Pin 11 of your slave, connect Pin 12 to Pin 12 on your slave and then lastly connect Pin 13 to Pin 13 on your slave.

If your chosen programmer board is an Arduino Mega then connect the wires like this: Connect pin 53 to the reset pin of your slave, connect Pin 52 to Pin 13 of your slave, connect Pin 51 to Pin 11 of your slave and lastly connect Pin 50 to Pin 12 of your slave.

Feel free to check out this link if you need more help connecting them.

What we have done is connect the two boards together using the Serial Peripheral Interface (SPI). Since only the programmer will be connected to the computer we will need to make sure your slave has access to power as well. To do this simply connect a wire from the 5v pin of your programmer's power rail to your slave's 5v pin and another wire connecting your programmer's Ground pin to your slave's Ground pin.

Technically you could program any number of different Arduinos with this system; just look up the hardware page and find the 4 pins needed for SPI interfacing.



The Second Part will involve uploading a project called ArduinoISP (which comes with the Arduino software) to your programmer board which will allow us to reprogram another board connected through the SPI system. First you'll need to make sure you have installed the programming IDE for Arduino which you can download from here. Simply choose the correct version for the operating system you have then download and install it. Once it's installed open up the program and on the top menu click File, then mouse over Examples and finally click on the ArduinoISP project which will open up an instance of the code. Now attach your desired programmer board to the computer, click on Tools and open up boards, select the board you wish to use as your programmer; in my case I chose "Arduino Mega (ATmega1280)". Go back to tools and select the Port your programmer is attached to. Finally you can click the upload button at the top that looks like an arrow pointing right which will upload the ArduinoISP project onto your programmer.

Now you might have noticed that I have an LED display on my cable. This is related to the ArduinoISP software which uses Pin 7 to indicate that it's programming, Pin 8 to report any errors and Pin 9 which is the heartbeat that pulses to indicate that everything is good; this information can be found in the top comments section of the project code. Feel free to add these LED's to your setup so that you can know when things are working properly or have failed somewhere. If you are new to connecting LED's to Arduino's then I recommend this great tutorial by Lady Ada.

Awesome, now that we have your programmer board all set up and connected to the slave board that we wish to reprogram, we now need a way of uploading your new boot-loader to it. A good way of testing your programmer board is to burn the default boot-loader onto your slave board. To do this, make sure that the programmer is attached to your computer and that both boards have power. Open up the Arduino programming IDE that we recently installed, then under the Tools select the board that is your slave; in my case I selected "Arduino Duemilanove /w ATmega328". Then in the Tools menu go to Programmer, then select "Arduino as ISP", once that's selected go back to Tools and click on "Burn Bootloader" and you should see your programmer board upload the boot-loader to your slave board with the default blink sketch blinking the led on Pin 13; just like when you first bought the board from a reseller.

Alright, now that we can upload to your slave board successfully using your programmer there's lot of things we can try out. I'll show you how to upload your sketches without the need for a boot-loader as well as upgrading your older Arduino's with the latest Optiboot loader. To do this we will be using a program called AVRDude which comes with WinAVR. You can download the latest version from its source forge page here then install it. WinAVR's installer will register the AVRDude executable with Windows so it can be accessed via command prompt. You can access the command prompt in Windows a myriad of ways. I usually just press the Windows key and type "cmd" or "powershell" and hit enter in Windows 7 but for this tutorial I'll be using the power-shell as my preferred terminal. Alternatively you can open the command prompt via the start menu and click on run, then type "cmd" or "powershell" and hit enter. You can even shift + right click in any folder or on the desktop then click the new "Open command window here" option that appears. Once you have your terminal open type "avrdude" and hit enter, you should see a list of available options listed like I show here:

Command terminals on Windows default the starting location to the user's folder unless you used the "Open command window here" method which will inherit the folder you right clicked in. If this is the case then simply type "cd.." and hit enter, do this again and again until you are at the root drive and only see "C:\" in the command window. Here's an example:


This is simply to make uploading a Hex file to your board much easier since you would need to specify the directory that contains your file in full for AVRDude. Feel free to use a folder structure though if you prefer but since your project files are so small it's easy to use the root drive as a temporary folder for uploading. Hex files are the end result of a compile with the Arduino IDE and are encoded in Intel assembly; to learn more about the Arduino build process you can check out this link. In older versions of the IDE you could find the Hex file in your project's directory but the later versions now store the compiled code temporarily in the Windows temp folder which is hidden from the user by default located here:

C:\Users\USER_NAME_HERE\AppData\Local\Temp

This folder is specific to which operating system you are using, in my case I have Windows 7 but if you have a different OS then you can find where the IDE compiles to by initialising verbosity mode. Go to the top menu and click File then Preferences and in the preferences window you should see "Show verbose output during:". Select compile or both if you prefer then hit ok. Now when you click the Verify button you should see where the IDE is compiling the code to.

Lets prepare a project to upload to your slave board without a boot-loader installed. I like the blink project as it give you feedback of a successful upload via the blinking LED. With the Arduino IDE open, go to the top menu and click on "File" then go to Examples/01.Basics and click on Blink. You should now have a Blink project open, since we need the code compiled into a Hex file but we don't want the code uploaded to the board just yet, you can click on the Verify button (looks like a tick) which will compile your code and check for errors but it won't upload the code to the board which can be very useful. While the IDE is open and you have compiled your code, the Hex file can be found in the Temp folder I showed previously; projects in this folder usually start with the name "build" with a series of unique numbers like this "build1544573883262332201.tmp" and inside this folder will be your Hex file and in my case it was called "Blink.cpp.hex". Remember that your Hex file will usually be deleted the moment you close the IDE along with the temporary folder so it's best to find your Hex file and copy / paste it into your C:\ drive for uploading, feel free to rename it to whatever you like; for example: "Blink.hex".

Uploading Raw Sketches

Before we begin the upload, if you are worried about the fact that we will no longer have a boot-loader on the board, remember that you always have the "Burn Bootloader" option at your disposal in the Arduino IDE under Tools; this uploads the default boot-loader that comes with the board you have selected as your slave. Additionally if you go back to the default boot-loader and wish to upload projects to it like normal without a programming board, remember to change the IDE's programmer under Tools back to "AVRISP_II" and set the Board and Serial Port respectfully for the board you plan to upload to.

Alright, now that we have successfully compiled a project and have our Hex file ready to go I can now teach you how to use AVRDude to upload it to your slave board. There's a number of parameters that we will need to pass to AVRDude in order to upload our sketch to the board, this will include the method we are using to upload with, the baud rate, what chip we are programming and where the sketch will be stored etc. Make sure you have a command prompt open and set to your C:\ drive like I showed above.

The First Parameter will be our uploading method; there's numerous options which you can see a full list of if you type "avrdude -c randomtext" since random text isn't an available option, AVRDude will list all the possible upload methods supported. Take note of the last option in the list called "Arduino" which means that an Arduino would be used for our programming method which is perfect for us since we are using one as an ISP programmer. Now that we know which programmer to use, lets move on to the next parameter.

The Second Parameter will be the chip we plan to upload to, if you type "avrdude -c arduino" and hit enter, AVRDude will display a list of supported micro controllers which can be specified with "-p" and then the name of the chip we are programming. If you are unsure of the chip on your board you can check out the Hardware page for your board at the Arduino website which will show the technical specifications that indicates what chip is used. In my case I was using an Arduino Duemilanove with an ATmega328 chip so I would choose "m328p" from the list.

The Third Parameter will be the name of our port that the Arduino programmer is attached to. The best way I find to work this out is to simply reference where the Arduino IDE says in "Tools/Serial Port". Alternatively you can go to your Device Manager and under "Ports (COM & LPT)" you should see a device listed with the port that it uses. You can pass a port to AVRDude by using the "-P" command and typing the port's name after that; in my case it was "-P com3".

The Fourth Parameter will be our desired baud rate which is how fast we will be sending data to our programmer. Since we are going to be using the ISP system we must use "19200" as our overriding baud rate which you can pass to AVRDude with the "-b" command. If this command is not passed you may receive issues with syncing the programmer board.

The Fifth Parameter will specify where in the micro controller's memory that the sketch will be uploaded to; in this case we will be using flash, additionally we will also specify that we wish to write to the memory which is specified with "w" between the colons. You use the "-U" command and then pass "flash:w:" then write the name of your Hex file "Blink.hex", in my case I wrote "-U flash:w:Blink.hex".

The whole command should look like this:
Once you've typed that in, hit enter and if everything goes well, you should see AVRDude uploading the Hex file to the board and verifying that everything was uploaded correctly as you can see here:



And now you should see your Arduino slave board blinking away, since there's no longer a boot loader on the Arduino if you reset the board you'll noticed almost no delay before the code starts again which can be extremely useful for projects that need as much up time as possible during self resets. Another useful feature of not using a boot-loader is that you have a lot more room for large sketches / projects.

Uploading Optiboot

Cool, now that we have successfully uploaded a raw Hex file to our board I'll now show you how to upload the more up to date boot-loader called Optiboot. Optiboot actually comes with your Arduino's IDE software; simply go to the folder you have placed the software in and go to this location:

(Arduino Installation Folder)\hardware\arduino\bootloaders\optiboot

And you should see a Hex file called "optiboot_atmega328.hex", copy and paste this file to your "C:\" drive so we can upload it to our slave board like before. The boot-loaders folder that we just went inside contains the Hex files that the Arduino IDE literally uploads to the board when you click on "Burn Bootloader". The association for each board's default boot-loader is defined inside the "boards.txt" file in the "hardware\arduino" folder, which I'll be talking about more in the bonus tutorial below.

Now inside your command prompt that was used to upload the Blink sketch, we will now upload the Optiboot Hex file. To do this, type exactly what was typed before but change "Blink.hex" to the name of the Optiboot Hex file "optiboot_atmega328.hex" then hit enter. This will take a few seconds longer to upload to the slave board than the Blink sketch since it is much larger file and just like before you should see this:
























The majority of the time that is taken for AVRDude is verifying every bit that was uploaded to your slave board, if you are confident in AVRDude's ability to upload without fault then feel free to pass the "-V" command which will omit the verification process and finalise the upload much quicker.

You should now have an Arduino Duemilanove with the latest Optiboot loader installed :) please note that this new boot-loader has a faster upload allowance and that you won't be able to upload your code using the Arduino IDE with Duemilanove set as your board. Additionally you shouldn't worry if the light is not blinking this time since the new boot-loader doesn't come with it by default. Duemilanoves use "57600" as their baud rate while the Optiboot loader uses "115200" which is two times faster so if you tried uploading sketches the normal way to your new board you'd receive a sync error. Since the Arduino UNO has the exact same chip and parameters as the Duemilanove, you can use the UNO as your uploading board. If you wish to learn more about how you could create a custom board definition for an Arduino Duemilanove with Optiboot then feel free to continue reading my bonus tutorial which will not only show you how to create a custom board but also introduce you to what fuses are all about.

Bonus Tutorial :)

I decided since this tutorial turned out so huge that another complemetary tutorial couldn't hurt and might be of some interest to a few people.

Since we have physically changed the boot-loader that was once on our Arduino to the new Optiboot that comes with Arduino Uno I thought it might be nice to show you how to add a custom board to the Arduino IDE that can represent an Arduino Duemilanove with Optiboot and allow uploading sketches.

To make a custom board that we can use with our new board, we'll need to modify the "boards.txt" file inside the "hardware\arduino" folder. Since the encoding of the file is extended beyond basic ASCII we will need a proper binary editor; Notepad won't be able to format the text correctly. The one I like to use is called Context which you can download here. There's also an editor called Notepad++ that should work. There are lots of editors out there so feel free to choose the one you like best.

Once you have installed an editor, open the "boards.txt" file inside it and you should see all the definitions of the boards currently supported by the Arduino IDE. We will be extending this list with a custom board definition that you can see here:

##############################################################

Duemilanove.name=Arduino Duemilanove w/ ATmega328 - Optiboot

Duemilanove.upload.protocol=arduino
Duemilanove.upload.maximum_size=32256
Duemilanove.upload.speed=115200

Duemilanove.bootloader.low_fuses=0xFF
Duemilanove.bootloader.high_fuses=0xDE
Duemilanove.bootloader.extended_fuses=0x05
Duemilanove.bootloader.path=optiboot
Duemilanove.bootloader.file=optiboot_atmega328.hex
Duemilanove.bootloader.unlock_bits=0x3F
Duemilanove.bootloader.lock_bits=0x0F

Duemilanove.build.mcu=atmega328p
Duemilanove.build.f_cpu=16000000L
Duemilanove.build.core=arduino
Duemilanove.build.variant=standard

##############################################################

Place this between the "Arduino Uno" definition and the "Arduino Duemilanove w/ ATmega328" one. As you can see there's a few differences from the original Duemilanove definition; there's a larger "maximum_size" that takes into account the new memory given back by the smaller bootloader and the baud rate has been doubled to support our new board for uploading. Additionally for those who are curious, the "bootloader.file=optiboot_atmega328.hex" line is actually what the IDE will consider the default boot-loader to upload to your board if you click the "Burn Bootloader" button while the "bootloader.path" specifies what folder inside the "hardware\arduino\bootloaders" folder that the Hex file exists in.

The name before every line must be unique from every other definition or it will not show up in the Arduino IDE. Since the definition for the original Duemilanove was "atmega328" I decided to call the new one "Duemilanove". If you close all instances of the Arduino IDE and re-open it you'll find the new board definition available which you can use to burn sketches to your hearts content. Just remember to change the programmer back to "AVRISP_II" since we won't need the programmer board now that we have a boot-loader.

Fuses are a bit of a misnomer since they don't have anything to do with protecting against power surges etc. In the microprocessor world fuses are simply switches that can be turned on and off to specify how the board should act. The fuses are non-volatile and will remain set even if you erase the board since they have their own flash memory that they are stored in. A word of caution though, you can damage your arduino beyond repair if these are set incorrectly and won't be able to reprogram it using ISP. The only way to recover a damaged chip is to use a high voltage programmer; here's a good example that's compatible with Arduinos.

Fuses are stored as hex values which if converted to binary will show you which switches are turned on and off. Each letter of the Hex value represents 4 bits and since we have two letters that's 8 bits in total or one byte. I'll give an example of the "0xDE" high fuse value of our board definition:

0xDE
or
11011110

To make life easier we can use a fuse calculator to derive the needed Hex values. The one I like to use is here. Simply choose the chip that you are programming; in my case it's "ATmega328P" then click select. You should see the interface expand showing the default settings that the chip has as a factory default. Further down the screen you can find the Hex values in the "Current Settings" area. Any changes you make to the above settings will change the Hex values appropriately. Never set "Reset Disabled" or "Disable ISP" to true unless you know what you are doing since you won't be able to reprogram the chip using the In-System-Programming method. If you accidentally did this and can no longer reprogram the chip just remember to get yourself or make a high voltage programmer: a good example of one can be found here and here. This calculator website kindly displays the commands needed to set the fuses of your board using AVRDude just to the right of the "Current Settings" area:

avrdude -c arduino -p m328p -P com3 -U lfuse:w:0xFF:m
avrdude -c arduino -p m328p -P com3 -U hfuse:w:0xDE:m
avrdude -c arduino -p m328p -P com3 -U efuse:w:0x05:m

After choosing the settings you desire, the Hex values will be calculated, then it's just a matter of passing the correct Hex value to the correct fuse using AVRDude: either Low, High or Extended. I recommend you double or even triple check the settings before uploading to the board just to be safe and don't forget to use your programmer with the ISP cable to code the new fuse settings to the slave.

Some of the settings that are of interest include:

Disabling the "Divide clock by 8" option which will increase the speed of your Arduino to maximum speed but uses more power. Or maybe your project doesn't require much speed and enabling the "Divide clock by 8" feature would lower power consumption which can be handy if your project is powered by a battery.

Turning on "Brownout Detection" if your project is dependant on using the EEPROM for storing information, the moment you go below the brownout power threshold the Arduino will shut down to shield the EEPROM from being erased or corrupted.

To compliment the "Brownout Detection" feature you can enable "Preserve EEPROM memory" which keeps the data stored in the EEPROM even after a chip erase since you may not want the information deleted.

That's all I can think of for now but I do hope this tutorial was helpful

Thanks for reading,
Ashton.

Monday, June 25, 2012

Quickfix - Arduino Pro Mini's not Syncronizing

Hey everyone,

A little while back I bought an Arduino Pro Mini (5v version) and was planning on using it to make small devices like remotes or human interface devices to control my computer. Everything was going well, I soldered connections to all the pins and was ready to program the device using a USB to Serial converter (which is also rated at 5v to match my Arduino) that you can see here:



So I plugged it in and everything seemed fine, but as soon as I tried to reprogram the Arduino from the default blink project that it came pre-programmed with, I received an error saying that I couldn't synchronise with the board and that Processing couldn't upload my new code. I spent a good day looking up solutions on the internet and nothing helped, there was even two images of the same serial board I had attached to the Arduino forwards and backwards which wouldn't help anyone who was looking for solutions and I was sure I had the boards matching up correctly so that wasn't it, you'll find there's two version with the BLK to GRN switched so just make sure that your particular version is aligned correctly to the serial converter. Eventually I found my own solution utilising a method I use when debugging in C++ / C#; I connected up just the power and ground then slowly introduced each pin until I was able to commit my code to the Arduino. The solution was simply to remove one of the pins that said ground (Since the BLK pin was also a ground pin) on the Arduino Mini Pro which was connecting to a pin called CTS on the Serial board as you can see here:























As soon as I removed the pin everything just worked, no more sync issues with Processing and I could finally begin developing with the Arduino board :)

I recommend that you try connecting wires first before removing the pin; just in case your mini has a different reason than mine for not syncing, if yours doesn't have the same problem then it would be safer since the small board doesn't cope well with repeated application of heat from a soldering iron.

After solving the problem I read up on what the pin does, it's called CTS (Clear To Send) and was responsible for serial handshaking. Since the pin is omitted from the Arduino Mini Pro, I'm guessing they no longer need that pin and was used with older systems that didn't come with a self reset feature for programming; older Arduino's required you to reset the board just before the serial command to reprogram the board was sent. The USB to Serial Converter must have kept it for backwards compatibility with older boards and other serial devices. For additional information for those who are curious you can read about the flow control system here.

My Arduino Mini Pro seems to have the connections reversed from the one specified on the Arduino website here which may indicate that my Arduino may be outdated or perhaps it's a difference between the 3.3v and 5v versions. This being the case, if your version has the connections similar to the website then I can't guarantee if this solution will fix yours since I've never used that version but if my theory about the CTS pin being pulled to ground is correct which causes interference with the re-programming then I do hope this solution helps you too.

Thanks for reading,
Ashton.

Monday, March 19, 2012

Tutorial - Dosbox Linear Scaler 4x and Greater

Hey Everyone,

I was just checking up on the status of a program called Dosbox to see how the development is going and started reading the forum, I noticed someone asking if additional linear scales could be added to the rendering context configuration. I actually did this myself when I needed the game to fit nicely on a 2560x1600 screen in window mode by modifying and recompiling the source code. So since I've done it before I decided I should write a nice "quickish" tutorial on how to do this for those who are curious or even have the same problem like I once had. Please note that this is only going to add additional ScaleNormal's; 2x, 3x, etc which doesn't include TV, RGB, Scan, HQ, Sai, Super, Advanced Mame or Interp. Also for those who are more familiar with programming and are comfortable with working out dependencies in your favourite IDE etc feel free to skip the steps and head straight to the code change section :)

Additionally someone has recently compiled a patch using this tutorial to add support for 4x, 5x and 6x which you can find at the DosBox Development Forum here: link :)

Please note that at the point of which I wrote this tutorial, Dosbox v0.74 was the latest revision so I can't promise this tutorial will still be accurate with additional future Dosbox updates and changes to the VGA scaler code. If this is the case then I will take a look at the changes and if possible, I'll make a new tutorial in the future :)

The first step is to obtain the source code, you can either download the latest stable build from here or you could download a subversion aggregation program to obtain the latest up to date version of the code, the one I use is called Tortoise SVN which you can download from here. Once you have that you can download the latest SVN repository of Dosbox by copying and pasting this link into your subversion's checkout process:

https://dosbox.svn.sourceforge.net/svnroot/dosbox/dosbox/trunk

The second step once you've downloaded the source code into your desired directory you'll need an editor for modifying the source code, I believe Dosbox supports a few including make files. Since I use the Windows operating system I like to edit code using Microsoft's visual studio which you can download the express version for free from here, the source code is written in C++ so I've linked the 2010 C++ Express edition.

The third step is to load the project into your editor, for those using visual studio they have provided an .sln project file that you can open in the editor, you can find this in "SVNFolder\dosbox\trunk\visualc_net". You may need to convert the project file to 2010 due to the project being built from an older visual studio version but the code will still work fine in 2010 after you convert it; Visual Studio will provide a window that will take you through the conversion process while also giving the option to backup the code in case the conversion fails.

The fourth step will be getting the code to compile without build errors; for the purposes of the tutorial and to make things easier I'll be omitting the screenshot ability as well as the debugging system of Dosbox so the code will compile with less hassle. First things first, create a folder for placing everything in; well need to download some dependencies for the Dosbox rendering context and networking subsystem. First you'll need to download SDL from here, at the bottom of the page where it says development libraries click on the appropriate file for your IDE and download it to your new folder. Second you'll need to download SDL_Net from here where it says binaries; download the appropriate developer package for your operating system, they'll contain "devel" in their names and download it to your new folder as well.

Extract both packages to their own folder and then decide where you'd like your global dependencies to exist for future projects like "C:\API Dependencies" or something like that so you have a nice place to put everything. Create two folders inside; one called SDL and the other SDL_Net, once you've done that open the SDL folder you extracted and drag and drop the include and lib folders to your new SDL API Dependencies folder. Then do the same for SDL_Net from your extraction folder to the dependencies SDL_Net folder.

Ok time to modify the Dosbox project settings so it knows where these files are and allow it to compile happily. Make sure you have the project open in Visual Studio 2010, you can optionally set the project to either debug mode or release mode; release being more efficient and result in a smaller exe file but remember that all these settings you are about to change will have to be done again for debug. Please note that release mode will take longer to compile due to additional code optimizations but the program will run a lot smoother as a result, after choosing that you can either hit Alt+F7 or go up to the top menu under "Project" and click on "Dosbox Properties" which will open the project settings dialogue. Click on "VC++ Directories", then click on "Include Directories" and an arrow will appear to the right side of the text area, click that and then click edit (I have no idea why the interface is like this so bare with it). After you do that you'll see a small window open up called "Include Directories", go back to your API Dependencies folder and locate the include folder for SDL and copy the directories path and then go back to the "Include Directories" window, double click on the white space or click the new path button and paste your SDL directory into it. Do the same for SDL_Net and then hit ok to close the window.

Further down the list you'll see another list called "Library Directories", this time you need to copy and paste the "Lib" folder directories of both SDL and SDL_Net into the libraries window then hit ok. So far so good, now on the right panel of your project settings you'll see something called "Linker", click this and then open up the "Additional Dependencies" list like you did with the include and library lists. Remove the references to "zlib.lib", "libpng.lib" and "curses.lib" then hit ok, this will remove the dependencies for the screenshot and debugging systems; you can add this back later if your willing to compile libpng and zlib yourself since Dosbox doesn't come with them, probably due to licensing or something and what's worse is some dependency developers don't even provide binaries or libraries so you can avoid compiling manually.

To finalise the removal of all external dependencies you'll need to open the "config.h" file located under "Source Files/visualc" and make sure both "C_DEBUG" and "C_SSHOT" are set to zero next to them. If you compile the code you should be left with one last error informing you that it can not find "afxres.h" which for some reason the express addition of visual studio doesn't come packaged with, to fix this last error double click on the error about the missing file and it will open the "winres.rc" file showing the include statement trying to find the missing header file, replace that line with this code section:

#include <Windows.h>

Ok with any luck you should have a compiled version of Dosbox, just make sure that when you place the exe outside of the IDE's compile folder to make sure you put both "SDL.dll" and "SDL_net.dll" which you can find inside the dependencies lib folder under x86 with it, otherwise it will crash. You should take note when you run the program that there's a reference to the config file that allows you to change Dosbox's settings written on the console that's unique for this SVN Build located at "C:\Users\Your Name\AppData\Local\DOSBox\dosbox-SVN.conf" for Windows 7 but write down where it says for your computer so you can change the settings later.

Code Change Section

Alrighty, now that we can run Dosbox from its source code we can begin to implement some upgrades for the VGA linear scaling system. First things first we must create a new definition for our new scaler type; under "Source Files/gui" you will find a header file called "render_scalers.h", open it and scroll down to the bottom. You should see this

extern ScalerSimpleBlock_t ScaleNormal2x;
extern ScalerSimpleBlock_t ScaleNormal3x;

Add this line just after them at whatever scale you desire:

extern ScalerSimpleBlock_t ScaleNormal4x;

In this case I'll be adding a 4x linear scaler. Now Open the file "render.cpp" under the gui folder and scroll down to line 291, you should see this:

if ( render.scale.size == 2 )
       simpleBlock = &ScaleNormal2x
else if ( render.scale.size == 3 )
       simpleBlock = &ScaleNormal3x;
else
       simpleBlock = &ScaleNormal1x;

Append your scaler as an additional else if line like this:

else if ( render.scale.size == 4 )
       simpleBlock = &ScaleNormal4x;

Scroll down to line 600 and add this:

else if (scaler == "normal4x") { render.scale.op = scalerOpNormal;render.scale.size = 4; }

Ok, now open up "render_templates.h" in the gui folder, then scroll down to line 241. Add this after the Normal3x's definition:

#define SCALERNAME        Normal4x
#define SCALERWIDTH        4
#define SCALERHEIGHT    4
#define SCALERFUNC                                \
    line0[0] = P;                                \
    line0[1] = P;                                \
    line0[2] = P;                                \
    line0[3] = P;                                \
    line1[0] = P;                                \
    line1[1] = P;                                \
    line1[2] = P;                                \
    line1[3] = P;                                \
    line2[0] = P;                                \
    line2[1] = P;                                \
    line2[2] = P;                                \
    line2[3] = P;                                \
    line3[0] = P;                                \
    line3[1] = P;                                \
    line3[2] = P;                                \
    line3[3] = P; 
#include "render_simple.h"
#undef SCALERNAME
#undef SCALERWIDTH
#undef SCALERHEIGHT
#undef SCALERFUNC

Alright, now we need to declare our scaler; open up "render_scalers.cpp" under gui and scroll down to line 242. Here you can see the definitions for the linear scalers, append this code after the definition of "ScaleNormal3x":

ScalerSimpleBlock_t ScaleNormal4x = {
    "Normal4x",
    GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32,
    4,4,{
{    Normal4x_8_8_L,        Normal4x_8_15_L ,    Normal4x_8_16_L ,    Normal4x_8_32_L },
{                 0,        Normal4x_15_15_L,    Normal4x_15_16_L,    Normal4x_15_32_L},
{                 0,        Normal4x_16_15_L,    Normal4x_16_16_L,    Normal4x_16_32_L},
{                 0,        Normal4x_32_15_L,    Normal4x_32_16_L,    Normal4x_32_32_L},
{    Normal4x_8_8_L,        Normal4x_9_15_L ,    Normal4x_9_16_L ,    Normal4x_9_32_L }
},{
{    Normal4x_8_8_R,        Normal4x_8_15_R ,    Normal4x_8_16_R ,    Normal4x_8_32_R },
{                 0,        Normal4x_15_15_R,    Normal4x_15_16_R,    Normal4x_15_32_R},
{                 0,        Normal4x_16_15_R,    Normal4x_16_16_R,    Normal4x_16_32_R},
{                 0,        Normal4x_32_15_R,    Normal4x_32_16_R,    Normal4x_32_32_R},
{    Normal4x_8_8_R,        Normal4x_9_15_R ,    Normal4x_9_16_R ,    Normal4x_9_32_R }
}};

Ok, now inside "render_simple.h" in the gui folder which in my case seems to be excluded for some reason. You can find it inside the SVN directory's gui folder manually, just drag and drop it into your IDE editor; feel free to add it to your "Source Files/gui" folder so you can always access it later. Now you can scroll down to line 68 and append this:

#if (SCALERHEIGHT > 3)
            PTYPE *line3 = WC[2];
#endif

This after line 79:

#if (SCALERHEIGHT > 3)
        PTYPE *line3 = (PTYPE *)(((Bit8u*)line0)+ render.scale.outPitch * 3);
#endif

This after line 97:

#if (SCALERHEIGHT > 3)
                line3 += SCALERWIDTH;
#endif

Finally this after line 109:

#if (SCALERHEIGHT > 3)
            BituMove(((Bit8u*)line0)-copyLen+render.scale.outPitch*3,WC[2], copyLen );
#endif

To use your new scaler as an available option, you can open up "dosbox.cpp" and go to line 389 where you can add this:

const char *scalers[] = {
        "none", "normal2x", "normal3x", "normal4x" 

Now compile the code and you'll be able to specify the "Normal4x" setting inside the Dosbox.conf file and your game should render larger than the 3x multiplier. If you would like the config file to show your scaler as an available option in the comments you'll need to delete the old config file first as this change will only effect the config when it's created by default; when one hasn't been found in the AppData directory.

And that's it! I hope this wasn't too much of a headache for people and that you enjoyed the tutorial. Feel free to explore what the changes do and see if you can work out how to add even more scalers to your code :)

Thanks for reading,
Ashton.