Showing posts with label Technical Discussion. Show all posts
Showing posts with label Technical Discussion. Show all posts

Monday, September 1, 2014

How many FPS? - DOS Games and Framerates

The refresh rate is the number of times the display redraws the screen per second.  In the DOS world, three refresh rates were typically used by monitors.  Displays compatible with the MDA and Hercules Graphics Card used a 50Hz refresh rate.  To reduce flicker, they also used slow-decaying phosphors, giving a ghosting effect.  A high pixel resolution of 720x350 was available, but these displays used a TTL signal composed of a video and an intensity line, instead of an analog composite signal.

The CGA was designed for TV screens and color RGB monitors, so its displays used a 60Hz refresh rate.  As a tradeoff, the resolution of this adapter could not exceed 240 lines.  The adapter did not support interlaced video modes, which generally use 480 or more lines and which ran at ~30Hz.  The flicker caused by an interlaced signal on a CRT is very noticeable when the user is close to the screen.  The monitor used a 4-bit digital input for RGBI monitors, but was otherwise similar to analog RGB monitors like the Amiga 1084.  The PCjr. and Tandy Graphics Adapters used the same displays.  The EGA could use either an Monochrome Display, a Color Display or an Enhanced Color Display that supported 350-lines and 6-bit digital RrGgBb input.  The refresh rate for the Enhanced Color Display was still 60Hz.

Later, the VGA and MCGA supported high resolution analog RGB monitors.  To reduce flicker, these monitors refresh all resolutions at 70Hz, except for 640x480, which uses 60Hz.  SVGA and later standards would typically allow the user to set the refresh rate for the resolution he wished to use, and some CRT monitors of the late 1990s could handle refresh rates up to 120Hz at 640x480 and 85Hz at 1024x786 or better.  Refresh rate also tended to depend on bit depth, and the monitor may not be able to handle a 32-bit graphics mode at a high refresh rate.

The increase in refresh rate was mainly done to combat flicker.  When someone sits five feet from a TV screen, interlacing and flicker are generally not so great a problem as to distract a person.  However, when someone sits five inches from a computer monitor, 60Hz can become a problem, especially as screen sizes grew from 13" to 15" and beyond.

Just because the display adapter is drawing the screen 60 times per second, that does not necessarily mean that there is some movement occurring on the screen at that framerate.  Many DOS games, like adventures, are fairly static games where often little is occurring on the screen.  In this sense, the game's framerate is only the rate needed to update the animation.  Games with cursors can redraw the cursor as fast as the refresh rate allows.  Therefore, despite the potential of the displays, actual high frame rate games are comparatively uncommon.  Many CGA and EGA games will limit themselves to 30 (Test Drive), 20, 15 (Lemmings), 10 or 5 frames per second.  By keeping the frame rate to an even divisor of 60, the game can avoid screen tearing.

Similarly, in many action games of the 1990s that used VGA, the frame rate would not intentionally exceed 35 frames per second during the action.  Some of ID Software's games from this period follow this rule, including Commander Keen 4-6 and Keen Dreams and the DOOM games.  The use of 35 frames, even in a 16-color game like Keen, demonstrates that ID was using VGA, not EGA, to develop the game.

Commander Keen 1-3 use a "cinematic" 24 frames per second approach, and Commander Keen 4-6 and Keen Dreams for CGA allow up to 60 frames per second.  This may be to compensate for the lack of scrolling hardware with CGA.  Dangerous Dave, Monster Bash and Catacomb 3-D use 60 frames per second with EGA and 70 frames per second with VGA.  Wolfenstein 3D is a 70 frames per second game using an updated Catacomb 3-D engine.  Jazz Jackrabbit is a very fast and fluid game, and it uses 60 frames per second in its action sequences.  To avoid screen tearing, the game uses a custom 320x199 resolution to allow it to specify a custom 60Hz refresh rate.

The best DOS pinball games are also high frame rate games.  Epic Pinball, Pinball Fantasies and Pinball Illusions all use 60 frames per second for the tables.  This makes sense because they are trying to simulate the fast action of a pinball table and ensure smooth screen scrolling as the table has to frequently shift from the upper and lower portions of the table.  Pinball Dreams and Pinball Dreams 2 actually use 70 frames per second for their tables.

High framerates assumes your hardware can push those frames out to the adapter.  Lower-end hardware will not be able to keep up, and the responsiveness of the screen will not be as fluid.  However, on the other end of the spectrum, older games may be run too fast on newer hardware, and thus may approach 60 or 70 frames per second when they were intended only to produce a fraction of that rate.  In Sierra's AGI games, for example, while the frame rate is usually in the teens, if you use the fastest setting on a 486, for instance, you may go to at least 60 or 70 frames per second.

Friday, June 6, 2014

Arcadia/Starpath Supercharger - Cassette Games on Consoles

The Arcadia/Starpath Supercharger for the Atari 2600 was a very peculiar device from the second generation of video games.  It was a very large cartridge that plugged into the 2600's cartridge port.  It contained 6K of S-RAM for loading games off cassette tapes and 2K of ROM for the loading code.  The Supercharger was packaged with the game Phaser Patrol.  The initial cost of acquiring the Supercharger was higher ($44.95) than a standard 2600 cartridge ($29.95 for many new titles), but the games themselves were often priced lower than cartridge games ($14.95-17.95) due to the use of cassettes, which were much cheaper to mass produce than cartridges. Not included in that price was the cost of the cassette recorder, which the player had to supply.  The cassette recorder's line out would be connected via the Supercharger's audio cable.

Ten games were widely available during the accessory's life, two could be purchased by mail order, and four prototypes are known to exist.  Among the Supercharger's best games were Dragonstomper, one of the first console RPG games.  Communist Mutants from Outer Space is a fun shoot-em-up in the Galaxian vein, and Fireball is a fun Breakout clone.  Escape from the Mindmaster uses a very impressive first-person perspective.  Even though the library is small, the overall quality of Starpath's 2600 games, in my opinion puts the company in the first rank of 2600 game designers alongside Atari, Activision and Imagic.

I must give special mention to the version of Frogger released for the Supercharger.  This version, the so-called Official Release looks, sounds and plays far better than the Parker Bros. cartridge. In fact, it is superior to just about every cartridge release of the game.  The arcade original has five lanes of roads and five lanes of water, but many console ports only give you four road lanes. Even more impressive is the fact that the arcade music plays throughout as it should despite the rather humble audio capabilities of the 2600. Many ports cut the theme short and leave you with silence during most of the gameplay.  The SNES version is particularly atrocious in this regard because it has no music at all!

When the Supercharger was inserted into the 2600 console, the screen would show "REWIND TAPE PRESS PLAY".  Once the player did that, the game would proceed to load, with colored bars on the screen closing in informing the player of the progress of the load.  When done, the screen would display "STOP TAPE" for a moment, then the title screen of the game would appear and the player could start playing.

Most games were fully loaded within one load of the cassette, but four games (Dragonstomper, Party Mix, Survival Island, Sweat! - The Decathalon Game) used three loads and one (Escape from the Mindmaster) used four.  The tape would be rewound to the beginning, then the first load would start the game, requiring the player to stop the tape.  When the game needed the next load, the player would have to start the tape again.  If he waited too long in stopping the tape, he would have to rewind it and play it until the game found the beginning of the right load.  A load may take approximately 20-40 seconds, depending on the game and which side of the tape was being used.  Side A was the fast-load side, Side B was a slower load if Side A did not work with the player's cassette recorder.

The Supercharger digitized the binary data of a game onto an audio cassette.  A "0" bit would be an audio wave pulse of 158ms and a "1" bit would take 317ms (fastest speeds) or 900ms/2450ms (slowest speeds).   The controller chip in the Supercharger would use an ADC to convert the audio into binary data for the RAM.  The Supercharger supports three banks of 2KB of RAM and one bank for the 2KB ROM.

People talking about the Supercharger often state that it increased the RAM capacity of the 2600 (128 bytes) 49-fold.  This is not really an apt comparison.  An average cart uses a 4KB ROM chip to store program code, graphics and sound.  That data must be stored in the Supercharger RAM.  A Supercharger game is really like a 6KB cart (with a single load game, otherwise 18KB/24KB cart).  However, any portion of that 6KB can be used as extra RAM.  Each load of a Supercharger game transforms into an 8448 byte binary file, but that file includes a good deal of space not used by the game (including the space occupied by the ROM bank and a header).  Additionally, all ten of the officially released Supercharger games include a "demo" load at the end of the last game load on the tape to show previews of other games.  For multiload games, a combined binary file is used with emulators and cartridges like the Harmony Cartridge.

Comparatively, 8KB, 12KB, 16KB and even a 32KB cart were released during the 2600's lifetime.  The three 12KB carts from CBS came with 256 extra bytes of RAM, and sixteen of the 8KB, 16KB and 32KB carts from Atari came with 128 bytes of RAM.  One game from M-Network, Burgertime, used 12KB of ROM and 2KB of RAM.

The Supercharger was not the only 2600 peripheral that could utilize cassette storage.  The CommaVid Magicard programming cartridge came with 2KB of ROM and 1KB of RAM.  There were instructions in the manual to modify the cartridge to add support for saving and loading programs to cassette.  The Spectravideo Computmate came with 16KB of ROM and 2KB of RAM.  The Compumate turned your 2600 into a cheap computer as it came with a 42 key membrane keyboard that would fit on the front grill of a pre 2600jr. machine.  It supported saving and loading programs from cassette using a standard cassette recorder.  But the impact of these devices pales in comparison to the Supercharger and its games.

Saturday, March 8, 2014

Joystick Problems with DOS and Approaches to the Problem

IBM's Game Control Adapter was designed as something of an afterthought, a simple to use expansion card (for a programmer) as a way to provide for connecting a low-priority input device.  It sat at port 201, supported four digital inputs, intended for buttons and four analog inputs, intended for paddles or joystick axes.

When it was released as one of the original expansion cards for the new IBM PC, it was perfectly adequate for the time.  The Apple II joystick port operated in the same way but only supported three buttons.  The Tandy Color Computer also supported four analog axes and four buttons, and its joysticks were later used in the mostly-PC compatible Tandy 1000 line.  The Commodore VIC-20 only supported one Atari-style joystick or two Atari-style paddles.  Only the Atari 400 and 800, with their four joystick ports, supported more game inputs.

In IBM's design, a joystick is a pair of potentiometers which are turned by moving the joystick.  Each three-terminal, 100 kOhm potentiometer is connected through the joystick cable to a +5v line and a capacitor on the game control adapter.  This capacitor is tied to an input on the NE558 Timer IC.  The Timer compares the capacitance on its input with a reference capacitance, and outputs a 1 when the capacitance is not equal and a 0 when the capacitance is equal.  The resistance value from the potentiometer determines how quickly the capacitor on the input will be charged.  If the capacitor is turned to a lower resistance, the capacitor charges more quickly, and if turned to a higher resistance, the capacitor charges more slowly.

When the programmer wants to read the joystick position, he writes to port 201.  This discharges the capacitors.  Then the programmer reads and reads port 201 until there is a 1 for the axis he is trying to measure.  The time taken for the value to become a 0 represents the position of the joystick.  Many games have joystick calibration prompts requiring the player to move his stick to its maximum positions and its center to obtain the timing required to properly calibrate the stick.

Eventually the limits of the design began to emerge.  The first was that the joystick had to be read several times to get an accurate measurement of the stick's position.  This took a substantial portion of a 4.77MHz  8088 CPU's time.  However, when there was only one CPU and one speed used in PC and compatibles, this was just an inconvenience, because the timing would be equivalent on all machines.  For many simpler games, which relied on digital controls, fine measurement of the joystick axes was not an issue.  However, when faster CPUs and clock speed began to emerge, joystick routines would consequently run faster.  Thus routines would take 20% of the CPU's time an 8088 may only take 10% or less of the CPU's time on the more efficient 286.  When CPU speeds began increasing to 6MHz, 8MHz and beyond, routines that were designed for the IBM PC would complete themselves far too quickly to get an accurate read of the joystick.

A second issue with the inherent accuracy of the components used to determine the joystick's position. Linear potentiometers such as used in the PC are not known for their rigorous accuracy.  While the adjustment dials on each axis can help, they can shift or loosen over time.  Moreover, the housings containing the resistive element and wiper are not hermetically sealed or anything close to it.  Dust and dirt and oils over time can seep in and cause jittery or inaccurate reads.  Wear on the resistive element can make it harder for the stick to give an accurate resistance.

IBM gave a formula to measure the time the stick would take to charge the capacitor at any given resistance (0-100).  When it released the IBM PC AT, with its 6MHz 80286 CPU, it introduced Int 15, subfunction 84 to give a BIOS routine to read the joystick.  Unfortunately, the clone PC makers had already spent substantial time and money cloning the original IBM PC BIOS, and this new BIOS call did not necessarily make it into every clone.  Tandy 1000s do not support it.  The advantage of the function was to give reliable reads because the routine was tied to the processor and speed(s) which the system board was designed to run.

Other companies tried to offer solutions to these problems.  Tandy 1000 joysticks used the design from the Tandy Color Computer.  Instead of using the potentiometers as variable resistors, Tandy uses them as voltage dividers by connecting the third terminal to ground.  Inside the machine, the voltage is compared to a voltage ramp which, when port 201 is written to, is charged from 0v to +5v in a set period of time.  When the voltage ramp is greater than the voltage from the joystick, a 0 is reported.  This method has been said to give more precise and less jittery results than the timer-resistance method used on a true PC.

The Amstrad PC-1512 gave a unique solution to the joystick problem.  It supported one Atari-style digital joystick with two buttons.  This joystick plugged into the keyboard.  The directionals and buttons for the joystick were assigned to unique keyboard scancodes 7C-77.  However, when reported by the BIOS, pressing the directionals would give scancodes assigned to the cursor keys on the numeric keypad.  Since many, many games used the keypad cursor control keys for movement, this was a highly compatible way to implement digital input.  It would not work if the program read directly from the keyboard input port instead of the BIOS unless the program was Amstrad-aware.  The two joystick buttons could be assigned to represent any key through the use of a program which would write to the Amstrad's non-volatile RAM.  This memory would retain the buttons' settings until the next time the buttons' settings were changed.

When the Sound Blaster came along, it implemented a standard joystick port.  Until the Sound Blaster 16, the port did not change.  In the Sound Blaster 16, the old DIP-style NE558 timer was replaced with surface mounted components, which presumably have lower latencies which work better with faster processors. The Gravis Ultrasound implemented a hardware version of a speed adjustable gameport, and came with a program to adjust the sensitivity of the gameport without the use of an external dial or jumper.

Other companies made speed-adjustable gameports.  In these gameports, a dial would be routed outside the computer to adjust the speed of the gameport.  In the Thrustmaster ACM Game Card, the dial was a potentiometer which would adjust the resistance going to the reference capacitor.  The ACM Game Card had a second joystick interface at port 209, requiring a second NE558.  The dial controls the resistance for both reference capacitors.

The Gravis Gamepad was very popular in the early 90s because it provided four buttons and a NES-style D-pad.  However, inside the Gravis Gamepad were transistors to convert the digital values of a D-pad into the analog resistance values expected by the PC gameport.  Essentially pressing one side of the pad would give the maximum resistance value of the axis, the other side would give the minimum resistance value and not pressing the pad would give the middle of the resistance value.

Later joysticks, like the Gravis Gamepad Pro and the Microsoft Sidewinder gamepads would give options for truly digital controller with more than four buttons.  These sticks would use the gameport to send binary codes to the program.  The downside is that a DOS program had to have specific support for the gamepad, or the digital functionality of the gamepad would only work in Windows 95 with a driver.

Another late innovation was to take inspiration from computer ball mice.  Computer mice and trackballs use optical rotary encoders to track movement, just like the dials on most arcade machines, the Atari driving controller and the N64 thumbstick.  Reading from the encoders is much more reliable than the timer-potentiometer method and not prone to speed sensitive issues or the same kind of wear.  The Microsoft Sidewinder 3D Pro had this function and many buttons, but unless a DOS program understood it, it had to emulate the analog potentiometer method

Once IBM ceded leadership of the PC market, no other company came up with a standardized digital gameport solution.  Eventually, USB input devices of all kinds, gamepads, joysticks, driving wheels, rudder pedals, throttles, yokes put all the speed issues to software.  However, USB really didn't catch on until Windows 98, so for almost twenty years game players had to deal with the analog gameport.

Friday, March 7, 2014

Tutorial : Compiling DOSBox SVN with Screenshot, Video Capture and IPX/Modem Support in Windows

DOSBox is a wonderful program, but in case you haven't noticed, the last official release, 0.74, is rapidly approaching its fourth birthday (05/12/2010).  This is by far the longest time span between releases of the program.  But DOSBox has not been sitting idly by, the developers have continued to fix bugs and add new features.  While it is easy enough to find a pre-compiled version of the latest SVN, it may not be able to support screenshots without crashing (EmuCR), has more options in the config file than an average DOSBox user may need (DOSBox-X, Yhkwong's build) or simply won't have the features of that particular patch you are looking for.  Until the development team releases 0.75, this is the closest you can get.

This tutorial is intended to guide a beginner through the compiling process in order to obtain a fully featured build of DOSBox SVN with important optional features such as IPX and Modem support and Screenshot and Video Recording in Windows.  I have omitted adding the debugger features, if you need them, then this tutorial is probably too basic for you.  To include the debug features, you need the curses library, and the best library for implementing the debugger in Windows is the pdcurses 3.4 library.

1.  The Compiler

This tutorial assumes you are running DOSBox on some modern version of Windows and using an x86 CPU.  (No Windows RT.)  Since we will be using a Microsoft product to compile the source code, it will not work on any other system.  It is easy enough to compile a DOSBox with the basic features.  There is a good tutorial on how to do it in Visual Studio 2008 Express Edition.  You can find it here and you may wish to consult with it if anything in this tutorial is unclear : http://www.dosbox.com/wiki/Building_DOSBox_with_Visual_C_2008_Express

I am indebted to the author, for this is the way I learned how to compile DOSBox, being a Microsoft loyalist since I first used a PC compatible in the early 90s.  You can also use MinGW and MSYS, but that is a Unix/Linux approach utterly foreign to me (and I could never figure it out anyways).

VS2008 is getting a bit old in the tooth, and some of the more modern project files do not really support VS2008.  So in this tutorial, I will be using Visual Studio 2010 Express, also freely downloadable from Microsoft.  Virtual Studio includes Visual C++.  Find it here :

http://www.visualstudio.com/en-us/downloads#d-2010-express

The installer will download the program and the modules it needs and will install them.  It will also set file associations for the files we will be using.

2.  The Source Code

Now, you need the source code.  First start with the current DOSBox SVN, found here :

http://source.dosbox.com/dosboxsvn.tgz

You should use a program like 7zip to uncompress this file.  It is doubly compressed.  Please see my DOSBox patching guide if you want to add any patches, as you can at this stage :

http://nerdlypleasures.blogspot.com/2014/02/patching-dosbox-for-beginners.html

Next, you will need the Simple Directmedia Layer (SDL) to build libraries that DOSBox needs to function.  DOSBox is only compatible with the 1.2 versions and the last version of SDL is 1.2.15.  However, you should obtain the source code for 1.2.14, which is the last SDL 1.2 version that will compile easily in VS2010.  You can download it here :

http://www.libsdl.org/release/SDL-1.2.14.zip

3.  Optional Libraries

If you want to add the optional features to your compiled DOSBox, you will need some more source code to build libraries.

1.  For Modem/IPX support, you need SDL_net.  SDL_net's mirrors SDL's versions, and the most current  version that will compile easily in VS2010 is 1.2.7.  Get it here :

http://www.libsdl.org/projects/SDL_net/release/SDL_net-1.2.7.zip

Now what you have obtained above is the easy part.  For working screenshots and video recording, you will need to compile libpng and zlib libraries from source.  After that, then you compile DOSBox.

For libpng, the current stable source is 1.6.9.  You can obtain it here :

http://prdownloads.sourceforge.net/libpng/lpng169.zip?download

You use libpng to compile both libpng.lib and zlib.lib, but for the latter, you need the zlib source code, and specifically 1.2.5 (even though 1.2.8 is the most recent version, but libpng expects 1.2.5).  You can obtain 1.2.5 here :

http://www.winimage.com/zLibDll/zlib125.zip

4.  Directory Setup

Once you have installed VS2010 and downloaded your source code and libraries, you need to put the source somewhere.  Make a folder like \Project and unzip your source code and libraries so they look like this :

\Project\dosboxsvn
\Project\lpng169
\Project\SDL_net-1.2.7
\Project\SDL-devel-1.2.14
\Project\zlib-1.2.5

This will be important for the next step and make it easier to point the compiler to the various include and library files later on.

5.  Compiling libpng.lib and zlib.lib

Go to \Project\lpng69\projects\vstudio\libpng and double click on libpng.vcxproj  A vcxproj file is a  Project File that tells a compiler how to build code.  This will start the compiler.  You should see Solution Explorer on the left hand side of the program.  There are seven projects here, but we only need two of them.  Right click on Solution 'vstudio' (7 projects), click on Properties and check the button that says Multiple startup projects:  Set libpng and zlib to Start and the rest to None.  Press Apply and OK.

Libpng relies on zlib, so we want to make sure zlib is compiled first.  Right click on libpng in the Solution Explorer and go to Project Dependencies.  In the drop down box, select libpng and make sure there is a checkmark next to zlib in the box below and none on any other box.  Then click on the Build Order tab and you should see that zlib comes first and libpng comes second.

Next right click on Solution 'vstudio' (7 projects) and click on Configuration Manager.  Under Active solution configuration: click Release Library.  In the box below, next to libpng and zlib, change the Configuration to Release Library.  For the other options, uncheck the boxes next to the Build so they will not be compiled.  Do not worry if they compile anyway, these extra projects are mainly for testing.

Next, in the Solution Explorer right click on libpng and go to properties.  On the left hand side, you should see a line called Configuration Properties.  On the right side of the window, you will see a line that says Configuration Type.  Click on the dropdown box next to it and set it to Static library (.lib) if it is not already.

Then click on VC++ Directories.  The window here is a bit small for what you need to do, but be very careful here.  Clicking on the wrong thing will wipe out the default directory entries, and if you do that the compiler will not know where to find the code it needs to compile.

Next to the line that says Include Directories, click once on the box after the partition.  This will show a down arrow button.  Click on that once and then click on  On the next window, click on the icon of a file with an asterisk in the corner, then click on the box with the ...  On the Select Directory Window, navigate to the directory with the zlib Include files.  The directory is typically : \Project\zlib-1.2.5.  When done, click OK.

To compile the libraries, hit F7.  In the output window, you will see the compiler crunch code and turn it into libpng.lib and zlib.lib.  If you succeed, the compiler will indicate where the .lib files are located.  If you fail, then the compiler will report an error and your files will not be built.  In this example, you can find the .lib files in \Project\lpng169\projects\vstudio\Release Library\ as zlib.lib and libpng16.lib.

6.  Compiling SDL and SDL_net

In this guide, I have completely avoided using developer libraries.  While there are appropriate Visual C ++ developer libraries that work with VS2010 available for SDL and SDL_net, I think its best to compile your own libraries.  Since you have to do this for libpng and zlib, you already should begin to get a feel for how to incorporate include and library directories.  Compiling your own libraries can improve DOSBox performance and compatibility with your particular system.

To compile SDL, you will need the DirectX SDK.  The DirectX 10 SDK from June 2010 seems compatible, and you can get it here :

http://www.microsoft.com/en-us/download/details.aspx?id=6812

You only need to install the libraries.  The installer may give an error if the rest of the components aren't installed, but the libraries will be installed.  You will be able to find them typically in C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)

Now, in the SDL-1.2.14 directory, there will be a zip file named VisualC.zip.  Unzip it so that you can see files in the next level subdirectory.  Go into that subdirectory and open the file SDL.sln.  This is a solution file used by older versions of Visual C++ to build a project. VS2010 will run a conversion tool that will convert it into something it can manage properly.   Click on Next and then Finish.  You may see some warnings but you shouldn't see any errors.

In the resulting Solution Explorer, you will see two projects, SDL and SDLmain, and you will need to compile both of them.  First, right click on Solution 'SDL' (2 projects) and go to properties.  Then click on the button that says Configuration Manager.  From the Active solution configuration: dropdown menu, click on release, and for the Configuration menu drop downs next to SDL and SDLmain, set them both to release.  Close the Configuration Manager.  At this point, the Configuration dropmenu should show Active(Release).  Click on Apply and then OK.

Next, in the Solution Explorer right click on SDL and go to properties.  On the left hand side, you should see a line called Configuration Properties.  On the right side of the window, you will see a line that says Configuration Type.  Click on the dropdown box next to it and set it to Static library (.lib) if it is not already.  DOSBox needs the libraries to compile, and SDL should still create an SDL.dll when you compile it.

Then click on VC++ Directories.  This is where you add the DirectX SDK libraries you installed at the beginning of this step  Next to the line that says Include Directories, click once on the box after the partition.  This will show a down arrow button.  Click on that once and then click on  On the next window, click on the icon of a file with an asterisk in the corner, then click on the box with the ...  On the Select Directory Window, navigate to the directory with the DirectX SDK Include files.  The directory is typically : \Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include  When done, click OK.

On the line that says Library Directories, you are going to do almost the same thing.  This time, you want to add the directory for the DirectX SDK Library files.  The directory is typically : \Program Files (x86)\Microsoft DirectX SDK (June 2010)\Lib\x86.  Make sure you select the x86 (for 32-bit) and not the x64 (64-bit, DOSBox doesn't like 64-bit code).  Once you are done, you can press OK to get back to the Solution Explorer. Now press F7 and you should be have created sdl.lib and sdlmain.lib in their respective Release directories, \Project\SDL-1.2.14\VisualC\SDL\Release and \Project\SDL-1.2.14\VisualC\SDLmain\Release

SDL_net requires the SDL libraries, which is why we compiled the SDL libraries first.  Like with SDL, you will need to unzip the VisualC.zip file and convert the solution file SDL_net.sln.  Set SDL_net to Release in the Configuration Properties.

Open the SDL_net properties page, set the Configuration Type to Static library (.lib) and then click on VC++ Directories.  For the Include Directories, you need to add the directory containing the SDL Include files.  They can be typically found here : \Project\SDL-1.2.14  Next you need to add the directories containing the SDL Library files.  These are \Project\SDL-1.2.14\VisualC\SDL\Release and \Project\SDL-1.2.14\VisualC\SDLmain\Release.  You need to add both.  After you have done all this, you can exit the properties window and press F7 to compile.  You should end up with sdl_net.lib.

7.  Setting Up the DOSBox Compiling Environment

Now that you have all your libraries, you can compile as full a DOSBox as you like.  Navigate to \Project\dosboxsvn\dosbox\visualc_net and click on dosbox.vcxproj

In the Solution Explorer Window, right click on dosbox.  Set the active configuration to Release using the Configuration drop box and the Configuration Manager button first.

In the VC++ Directories, you will need to add the following directories to the Include Directories :

\Project\lpng169
\Project\SDL_net-1.2.7
\Project\SDL-1.2.14\include
\Project\zlib-1.2.5
\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include

If you are compiling code specific to Windows, you may also need to include a directory like :

\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\sys

You will need to add the following directories to the Library Directories :

\Project\lpng169\projects\vstudio\Release Library\
\Project\SDL_net-1.2.7\VisualC\Release
\Project\SDL-1.2.14\VisualC\SDL\Release
\Project\SDL-1.2.14\VisualC\SDLmain\Release
\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Lib\x86

On the left side of the Property Page, click on C/C++ and then on General.  On the line that says Treat Warnings As Errors, click on the box next to it and set it to No (/WX-)  The compiling process will give many warnings, and if this is not set these warnings will cause the build to fail.

Next click on Linker and next to the Force File Output, click on the box next to it and select Multiply Defined Symbol Only (/FORCE:MULTIPLE).  Next to the Treat Linker Warning As Errors, click on the box next to it and select No (/WX:NO).  These "errors" and warnings are not going to affect a compiled DOSBox, but they certainly will stop DOSBox from compiling correctly.

Finally, underneath Linker, click Input.  The following line needs to be present :

dinput8.lib;dxguid.lib;libpng16.lib;sdl_net.lib;opengl32.lib;winmm.lib;sdlmain.lib;sdl.lib;ws2_32.lib;zlib.lib;%(AdditionalDependencies)

Many of these items are already present.  You will need to add dinput8.lib and dxguid.lib and rename libpng.lib to libpng16.lib.  Since the space is very small, you should check the spelling and formatting very carefully.  Each library, including the last, needs a semicolon ; after it.

8.  Adjusting the DOSBox Code and compiling

In the Solution Explorer, clock on Source Files and then click on visualc and then double click on config.h. The code listing will appear to the right.  If you are not compiling with IPX and Modem support, then change the values from 1 to 0 in the lines :

#define C_MODEM 1

#define C_IPX 1

If you are not compiling with screenshot and video recording support, change the value from 1 to 0 in the
line :

#define C_SSHOT 1

Next, for a speed boost, change the value from 0 to 1 in the line :

#define C_CORE_INLINE 0

Finally, you should see in the Solution Explorer a file called winres.rc.  Right click on that and select View Code  Change the line that says #include "afxres.h" to #include "Windows.h"

In the Solution Explorer, right click on dosbox, go to properties an then the Configuration Manager.  Makes sure the Active solution configuration and the dosbox project configuration are both set to Release, NOT Debug.  Release builds are faster than debug builds.  Debug DOSBox builds exhibit an annoying issue with the Adlib music where it will stutter unless the cycle count is set very low in DOSBox.  After you close the Configuration Manager window, you should see in the Configuration drop down menu Active(Release).  Exit the dosbox Property pages.

Now you are ready to compile.  Hit F7 and be prepared to wait.  If you are successful, you will have a dosbox.exe in \Project\dosboxsvn\dosbox\visualc_net\Release.  You probably will not need any .dll files since the libraries should be statically linked within the DOSBox executable, but if you do, you can obtain them from the official 0.74 DOSBox.

DOSBox will generate a .conf file on its first run if one is not present.  Look in the status window to find it and move it to the directory in which you will use DOSBox.  It is typically buried in AppData on Windows Vista/7/8.   It will save screenshots and other captures to a folder named capture, but by default will save them to the same place as it wrote the .conf file.

If you are using Windows 8.1, you will find that the mouse movement will be extremely jerky when using this build.  This is due to some changes Microsoft made in handling mouse input.  To fix the problem, apply the appropriate patch for your OS (32-bit or 64-bit) from here : http://support.microsoft.com/kb/2908279

Sunday, March 2, 2014

A Hypothesis of the Tandy 1000 Parallel Ports

The Tandy 1000s, until the RL and TL/3, have a built in parallel port.  It does not use a standard DB-25 parallel port connector.  It uses a 34-pin card edge connector, and Tandy usually supplied adapter cables to connect to a Centronics 36-pin connector at the printer.  However, there are some very useful devices that use the parallel port as a generic input and output port.  Parallel port floppy drives, CD-ROMs, Zip drives, the Disney Sound Source and Network Adapters could in theory and with an adapter use these card edge ports.  What is unknown is whether Tandy 1000 ports can support any kind of standardized (and I mean that loosely) data input.  To begin the exploration of the Tandy parallel ports, first I will need to discuss a standard IBM PC printer port.

Unidirectional Printer Ports

The first parallel printer port for the IBM PC had eight data lines, five status lines and four control lines.  The data lines allowed the computer to send eight bits of data to the printer.  The four control bits would send control information to the printer, which could send five bits back to the PC on the status bits.  Thus, the parallel port has three registers, and in a system without a monochrome display adapter parallel port, their addresses are these :

0378 - Data Port
0379 - Status Port
037A - Control Port

The status port is read only, and the data and control ports are read and write capable.  If the data or control port is read, the computer will read the bits last sent to the port.  IBM warned against a printer or other external device trying to use the parallel port to write data on the lines meant for the data or control ports.  Thus these ports are designated as output only ports.  Officially, a printer communicated to the computer through the use of the status port.  This port is designated as an input only port.

The bit assignments for the status and control ports become important to the discussion below :

Line Name IBM Pin Active Low Direction Function Bit
Strobe 1 Yes Out Control Port 37A C0
Data 0 2 No Out Data Port 378 D0
Data 1 3 No Out Data Port 378 D1
Data 2 4 No Out Data Port 378 D2
Data 3 5 No Out Data Port 378 D3
Data 4 6 No Out Data Port 378 D4
Data 5 7 No Out Data Port 378 D5
Data 6 8 No Out Data Port 378 D6
Data 7 9 No Out Data Port 378 D7
Ack 10 Yes In Status Port 379 S6
Busy 11 No In Status Port 379 S7
Paper-Out 12 No In Status Port 379 S5
Select (Input) 13 No In Status Port 379 S4
Auto Linefeed XT 14 Yes Out Control Port 37A C1
Error 15 Yes In Status Port 379 S3
Init 16 Yes Out Control Port 37A C2
Select-In (Output) 17 Yes Out Control Port 37A C3
Ground           18-25




Strobe - The strobe signal is sent to the printer to alert it that there is valid data byte on the data output lines.  This signal is active low and held for at least 0.5uS.  AKA STB,
Ack - The acknowledge signal is sent from the printer to tell the computer that the printer has received the data byte and ready to accept more data.  This line is tied to IRQ7 through the IRQ enable bit, Control Port C4.  This signal is typically held low for 5uS.  AKA ACKNLG, PACK
Busy - The busy signal is sent from the printer to tell the computer, when high, that it cannot process data at the present time.  This is typically when the printer is busy processing data, printing data, when it is offline or has reported an error.
Paper Out - The out of paper signal is sent from the printer and, when high, tells the computer that the printer is out of paper.  AKA End of Form, P. End, PE, PAEM, Out of Paper
Select Printer (Status Port) - The printer selected signal is sent from the printer to indicate to the PC that, when high, the printer considers itself selected and on-line.  AKA Printer Selected, SLCT, SEL
Auto Linefeed XT - The auto linefeed signal is sent to the printer to tell it, when low, to advance the printer a line after a carriage return.  AKA AUTO FEED XT, AF
Error - The error signal is sent from the printer to the computer to alert the computer of a fault at the printer's end.  This is typically when the printer is offline, out of paper or has some error condition.  AKA FAULT
Init - The initialize printer signal is sent to the printer to tell it to reset itself and clear its printer buffer.  This signal must be held low for 50uS for it to be effective.  AKA PRIME
Select-Input (Control Port) - The printer select signal is sent to the printer to tell it that, when low, it has been selected and should be ready to receive data.  AKA SLCT IN, Select-In

One thing to note about these bits is that of the Control Port signals, the Strobe, Auto Linefeed and Select-In (Output) are all inverted as they are output from their register to the connector.  Since these are active Low, you must set these bits High (1) to activate these signals.  Also, the Busy signal, as it comes from the printer, is also inverted at the Status Port.  Since Busy is active High, a Low (0) bit means the Printer is Busy.

Not all bits are used by all printers.  Most printers have a dipswitch to set the printer to the Auto Linefeed mode, since this usually desired.  It is hard to imagine today that a printer or typewriter would not automatically advance to the next line after pressing the Carriage Return/Enter key.

IBM's Graphics Printer, essentially the standard of the day, had a dipswitch to always set Select Printer (which from the printer's perspective it is an output line) to the active state.

C5 is used as an Interrupt Enable line.  It is active High, so when a (1) is written to the bit, IRQ7 will be sent when the Ack signal becomes active.  The intended use for this signal is that the printer program, when the IRQ was sent, would know without having to waste time polling the Status Port that it could send the next byte to the printer.

Nibble Mode

Before the introduction of the PS/2 Bidrectional Mode, the Nibble mode was the only compatible way to read data from an external device connected to the parallel port.  The external device would drive its data onto the status port.  The high four bits of the port would be the easiest to use, which in this case would be the Busy, Ack, Paper Out and Select bits.  This would form a 4-bit nibble, and two nibbles would form a byte.  As the Busy signal is inverted, code would need to consider that in obtaining the right data nibble.

The Status Port is a 5-bit port, and if read eight times could be reformed into five bytes by including the Error bit in the read.

PS/2 Bidirectional Mode

In 1987, IBM released the PS/2 and it boasted of a bidirectional parallel port mode that would allow an external device attached to the parallel port to send eight bits of data to the computer via the data port.  TTL-based parallel ports for the IBM PC family, including IBM's, could easily be modified to do this.  In this case, Control Port C5, when set (1), would change the data output port to a data input port.  The default behavior was that C5 was not set (0).  When in data input mode, a read on the data port will give the value sent by the external device.  A write to the port would do nothing.

IBM's PS/2 and PS/1 family had more advanced bidirectional capabilities involving new registers outside the parallel port I/O space, but the basic functionality described in the previous paragraph is all that could be assumed on a regular PC compatible.

Tandy 1000

While there are the later EPP and ECP parallel ports, this post is primarily based on what the built-in ports of the Tandy 1000 are capable of, and none of them are capable of such advanced functionality.

Tandy 1000 printer ports are based off the pre-IBM Centronics standard and have some differences. Tandy marketed many, many printers, and they were designed to work with all its computer lines, including the TRS-80, the Color Computer and the Tandy 1000, 2000, 1200, 3000 & 4000.  Early printers did not use all the control and status lines of the IBM parallel printer port.  The two handshaking signals, strobe and ack, are the most important for any printer.

The Select signals are not used on Tandy printers.  Auto Linefeed is not used by some Tandy printers, the Init signal is not used by all Tandy printers and they provide an active low as well as an active high Busy signal on two separate pins.  Some Tandy printers also provide +5v on their Centronics connector at pin 18, you will want disconnect this pin at the DB-25 end of the cable if you use one of these printers.  Fortunately, pin 18 is unconnected on standard Centronics 36-pin male to DB-25 male printer cables.  Tandy Centronics connectors put Init, when used, at Pin 33, whereas it is on Pin 31 on IBM Centronics connectors.  This is the functional difference between Tandy Type A and B Card-edge to Centronics cables and Type C and D DB-25 to Centronics cables.

The Tandy 1000/A/HD have a 40-pin Parallel Port Array IC, it differs slightly from the later Array used on the SX, HX, EX and TX.  The technical reference implies that it is capable of bidirectional operation.  One difference is that the Auto Linefeed signal is on pin 32 of the 1000/A/HD card edge.  On later machines this signal is found on pin 27.  The Tandy 1000/A/HD connector leaves pin 34 unconnected, but later Tandys connect it to +5v.

The EX, HX, SX and TX all share the same Parallel Port Array IC and their ports are wired identically. While the IC has a pin (16) for the Select-Input (Control Port) line, it is not connected to any of the lines on the card edge.   Additionally, all five Status Port lines are connected from the card edge to the IC, so theoretically the port is capable of nibble transfers.  However, the Select Printer (Status Port) line usually needs to be connected via jumper to the Array IC because Tandy's printers do not use it).

Also, in theory, you could connect the Select-Input (Control Port) to the card edge and then to a parallel device by a custom adapter.  However, you would need a pullup resistor and a capacitor as the other lines have.

The TL and SL use the Jacksboro version of the PSSJ chip to implement a parallel port.  This chips does not have a pin for the Select-Input (Control Port) line at all.  Ditto for the TL/2, SL/2 and RL, even though they use the more advanced Bonanza PSSJ.  The number of pins on either version of the chip are the same.  Like the earlier devices, the Select Printer (Status Port) needs to be enabled via jumper.  On the TL/2 and RL, there are no jumper standoffs, so the jumper pins will need to be shorted.

The TL/3, RLX and RSX use the Hensdale version of the PSSJ, which has more pins and have a regular, bidirectional DB-25 parallel port.  The Select-Input (Control Port) and Select Printer (Status Port) lines are present on the connector.

Contructing a Converter Cable


Line Name        IBM Pin                    Tandy Pin
Strobe 1 1
Data 0 2 3
Data 1 3 5
Data 2 4 7
Data 3 5 9
Data 4 6 11
Data 5 7 13
Data 6 8 15
Data 7 9 17
Ack 10 19
Busy 11 21
Paper-Out 12 23
Select Input 13 25
Linefeed 14 32/27
Error 15 28
Init 16 30
Select-In Output 17
Ground            18-25                    see below

Fortunately, the 34-pin card edge connector used by the Tandy was also used by 5.25" floppy drives.  The Tandy printer card edge connector is not keyed while the floppy connectors usually are, so you will need to get an unkeyed connector or cut the plastic inside.  A short ribbon cable and a DB-25 female port connector is all that is required.  As you can see, the cable is very straightforward until IBM pin 15.  Never connect the card edge pin 34 to anything on a DB-25 connector. Pins 14, 26 and 32 are often grounded or unconnected, you can use one of the unconnected pins you try to connect Select In (Output).  Pins 2, 4, 6, 8, 10, 12, 16, 18, 20, 22, 24, 31 and 33 are connected to ground, but one Tandy ground wire for each DB-25 ground pin should be fine.

Covox Speech Thing & Disney Sound Source

The Disney Sound Source is an 8-bit D/A converter that is housed in a parallel port dongle and connected to a speaker.  The circuitry inside the dongle is powered by a 9V battery in the speaker, and a 4-pin wire with an RJ-11 jack connects the dongle to the speaker.  It does not require a bidirectional parallel port, but it does have a problem with the Tandy card edge port.

The problem is that the Sound Source, in addition to the eight data lines, uses the Ack, Init and Select-Input (Control Port) lines to control the D/A converter.  As the card edge does not include the Select-Input (Control Port)  line, the adapter will not work correctly in a Tandy.  Disney indicated that with a special adapter, the Auto Linefeed line could be used instead, but this would require a small modification to the code needed to run the Sound Source.

The Covox Speech Thing is a simpler device that does not use anything other than the data port, which is connected to a purely-passive resistor network to an audio jack.  The Tandy PSSJ DAC can emulate a Covox device using a program called Setdac, assuming the Covox-supporting program obeys DOS LPT address assignments.

Xircom PE3 Series Parallel Port Ethernet Adapters
Iomega Parallel Port Zip-100 Drives
MediaVision Audioport

Will only work with the ports in the TL3, RLX and RSX.  It is possible it may work in a TX or older if the Select-Input (Control Port)  line is brought to the connector.

Digital Joystick Adapters

The parallel port can be used as an adapter for simple, Atari-style digital joysticks.  This requires the game have specific support for this method.  Dyna Blaster is an example of a game that came with such an adapter.  In this case, the adapter had two DE-9 ports for Atari joysticks.  As you may recall from a prior post, there are many, many devices that are compatible with the Atari port.  For a game released in 1992 like Dyna Blaster, the user could use a spare Sega Master System or Mega Drive (Genesis) controller.

The maker of the adapter generally would not assume that the user would know the type of parallel port he had (unidirectional, bidirectional, EPP or ECP) or its setting.  Using the basic unidirectional port, five inputs bits are available on the status port.  Coincidentally, the basic Atari CX-40 joystick has four directional contacts and one button.  Each one can use one status bit to signal whether the directional or button has been pressed.  More buttons cannot be supported in this manner without activating some kind of multiplexer in the joystick.

Each button and joystick position hovers over an open switch.  The switch is closed when the user presses the joystick in a direction or the button down.  One contact of each switch is connected to a separate wire on the cable, and the other half of every switch is connected to a common wire.  Using one of the four control or eight data bits for the common wire, twelve joysticks could be controlled in this way.  The joystick essentially becomes a loop connector.

The Atari joystick has no chips inside it, nor does a Sega Master System or Atari 7800 controller, but the Genesis, NES and SNES controllers all have a logic chip or two that requires +5v.  Fortunately, the Tandy card edge provides +5v on pin 34 (except for the 1000/A/HD)  Using a dedicated line is much easier on the port than trying to combine the power with parallel port data pins as the NES and SNES adapters used by SNESkey do.

Parallel to SCSI Adapters

I take no credit for this discovery, that goes to my friend Cloudschatze, but there does exist a parallel port to Shuttle SCSI adapter that apparently works with the Tandy card-edge port to transfer data in both directions.  Shuttle made an adapter with a driver that will work in a pure bidirectional mode and overlook the lack of a Select-Input (Control Port) line, unlike other adapters.  Therefore, with the card edge to DB-25 converter, the Shuttle adapter and a SCSI storage device, it is quite possible to get the parallel port to transfer data to the Tandy, at least the *X or better models.

LapLink Cable

It is quite possible to get the MS-DOS program Interlnk to work with the Tandy 1000s and their parallel ports, see here for details :

http://nerdlypleasures.blogspot.com/2014/09/tandy-1000s-and-interlnk-and-laplink.html

Monday, December 2, 2013

The 8-bit TMS9918 "Not Quite a Standard"

Released in 1979, the Texas Instrument TMS9918 Video Display Controller chip or its derivatives and successors was used in an enormous number of home computing devices, starting with the unsuccessful TI-99/4.  It was the nucleus of devices as varied from the MSX computers to the Colecovision and the Sega SG-1000.  The base design called for a common 8-bit CPU, some ROM and RAM, a 3-voice sound chip and some IO.  For the CPU, the 8-bit Z-80 processor, running at 3.58MHz, was by far the most common used.  For the sound chip, the TI, Coleco and Sega systems used a TI SN76489 3-voice PSG while the MSX standard called for the slightly more capable AY-3-8910 chip.

The resolution of the VDP chip is fixed at 256x192, there are 16 colors available in its palette, the text mode uses 40x24 pixel tiles, two of the graphics modes uses 32x24 pixel tiles and the other graphics mode uses 64x32 pixel tiles.  The chip supports 32 one-color sprites on the screen at a time with no more than 4 sprites on a line. The chip  requires 16KB of Video RAM, which is on a separate bus from the CPU RAM.  RAM in those days was at a premium, so main CPU RAM was often smaller (256 bytes for the TI 99/A and /4A, 1K for the Colecovision).

The chips biggest weakness going forward was its lack of support for hardware scrolling.  Scrolling in a game was usually by tile, 8 pixels.  This is not smooth and scrolling looked jerky on these machines.  While this was not a huge issue in the late seventies and early eighties, where one-screen videogames were the norm, when sidescrollers and vertical shooters became popular, the systems with the bare TMS9918 looked jerky.  Smoother scrolling could be done in software, but this was rarely attempted due to the performance penalties incurred.

The TI-99/4 used the TMS-9918, whereas the TI-99/4A used the TMS-9918A.  The "A" version of the chip adds support for graphics mode 2, which is what most games used.  Both systems only had 256bytes of RAM, which was an extreme hinderance for programmers.  Unlike most other machines, this system had a 3MHz 16-bit TMS9900 CPU.  However, only the system ROM and first 256 bytes of RAM were accessed in 16-bit on the TI computers, any official RAM expansions were accessed in 8-bit form.  The programmers usually had to obtain more RAM from the Video Memory, the access of which was terribly slow.

The Colecovision used a 3.58MHz Z80 and a TI SN 76489 sound chip.  It had 1K of RAM, 8K of ROM.  The home computer version, the Coleco Adam, added 80KB of RAM, 32KB of ROM, a keyboard and a dual cassette tape recorder.  The Adam used a 6801 to handle all the additional IO.

Sega's SG-1000 and SG-3000 used the standard VDP and 3.58MHz Z80.  It also uses the TI SN76489 but provided 8K for the CPU RAM.  Sega added support for hardware, doubled the sprite limits, allowed for colorful sprites and a 64 color palette in its VDP upgrade first seen in the Sega Mark III/Master System.  A YM-2143 FM Upgrade was also released for this system.  Sega eventually allowed a palette of 4,096 colors for the VDP variant in the Sega Game Gear.  The VDP of the Sega Mega Drive/Genesis extended this even further, but the original modes no longer work.  By that time the Z80 had been relegated to sound coprocessor status and the TI sound chip was secondary to the Yamaha 4-op FM OPN2 YM-2612.

The Spectravideo SV-318 and SV-328 were the models upon which Microsoft based the MSX standard.  The SV-328 came with 32KB of ROM, half for BIOS and half for BASIC, and 64KB of RAM.  The SV-318 is compatible but has only 16KB of RAM.  They use an Intel 8255 for IO handling and an AY-3-8910 for sound processing duties.  These machines successor, the SV-378, is only slightly different but fully MSX compatible and uses different, MSX-compatible, cartridges.  The MSX had no chance in North America, but did see success in Japan and in some European countries.  While MSX machines could offer 8-64KB of RAM, most offered at least 32KB.  RAM could upgraded beyond 64KB.

The MSX2 standard called for the V9938 VDP variant to be used.  This upgrade allowed for 256 colors, 80-column text modes, 16/256 color paletized modes, more colorful sprites and hardware vertical scrolling.  It required more Video RAM, 128KB.  Some systems also had support for more than 64KB of CPU RAM.  Horizontal hardware scrolling had to wait for the MSX2+ and the V9958 VDP.  The MSX2 and MSX2+ standards still called for the Z80 at 3.58MHz to be used.  Some MSX2+ machines had the YM-2143 OPLL (MSX-Music) chip.  The MSX turbo R was the last iteration of the MSX line and used an R800 @ 7.16MHz as the main CPU with a Z80 for compatibility and had 256-512KB of RAM.

In addition to MSX-Music, there were other musical upgrades for the MSX machines.  MSX-Audio used the Y8950 chip, which was an improvement over the YM2143 and the Adlib OPL2 YM3812 chip.  Certain of Konami's cartridge games had a SCC or SCC+ chip, which could use small waveforms.  Moonsound was a sound board that was released late in the MSX's life and used a YMF-278 chip.  Yamaha built in the equilavent of a FB-01 into its CX5M MSX System.

All the above systems have at least 16KB of Video RAM, all support the Atari-style 9-pin joystick port (often with support for a second button) and all support cartridges of some type or another.  Other systems with the TMS-9918 or its derivatives and similar architecture include the CreatiVision, Memotech MTX, Sord M5, Tatung Einstein and Tomy Tutor/Pyuuta.

Wednesday, October 17, 2012

Floppy Disk Useful Storage Space

Standard DOS PC Game formats use the following :

160KB Floppy - 40 tracks x 8 sectors x 512 bytes per sector = 163,840 bytes
180KB Floppy - 40 tracks x 9 sectors x 512 bytes per sector = 184,320 bytes
320KB Floppy - 40 tracks x 8 sectors x 2 sides x 512 bytes per sector = 327,680 bytes
360KB Floppy - 40 tracks x 9 sectors x 2 sides x 512 bytes per sector = 368,640 bytes
720KB Floppy - 80 tracks x 9 sectors x 2 sides x 512 bytes per sector = 737,280 bytes
1.2MB Floppy - 80 tracks x 15 sectors x 2 sides x 512 bytes per sector = 1,228,800 bytes
1.44MB Floppy - 80 tracks x 18 sectors x 2 sides x 512 bytes per sector = 1,474,560 bytes

All disks intended for 720KB and lower capacities are referred to as Double Density (DD).  1.2MB and 1.44MB disks are referred to as High Density (HD).  No game ever came on a 2.88MB floppy, which uses 36 sectors per track and Extra High Density Disks.  I am not aware of any games that came on a DMF formatted disk from Microsoft.  The DMF format allowed 1.68MB on a 3.5HD floppy, using 21 sectors per track but having double or quadruple cluster sizes and only 16 root directory entries.

Now the above shows the maximum available disk space using the standard formatted capacities.  These also are the exact sizes for standard img/ima disk image files.  Anything else is under/overdumped, protected or compressed.  However, when a disk is formatted in MS-DOS, the FAT-12 file system takes up a certain amount of space given above.  So, with a standard format, the usable space works out to be the following :

160KB Floppy - 158,720 bytes or 96.875% of theoretical capacity
180KB Floppy - 179,200 bytes or 97.222%
320KB Floppy - 322,560 bytes or 98.438%
360KB Floppy - 362,496 bytes or 98.333%
720KB Floppy - 730,112 bytes or 99.027%
1.2MB Floppy - 1,213,952 bytes or 98.792%
1.44MB Floppy - 1,457,664 bytes or 98.854%

So what takes up all that space that you cannot use?

All floppy and hard disks have their first sector reserved by the file system.  This sector is called the Master Boot Record (MBR) or the Boot Sector.  This tells the system if the disk is bootable and DOS that it is a DOS compatible disk.  Then floppy disks have two copies of the File Allocation Table (FAT) for redundancy.  The FAT indicates on which sector each file starts and how many sectors the file takes on the disk.  Each FAT copy can take 1-9 sectors, with 160K & 320K disks taking 1 sector, 180K and 360K disks 2 sectors, 720K disks 3 sectors, 1.2MB disks 7 sectors and 1.44MB disks taking 9.  The FAT maps all clusters on the disk using a 12-bit number.  .

Finally, the root directory entries have a certain number of sectors allocated to them, from 4-14 sectors.  Each directory entry takes 32 bytes and includes the file name and extension, the file attributes (read only, hidden, system, archive), date and time of creation or last modification, starting cluster and file size in bytes.  Single sided DD disks default to 64 root directory entries (4 sectors used), double sided DD disks 112 entries (7 sectors used) and HD disks 224 entries (14 sectors used).  An entry can be a file or a subdirectory with DOS 2.0 or higher.   This limit only applies to the root directory such as A:\ or B:\, a subdirectory like A:\MYDOCS\ can have any number of files in it.

So, for a 360K disk, 1 sector is used by the MBR, 4 sectors for the FAT and 7 sectors for the root directory entries.  368,640 bytes - (12 sectors x 512 bytes/sector) = 362,496 bytes.

But why cannot I fill every byte of that disk with data?

This is where the FAT cluster size comes into play.  Cluster sizes for all double sided non-HD floppy formats is 2 sectors.  So a file that is one byte large will take 1,024 bytes on the disk, as would a file that is 900 bytes large.  A file that is 1,025 bytes long will take 2,048 bytes on the disk, and the extra space is wasted.  On a 360KB floppy, you could never have more than 354 files on that disk, since 362,496/1,024 is 354.  Single sided DD floppy formats, HD floppy formats, excluding the 2.88MB and DMF floppies, use a cluster size of 1 sector.  So on a 1.44MB floppy, you could have 2,847 files on the disk, if each were no more than 512 bytes large.  The cluster size is not intended to be changeable.

But I need to squeeze just 1KB more!

So, you are finding how tight floppy drive space is, eh?  Well, if you cannot feel you can work without an extra 1-2KB, you need to modify the default format.  The safest was to do this is to reduce the number of root directory entries supported.  If you will never need to put more than 16 files on the disk, then you can gain 3KB extra space and not have to worry about DOS complaining it cannot recognize the disk format.

If you really wanted to push the envelope, you could eliminate the second FAT, but if a bad sector develops in the first FAT, your disk will be unreadable.  Plus you will only gain 1K more on double density media.  So for a 360K disk, if you went to the total extreme of having only 1 FAT table and no more than 16 root directory entries, the usable space would be 366,592 bytes.

How to tell if a disk image is really original :

A disk image will contain a OEM ID string starting with byte 3 in the image file.  It will be something like IBM  3.1, TAN 3.2, MSDOS5.0.  However, images can also contain strings like WINIMAGE or VFD2.1.  These labels are created when the WinImage or Virtual Floppy Drive program makes a new disk image and are obviously not original.  More expert eyes will quickly look at the boot sector to determine whether an image is original or has been modified or recreated.  The boot sector from an MS-DOS 5.0 formatted floppy will look very different from one created by Virtual Floppy Disk.  WinImage may even overwrite the original OEM ID string when imaging disks.  Fortunately the parts of the boot sector which OEMs modify is not essential to disk operation in DOS.

The second way is to look at the volume label.  If there is no volume label for the floppy, it may not be original.  This is far from definitive, because many games did not have volume labels on their disks, because their install programs did not use them.  If someone else tells you that his original disks have a label and your disks do not, then they may not be original.  Some games do look at the volume label for installation or to swap disks, most do not care.

The third way is to look at the File Date and Time.  If the file dates is in the 21st century, then the disk is not original.  Other disks may have most of their files with consistent dates, but one or two relatively or much later dates.  But this is not conclusive, because the disks may have been mastered on a system without a real time clock (which was not ubiquitous in the 1980s), or one which had the wrong date/time set.

The fourth way is to do a binary comparison between the files between your disk and a known good disk.