Tuesday, March 18, 2014

The Monochrome Experience - CGA, EGA and VGA

A few posts back, I discussed some of the notable features of the Monochrome Display Adapter and Hercules Graphics Card.  In this post, I intend to talk about monochrome graphics on other adapters of the time, namely CGA (and its derivatives Tandy and PCjr.), EGA and VGA.  All these adapters could support monochrome monitors, although they were at their best when connected to color displays.

CGA, Tandy & PCjr.

At first, if you wanted to connect a CGA card to a monochrome monitor, you typically would use a monochrome composite monitor.  The RCA jack on the CGA card would be used.  If you were really lacking for a monitor, a black and white monitor would do in a pinch, but you probably would have to run the composite output of the CGA card through an RF converter box.  The resulting graphics would be nowhere near as sharp as with a straight composite connection.  Lets start with our test images :

Space Quest II - 320x200x4c "RGB" Mode (Mode 4)
Space Quest II - 640x200xMono "Composite Color" Mode (Mode 6 with Composite Color bit set)
Monochrome computer monitors typically would offer a high-contrast color : white on black, green on black or amber on black.  Text was sharp at 40 columns and tolerable at 80 columns, especially when the screen size was 12" or less.  Since composite monitors (in North America) refreshed at 60Hz, there was less need for the long persistence phosphors (and resulting ghosting) that was seen on the 50Hz MDA monitor.

The Compaq Portable used a 9" green composite screen.  The IBM PC Portable used a 9" amber monochrome composite screen connected to a CGA card.  Even though the IBM machine is close to a clone of the Compaq machine (which in turn is a clone of the IBM PC), their monitors are quite different.  The IBM monitor is a bog-standard monochrome composite screen and connects with an internal version of the RCA jack on its CGA card.  For this reason, you will see jailbars on the screen as you would see them on a color screen because the of the NTSC color decoding.

The screen on the Compaq is quite interesting.  The Compaq's video adapter supports both MDA and CGA graphics, and in the 80x25 text mode will act like an MDA card, not a CGA card.  Snow be gone!  The display is a "dual-sync" display apparently capable of accepting both a 15KHz and 18KHz horizontal scan frequency signal.  Otherwise the card acts like a CGA card.  The input must be able to accept the TTL signals from the CGA card and convert them to grayscale.  The resulting image is much sharper than on the IBM card (especially in 640x200 graphics) and will not show jailbars.

Early IBM CGA cards had a very basic monochrome support capability through the composite connector.  Essentially there for the low intensity eight colors would transform into black, gray and white.  For the high intensity colors, the same pattern would be seen, slightly brighter.  Later CGA cards took hue into account when converting RGB colors into luminances, so that there would be a unique shade for each of the 16 colors.  Here is an approximation of how the test images would look with the IBM PC Portable's amber monochrome screen and the early and late CGA cards.

IBM PC Portable with Early CGA Card, 3 Intensities Available
IBM PC Portable with Late CGA Card, 4 Intensities Available (note extra detail on the broom)
CGA Mode 6 was a 640x200 monochrome mode, where the active pixel could be a color, but the background color would always be black.  Any of the 16 CGA colors could be used, but typically the color would be white/light gray or white/high intensity white.  The IBM PC BIOS did not support selecting the foreground color in this mode, to do this you had to use the Color Select register.  It was not typically used because most CGA games preferred the more colorful if lower resolution Modes 4 & 5.  Often, if you saw these graphics, it was intended for color composite graphics.  The Wizardry games have intentional support for this mode, as do other games like SimCity, which benefits more from a high resolution than colorful graphics.

When the Color Composite bit was set in the Mode Control register, on a color composite monitor, the mode would display artifact colors.  On an RGB or monochrome composite monitor, the color composite bit made no difference to the graphics in a real CGA card.

CGA Mode 5 was a 320x200 color mode on an RGBI monitor, which a palette of cyan, red and white (intensity selectable).  On a composite monitor, whether color or monochrome, it displayed 2-3 (early CGA) or 4 (late CGA) shades of intensity, no color.  Mode 5 would typically be supported as an option if the game supported Mode 4 color graphics or Mode 6 color composite graphics or Tandy/EGA/MCGA/VGA.

Eventually, there would be monochrome TTL monitors that would accept a CGA signal.  In this case, the monitor converts RGBI into intensities of one color. Early LCDs were also monochrome devices, and brightness levels for each individual pixel were usually limited to on and off, although the IBM PC Convertible did advertise three levels of brightness for the CGA 4-color graphics modes.  The PC Convertible's LCD had a native resolution of 640x200 and stretched 320x200 graphics modes horizontally by two.  The aspect ratio would seem wrong except for applications intended for the Convertible's screen (typically from IBM).  Here are approximations of how the test graphics would look on the Convertible's LCD screen :

640x200xMono Color Composite Mode (Mode 6 with Composite Color bit set)

320x200x4 RGB Mode (Mode 4)
Tandy and PCjr always displayed 16 intensities of one color when displayed on a monochrome composite monitor.  It looks something like this :


EGA

IBM's EGA card could be connected to a color RGBI TTL monitor like the 5153 and support 8x8 text (Modes 0/1 and 2/3) and  color 200 line modes (Modes 4, 5, 6, D & E).  It could also a high resolution 6-bit RGB TTL monitor like the 5154 and support 8x14 text, color 200 and 350 line graphics modes (mode 10).  Finally, it could be connected to a monochrome TTL monitor like the 5151 and support text at 9x16 (Mode 7) just like an MDA card, and additionally supported a 640x350 line monochrome graphics mode (Mode F).  A real MDA monitor must be connected to use Mode F, which was similar to the Hercules Graphics in that it allowed each pixel to be turned on or off.  It did not work in the same way as Hercules, and far fewer games supported it.  While Hercules graphics were 720x348 pixels, usually only 640 horizontal pixels were actively used in Hercules as it was much easier to convert from 320 pixel graphics modes, so Hercules did not often have an advantage in resolution.  However, since IBM derived the graphics mode from the text mode, each individual pixel can be made to blink or display in intense video.  I do not know of any game which may have supported this functionality.  Mode F is the only graphics mode supported when the EGA is connected to an MDA monitor.

Microsoft Flight Simulator 3 - 640x350x16c Mode 10
Microsoft Flight Simulator 3 - 640x350xMono Mode 0F
In order to use an MDA monitor with an EGA card, the dipswitches or jumpers on the card must be set correctly.  Switch 3 must be ON, switches 2 & 4 must be OFF.  The EGA card, when connected to an MDA monitor, can be used with a CGA or a secondary EGA card connected to a color monitor.

Even though EGA can be connected to an MDA monitor and at first glance look identical to the MDA's text mode, using unusual text character attributes can show differences compared to the MDA.  This can be seen in 101 Monochrome Mazes, a game IBM released strictly for the MDA.  When you run this game on an EGA or VGA card, you will not see exactly the same "graphics".  This game uses text attributes that fall outside the canonical 16 IBM valid MDA attribute choices for the EGA and VGA.  Compare the following :

101 Monochrome Mazes MDA

101 Monochrome Mazes EGA/VGA
MCGA/VGA

When IBM released its PS/2 computers, it advertised monochrome analog high scan-rate monitors like the 8503 alongside more expensive RGB color analog high scan-rate (VGA) 8512 or 8513 monitors.  Systems with built in monitors like the PS/2 Model 25 could be ordered with a monochrome or color monitor.  The price difference was several hundred dollars at the beginning, so monochrome monitors were much more attractive for certain business and educational purchasers.

IBM's early VGA monitors designated four pins in the HD-15 VGA monitor connector to inform the card whether it was a mono or a color monitor.  Three of the bits would inform the VGA whether a monochrome monitor, a color monitor or an 8514 monitor was being used.  Later, these bits would be reused.  A real IBM monochrome monitor and VGA would output pixel information on the green pin only.

VGA used an 18-bit color  palette, with 6-bits for red, 6-bits for green and 6-bits for blue.  Each pixel on the screen could be set to any of 256 colors from the 18-bit palette.  When the monitor informs the card that it is a mono card, the VGA will convert the 18-bit color value into a 6-bit grayscale value by color summing the R, G and B values.  In this manner, 64 intensities of the monitor color could be displayed using the 256 color graphics mode 13.  In other modes, which support no more than 16 colors on screen at any one time, up to 16 grayscale shades would be available from the 64 that the monochrome monitor and the VGA could display.

Conquests of the Longbow - 320x200x256c Mode 13 Color
Conquests of the Longbow - 320x200x"256c"Mode 13 Grayscale
By the late 80s and early 90s, monochrome plasma displays were common on laptops, and this design allowed them to give some definition to what would otherwise have been color graphics.  However, this display technology was somewhat limited, as the gas plasma display in the IBM PS/2 Model P70 (a luggable) could only manage 16 shades of the orange color of that display.  In 320x200, IBM would selectively dither a 2x2 block of pixels (remember that the display stretches 320x200 to 640x400) to simulate the 64 intensities that should be available.

Some VGA games, including many of Sierra's SCI engine adventure games, had a driver which Sierra claimed would allow for up to 256 shades of "gray".  This was nonsense, the hardware was limited to 64 shades of gray due to the 6-bits per color regardless of being displayed on a monochrome or color VGA monitor.  This driver would show the same graphics whether used on a color or a monochrome VGA monitor.  However, the advantage to using this driver on a monochrome monitor is that by using only the grayscale options in the full VGA color palette, Sierra could ensure a good representation of the color graphics in grayscale and need not subject its color graphics to the VGA conversion formula.

Nonetheless, Sierra's driver did a very good job of preserving the detail of the color graphics for those forced to use color screens.   Pinball Fantasies also supported a "mono" graphics display setting, using up to 64 grayscale shades in the Mode X modes it supports, 320x240 amd 360x350.

Pinball Fantasies - 320x240x256c Mode X Color
Pinball Fantasies - 320x240x"256c" Mode X Grayscale (note the loss of detail on the table art)

Saturday, March 15, 2014

The Perfect Keyboard

In my opinion, the perfect keyboard has yet to be made.  I envision a keyboard with the solid construction of an IBM Model F keyboard, the removable keycaps, LED faceplate and keycap lettering of the IBM Model M, the compatibility and much the layout of a Northgate Omnikey Ultra with a bit of the Apple Extended Keyboard.

The layout of the Model F, either the PC/XT or the AT version may be lacking for the 21st Century, but its build quality is second to none for PC keyboards.  It uses buckling spring technology with stiff springs over a printed circuit board where the keyswitches are located.  No membranes in these keyboards.  They used steel and heavy duty plastic and weighed almost as much as the Model M, which used slightly lighter materials.  Although rather annoying, every part of every key could be replaced.  One lesser known feature of the Model F was that it did support N-key rollover, which the Model M does not.

Improvements of the Model M were keycaps that could be replaced without needing to replace key stems, making it much easier and quicker to rearrange the keyboard to the user's preference.  The basic layout is standard today.  The lettering IBM used on the keys and the LED panel is classic and professional.  However, if you wanted a more stylish design, you can by replacing the keycaps.  Replacing keycaps is easier than having to replace the keystem of the Model F.  The cables, whether coiled or straight, were fairly heavy duty as these cables went.  The SDL connector at the rear allowed you to change cables instead of using adapters, but today a lower cost connector could be used instead.

The Model M was criticized for putting the function keys above the keyboard instead of on the left side as on the PC/XT and AT keyboards.  The Northgate Omnikey Ultra T put a set of function keys on the left side as well as on top.  F1-F10 on the left side is in the same place as you would have found them on a PC/XT or AT keyboard, and F11-F12 are to the left of the Escape key, as they were added later.  There was a switch to designate the top or the side rows of function keys are the primary and secondary function keys.  With 24 function keys, any user should have enough keys for just about anything he or she wished to have a separate button.

Northgate's keyboards could emulate a wide variety of keyboards, including the PC/XT keyboard, the AT/Model M keyboard, the Tandy 1000, the Amstrad PCs, the ATT 6300, even the Amiga 2000 with dipswitches.  My ideal keyboard would keep as much of this functionality as possible, using a dipswitch panel.  A special driver should not be required for support in this day and age where cheap and powerful microcontrollers are readily available.

The Northgate Omnikey keyboards support N-key rollover, which the IBM Model M does not.  They also have their keyswitches soldered onto a PCB.  The IBM Model M uses a membrane sandwiched between the black plastic key housing frame and the PCB.  The whole structure of the keyboard is held together by plastic rivets.

One thing about the Northgate and Apple keyboards is that they split the large + key on the numeric keypad into + and = (Northgate) and + and - (Apple).  The Apple keyboard have added five keys, F16-F19 and an eject/power key on various keyboards.  It also has F13-F15 where the Print Screen, Scroll Lock and Pause/Break keys are on an IBM keyboard.  F13-F19 usually have no commonly defined role and there are plenty of keys in my ideal keyboard to accomodate them.

F16-F19 on an Apple keyboard occupy the area where the option LEDs are on an IBM Model M keyboard.  Many keyboards have LEDs next to the Caps Lock, Num Lock and Scroll Lock keys.  I am neutral to this.  However, the keys that would be where the LED panel would be should be exactly the same size and use the same keystems as the rest of the keyboard.

The modern Windows 104-key keyboard includes the Windows keys, which seem to be a functional equivalent of the Apple Command keys.  Occasionally, Windows keys can be helpful, but they can also very very annoying in their default usage.  However, the menu key is a useless key that can be replicated with a right mouse button click or a shift F10.  There is no reason for it to have a key as it really cuts down on the size of the spacebar.  In my perfect keyboard, it does not exist on the spacebar row.  There are plenty of function keys to assign it to.
                                                       
Big L shaped enter keys, who needs them?  I have never found them to be particularly helpful, and they cause the \ key to be put in odd places.  Northgate shortened the right shift key, which is the only real flaw in its non-101 designs.

Monday, March 10, 2014

Early PC CD-ROM Games

The Compact Disc may have been first prototyped in the 1970s, and the first CD-ROM drives available in the late 1980s, but it was the 1990s when CD-ROM games came to PCs.  At first, however, they were little more than the same games on floppy disks with some kind of Redbook CD-Audio. Not long afterward, they were used to store digital audio in files and more detailed or higher resolution graphics and movies.

The first known CD-ROM game released for the IBM PC was The Manhole.  This was a port of the floppy disk version of the B&W Macintosh original by Robyn and Rand Miller.  The Millers would later go on to create Myst, but in the Manhole, you can see a definite beginning of the style of game for which they would become famous.  The Manhole was released sometime around July, 1990.  It supports VGA, MCGA, EGA and Tandy graphics.  However, while the game uses VGA and MCGA graphics modes and supports a much wider variety of colors than the 16-color EGA and Tandy graphics modes, it displays no more than 16 colors on the screen at any one time.  This was common back in 1989 when the floppy disk version was released, as using many more colors meant redrawing the graphics.

The CD format for The Manhole was a mixed-mode CD, consisting of one data track and one or more audio tracks.  The CD standard can support a maximum of 99 tracks, and the Manhole uses 95 audio tracks  (this does not count the data track) to store music, speech and sound effects.  There is no need for a sound card to hear full audio with the CD version.  Since there is no save feature, the game is run entirely off the CD-ROM.  The floppy disk version supported Adlib, Roland MT-32 and Tandy 3-Voice music and Sound Blaster and Tandy DAC for speech.  The audio is obviously much improved in quality and quantity over the floppy version.  The graphics, however are exactly the same as the disk version.  This version of The Manhole is very obscure today, and the game was re-released twice on CD-ROM format, once for DOS and Windows as The Manhole - New and Enhanced Edition (also on floppy) and once for Windows as The Manhole - CD-ROM Masterpiece Edition.  These editions are much more common, much more impressive graphically, and use far fewer CD Audio tracks.

Just about one year later (1991), Sierra began to release its first CD-ROM conversions.  While there probably were other games released beforehand, this was the first time a gaming company committed substantial resources and effort into promoting the new "multimedia" experience offered on disc. First came Mixed-Up Mother Goose, then Jones in the Fast Lane, followed by Stellar 7, King's Quest V and Space Quest IV.  Like the Manhole, all had previously been released on floppies.  They were also more expensive than the older floppy versions.  Don't forget that a CD-ROM was a very expensive proposition in 1991, Sierra was charging $795.00 for a CD-ROM kit.  At least the hardware, a SCSI CD-ROM and a Mediavision Pro Audio Spectrum (later 16), were high quality products.

Sierra's evolution of the CD-ROM format was simple. Jones in the Fast Lane included all its speech on one large audio track.  The game would instruct the CD-ROM driver to play samples at specific times on the track.   Music would require separate music hardware, as the only one CD-Audio track can play at a time.

Stellar 7 used its single CD-Audio track for speech during cutscenes for voice acting and the music.  Sound effects were unchanged from the floppy version, relegating users to Adlib and MT-32 sound effects.  One benefit to having all the music on one track was there would be less of a pause for the music to restart.  However, preserving the timing of the track was especially critical, especially when making copies.

Mixed Up Mother Goose signalled a different approach.  This time, the CD-ROM would be used strictly as a data CD, with the speech samples stored in one large audio file instead of on an audio track.  A DAC like the Sound Blaster, Pro Audio Spectrum, Thunderboard, Tandy DAC or PS/1 Game/Audio Card would be required to hear the speech, which would be stored in an 8-bit sample format.  Without this innovation, no more than 74 minutes of speech could be stored on a CD-ROM.  Additionally, it was very annoying when the CD had to spin up to play a voice sample.

The most limiting aspect of the CD-ROM was the total inflexibility of pre-recorded audio.  To adjust the parameters of a piece of music played on an MT-32, the programmer would only need to send a few kilobytes of data to the module.  To adjust the music on a CD-ROM meant changing to another track.  With 74 minutes maximum and 99 tracks, the musician could easily run out of space.  LucasArts' games using the iMUSE dynamic sound system would always use the CD-ROM versions for voice acting.

Most CD-ROMs use the ISO-9660 format, which is standard for CD-ROMs and is widely used.  Some of these early CD-ROMs, especially those from Sierra, use an earlier format called the High Sierra Format.  MS-DOS's MSCDEX supports either format, but DOSBox has trouble with HSF.  DOSBox will not IMGMOUNT a HSF image, but will MOUNT a drive using Daemon Tools and read the disc from that drive.  Also, you can convert HSF images to ISO images using a program like Nero Burning ROM.

King's Quest V and Space Quest IV would continue the large audio file approach.  A common approach to voices at this time was to use company members to voice various parts.  Roberta Williams and other employees of Sierra, would lend their voices to many of these CD-ROM releases.  Unfortunately, the resulting quality of the voice acting was somewhat lacking, since these individuals were not trained actors.  Many other companies would follow Sierra's lead.

One company that never went the "Starring the programmers" route was LucasArts, which always sought professional voice talent for its CD-ROM conversions beginning with LOOM and Indiana Jones and The Fate of Atlantis.  Professional voice actors had been relegated to roles voicing cartoon characters, announcers, bit parts and the like.  Now there was a whole new avenue of employment for them for companies who cared enough about their expensive product to spring for decent voice acting.  Eventually, "name" actors would be given roles.

Another type of CD-ROM release which began to appear in 1992 or so is the compilation release.  On these CDs, there was nothing you could not have obtained on a disc, but the size of a CD allowed the inclusion of several (older) games (Interplay 10th Anniversary) or a game and all its expansion packs (Wing Commander Deluxe).

Data compression and relatively low bitrate techniques helped keep the size of speech files in check, and companies began to put full motion video on their discs.  Interplay would re-release its Lord of the Rings : Fellowship of the Rings with animated scenes taken from the Ralph Bakshi movie of the 1970s.  Sierra King's Quest VI CD-ROM would include a longer, better animated version of the introduction contained in the previously released floppy version.

One final issue with CD-ROMs games of the time is that these versions always seemed just to have something goat-glanded onto the floppy version.  When the 7th Guest turned out to be a huge hit in 1993, all of a sudden the market for CD-ROM only games became attractive to developers.  The 7th Guest used high resolution graphics throughout, digitized video around every corner and plenty of voice acting.  It also came on two CD-ROMs.  Far too much would have had to be cut to put the game on floppies, so Trilobyte took a gamble and did not bother to release a floppy version.

Just after The Seventh Guest, LucasArts released Day of the Tentacle simultaneously on floppy and CD.  Up to this point in time, CD releases would lag several months behind floppy disk releases.  Additionally, by the time the CD was released, there would be interface changes and the like.  For DOTT, the game was more or less identical except that the CD version had a very large audio file.  Floppy users still had the benefit of speech during the opening scenes.  By the end of 1993, many, many games were being designed with CD-ROM first and then a cutdown floppy version would follow, usually compressed onto many disks.

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

Thursday, March 6, 2014

IBM PCjr. Upgrades

IBM PCjr. Internal Modem

The IBM PCjr. Internal Modem fits in a special slot inside the PCjr.  The Modem sits at COM1 and this is undoubtedly its most useful purpose in the modern era.  The BIOS designates the internal serial port, with no modem installed, as COM1.  The resources the serial port uses, I/O 278H and IRQ3, are those typically assigned to COM2.  This causes programs no end of confusion, and usually a program like COMSWAP is used to redesignate the serial port as COM2.

The Internal Modem uses the resources typically assigned to COM1, I/O 3F8H and IRQ4.  By installing one, even if you never intend to use it, the BIOS will assign the Modem to COM1 and the serial port to COM2.

If you want to use a serial mouse and you don't have the Internal Modem installed, you can use the Cutemouse v1.91 driver.  You will need to use the following command line argument /S13.  This tells the driver to use the device at COM1 and IRQ3.

IBM's PCjr. Internal Modem is based on the Novation 103 Smart Modem, which uses a command set somewhat different from the Hayes compatible command set most terminal emulator programs expect.  However, once you learn the basic commands and how to implement them in a terminal emulator, it can be used, as it was intended, at 300 baud.  It does not have any speaker on it, so the only way to know whether you have connected is to review the messages sent from the modem.  All commands can be shortened to the first letter, like the Hayes command set in many instances.

To initialize the modem, use the command : I

To set the format, use the command : F.  The modem supports the following serial data formats (data bits:parity:stop bit) :

0 - 7:M-1
1 - 7-S-1
2 - 7-O-1
3 - 7-E-1
4 - 8-N-1

The default is 7-E-1.  M is Mark Parity, S is Space Parity, E is even Parity and O is Odd Parity.  To set the format to 8-N-1, use the command : F 4.  The initialize and format commands can be carried on the same command line, separated by a comma.  Using an 8-bit speed will show more corrupt characters than using the 7-bit speed, but it is faster and more compatible with BBS terminals that still allow for dialup.

The command to dial is appropriately called "dial", and you type in the number after it.  I would recommend putting a "w" just before the number to ensure the modem dials using tone rather than the old-fashioned pulse and add a short delay to avoid any confusion by noise at the line gets taken off the hook.  This is a command to dial : D w15555555555.

The command to answer is : A.  The hangup command is : H.

Any commands to the modem must be prefaced by a control character.  The default character is 0E/Ctrl N. This is the equivalent of the AT control character of the Hayes commands. The command string must be terminated by a carriage return/Ctrl M, just like Hayes.  However, there is no +++ equivalent, the modem will always view one of the 255 ASCII codes as a command code, but it does allow you to change the default ASCII value with the N command.

The program ProComm, 2.4.3, which was very popular back in the day, will work with the PCjr. Internal Modem.  The default strings to enter in the setup menu look like these :

^N I, F 4 ^M
^N D w##########
^M
^N H ^M

If you have a phone service that uses a stuttering dial tone to indicate that you have new voicemail, this modem may interpret the stuttering signal as a BUSY signal and do nothing.  Clear your voicemail.

Many of the few BBSes expect a faster transmission rate than 300 baud or a more robust modem solution. One BBS that more or less works is the Capitol City Online BBS out of Frankfort, KY.  Its telephone number is 502-875-8938.

IBM PCjr. Parallel Printer Attachment

This sidecar adds one parallel port and was a very popular add-on for the PCjr, which did not come with a parallel port.  The parallel port is a standard DB-25F connector, unlike virtually every port on the back of the PCjr.  It uses  the standard CGA LPT1 resources, I/O 378H and IRQ7.  If there is no parallel printer sidecar installed, then the serial port will receive the LPT1 designation.  When the parallel port is installed, the BIOS will reassign LPT1 to it.  IBM did not allow the settings on the parallel port adapter to be changed, so only one parallel port is supported.  There is a fairly simple mod to change the I/O to the LPT2 278H address, you can find it here : http://www.brutman.com/PCjr/lpt2_mod.html

The parallel port is a unidirectional port by default, capable of nibble transfers.  There is an easy mod to make the parallel port bidirectional.  This will double throughput when an external devices wants to send data through the parallel port to the computer.  The instructions for the mod can be found here : http://www.brutman.com/PCjr/parallel_port.html  This mod will also work with the ISA-based IBM PC Printer Adapter and the IBM Monochrome Display and Printer Adapter and probably all clones that implement a parallel port strictly using TTL logic.

The parallel port is useful for more than just connecting to printers, although it can do that too.  I have connected it to a 2008 vintage Brother MFC-8860DN and it was able to print from DOS.  It is far more useful to use with a 100MB zip drive or an Ethernet adapter like the Xircom PE3-10BC.  The Xircom's packet driver (PE3PD.COM) and test program (PE3TEST.EXE) work just fine with an 8088 machine and a PCjr.  The packet driver is initialized as follows for a PCjr. with an unmodified parallel port :

pe3pd sint=60 non

The non tells the adapter to operate in the non-Bidirectional mode (a.k.a. Unidirectional), and sint=60 assigns the Packet Driver services to software interrupt 60H.  The driver can autodetect the presence of the adapter on any of the LPT assignments and the Interrupt.

Using the Xircom adapter, you can transfer files to and from the PCjr. with relative ease.  There is a suite of TCP/IP utilities called mTCP, which you can get from here. http://www.brutman.com/mTCP/  The DHCP client utility especially useful for automatically obtaining all the critical information (IP, Gateway, Nameserver) from your route to connect to the Internet.  I typically start up the packet driver and dhcp client in a batch file which I created (MTCP.BAT) and it looks like this :

c:\mtcp\pe3pd sint=60 non
set MTCPCFG=c:\mtcp\tcp.cfg
c:\mtcp\dhcp.exe

There are other useful utilities.  The IRCJR functions as a basic Internet Relay Chat client.  You can use it to chat on IRC.  It will not download files from IRC though.  I use it to connect to the Vintage Computer IRC channel on irc.slashnet.org, /join #vc.  SNTP will obtain the time and date from an internet server and set the time and date in DOS.  This is very useful for systems without a Real Time Clock or you want more exact time.  There is also a Telnet client with ANSI emulation for all your text-based terminal needs.  There is also a basic FTP client.  It can copy (get) multiple files, but not sub-directories.

To actually use these utilities, you need to create a file called TCP.CFG.  At a minimum, the following is required :

PACKETINT 0x60
HOSTNAME PCjr

The PACKETINT must correspond with the Packet Driver's software interrupt, but the HOSTNAME can be anything.  DHCP will add or change the necessary configuration every time you start the DHCP server.  Individual mTCP utilities will have their own settings in this file.

The most important utility is the FTP Server.  This utility lets you operate your PCjr. as an FTP Server.  The practical application of this utility is an easy and modern method to send from and receive files to your PCjr.'s (or any DOS machine) drives.  You setup the FTP Server on the PCjr,'s end and use a modern FTP Client on your modern PC like Filezilla.  This is what I use, and with a few tweaks to Filezilla, it works well.

In Filezilla, set the transfer type to binary, the maximum number of connections to 1, the timeout to 200 seconds and the speed limits to 25K/25K.  If you have a bidirectional port, you can push the speeds higher, but 50KB/50KB is the max you will probably be able to get from a PCjr.  A V20 or faster CPU will speed up transfer rates a bit.  Filezilla expects to talk to a modern machine, and it runs so fast that the flow control will get screwed up waiting for the slow PCjr.

On the PCjr. FTP Server, I recommend the following lines added to TCP.CFG :

FTPSRV_PASSWORD_FILE ftppass.txt
FTPSRV_LOG_FILE log.txt
FTPSRV_EXCLUDE_DRIVES AB
FTPSRV_FILEBUFFER_SIZE 16
FTPSRV_TCPBUFFER_SIZE 16
FTPSRV_PACKETS_PER_POLL 10

The first two are required for FTP Server to run.  The remainder give the maximum buffer sizes and exclude the floppy drives.

jrIDE

jrIDE is an amazing sidecar that was recently (2012) developed by PCjr. enthusiasts, mainly Alan Hightower.  It combines 1MB of SRAM, a real time clock chip and can boot 16-bit IDE drives.  It can support an IDE master and an IDE slave drive, and it can effectively support hard drives up to 8GB (the maximum of using DOS and FAT16).

The RTC is a Dallas 12887 module, and is socketed for replacement.  The date and time is set by a program called rtc, loaded in the autoexec.bat file on startup.  IRQ 1, 2 or 7 can be selected for its operation.  I suggest IRQ2 because the parallel port uses IRQ7 and the keyboard on a regular PC uses IRQ1, which could possibly confuse some programs that are not PCjr-aware.  The Speech Attachment also uses IRQ1.  Using an IRQ really is not essential for this function.

In order to set the date and time, you will need a small program called rtc.com, available here:
http://www.retrotronics.org/svn/jride/trunk/prebuilt/jr/

To set the date and time for the RTC, first, set the correct date and time in DOS using the DATE and TIME commands.  Next, run the rtc.com program with the /r switch.  This will send the date and time you told DOS to the RTC.  Finally, add the rtc.com program to your autoexec.bat file with the /d switch.  Upon every bootup, this will fetch the correct date and time from the RTC and automatically set it in DOS.

The IDE header is at a right angle and has all 40 pins. Pins 1 and 2 are at the bottom of the board.  The key pin can (via jumper) be used to provide +5v to power low-power devices like Disk On Module (DOM) devices or Compact Flash cards.  The PCjr., without a power sidecar, is not likely able to supply sufficient power for a 2.5" or 3.5" hard disk drive.  I found that even a DOM had difficulty when it was the third card in the system.

The jrIDE BIOS is based on the Universal XT-IDE BIOS, so it should be able to support drives up to 8.4GB in size supported by Int 13 and maybe higher if true LBA is used..  Practically speaking, the use of DOS (pre 7.1) is going to limit you to 4GB drives.  You will need PC-DOS or MS-DOS 4.0 or better to use a primary partition (primary drive) greater than 32MB and logical drives greater than 32MB.  With DOS 4.0 or above, you can have a primary partition of 2GB (C:) and one or more logical drives in the extended partition within the remaining 2GB (D:).  With DOS 3.3, below, you will be limited at a maximum to a primary 32MB partition (C:) and 32MB logical drives in the extended partition, D:-Z: for 736MB total hard disk space.  With PC-DOS 3.0-3.2, only one DOS 32MB partition is available for a C: drive per disk.  DOS 2.1 allows only one 15MB partition for C:.  Using DOS 5.0 or above requires patching the DOS system files as outlined here : http://www.brutman.com/forums/viewtopic.php?f=3&t=224&p=1978&hilit=stacks#p1978

Of that 1MB of RAM, you can have 736KB total conventional memory, even though the PCjr. only counts to 640KB on the startup screen.  However, without a device driver loaded in config.sys, DOS will only see 128KB of RAM, and that is before it loads itself and the video buffer is taken into account.  The remaining RAM is the slow RAM controlled by the video controller.

The device driver to use with the PCjr. and jrIDE is JRCONFIG.SYS v3.10 from PC Enterprises.  The most basic use of it is to load it in config.sys like so :

DEVICE=C:\JRCONFIG.SYS -V64

When this driver is loaded with a jrIDE, it will give you 608KB of conventional memory free.  Physically, this memory is between the first, slow 128KB and the video buffer window which starts at 736KB.  The lower 128KB is reserved for DOS and the video memory.  You can use what is left over for a RAM disk.  RAM disks are especially important if you are using a null-modem to transfer data to or from a PCjr. because the machine lacks DMA.

A system booted to DOS with JRCONFIG v3.10 and no other drivers or an autoexec.bat loaded will report 753,664 total bytes (736KB) and 610,656 bytes free (596KB).  You can also try an earlier version of the driver called JRCONFIG.DSK v2.14, which should require less RAM.

The driver has many command line switches, the only one that most people will need is -v64.  This will allocate 64KB of video memory within a 32KB video page so that programs using the 320x200x16 and 640x200x4 modes will work.

The only major downside to using JRCONFIG is that it is not really compatible with Cartridge BASIC.  REM out the line with JRCONFIG or simply rename config.sys when you need to use Cartridge BASIC and DOS.  Cartridge BASIC is limited to 64KB free memory and freaks out if it is told there is more than 128KB in the system.

Since JRCONFIG uses software interrupt 60, which is the default software interrupt for many Ethernet DOS packet drivers, assign the packet driver to use a different interrupt.

You can find JRCONFIG here : http://www.brutman.com/PCjr/pcjr_downloads.html  jrconfig.zip is the v2.14 version, jrcfg310.zip is the v3.10 version.

To obtain a jrIDE, join the PCjr. Web Forum, here : http://www.brutman.com/forums/  Be prepared to spend well over $100 to obtain an assembled one, and you may have to wait.  The board assembly itself requires only through hole soldering, but the project is still quite the undertaking.

NEC V20

Most IBM PCjr. will have a socketed 8088 CPU, located underneath the disk drive.  If you are unlucky and received one of the last units sold by IBM, the CPU will be soldered onto the motherboard.  You can remove the 8088 CPU from the socket and replace it with a V20 CPU for a decent (10-15%) speed boost while retaining nearly 100% compatibility with software.  The most common part number for the V20 is the NEC D70108.  If you have a soldered CPU, you can always remove the CPU and solder in a 40-pin socket.

The V20, V30, 80186 and 80286 and later CPUs are not 100% compatible with 8086/8088 software because the 8086/8088 have undefined/illegal (as opposed to undocumented) opcodes whereas the later CPUs do not.  The only game I am aware of, after a great deal of searching, that may not support the V20 PCjr. is Lode Runner, but every version of the game available for download works just fine with a V20.  Every cartridge game for the PCjr. works fine with the V20.

Increasing the clock speed of the 8088 or V20 is not for the faint of heart.  There is one 14.318MHz crystal on the PCjr that is used for all system timing.  This includes the CPU clock speed, the 8253 Timer input and the OSC signal.  In the PC it is arguably more difficult to overclock because the DMA chip uses the CPU CLK signal for its timing.  Replace that crystal and all three frequencies, which are derived from an Intel 8284 Clock Generator chip, will change.

There is a PCB design called PC-SPRINT that essentially directs a higher clock solely to the CPU.  It is a separate board which is piggybacked on the existing CPU socket.  It has a separate crystal and a second 8284.  Typically, speeds of 7.16MHz or 7.37MHz are stable, although some people have boasted of obtaining a 9.54MHz speed.

IBM PCjr. Speech Attachment

This sidecar contains a TMS5220 chip very similar to the chips used in the Speak & Spell toys of the time and sounds identical.  It uses two methods to digitize and playback sound, LPC (linear predictive coding) and CVSD (continuously variable slope delta modulation).  The TMS chip handles the LPC while the CVSD is handled by a MC3418.  Interfacing to these chips is through an 8255 PPI and 8254 Timer.  All audio output is routed through the system board multiplexer just like the 3-voice chip.

LPC allows for the use of compressed digitized samples and the sampling rate is of higher quality.  The Sppech Attachment uses this method to play its built in vocabulary of 196 words, phrases and sound effects. Its 32K ROM chip resides at CE000-CFFFF.  The voice playback of the vocabulary samples has an 8KHz sample rate.  The built-in vocabulary is very easy to access in BASIC.  You can add your own (compressed) vocabulary words with a computer that has a program that can encode the recorded sound into the format of the Speech Attachment.

CVSD allows for recording voice and sound through the microphone input and play it back.  Normally voice recording is limited to disk size, but if you have a large hard disk, this will be less of a concern.  The recording and playback speed through the microphone ranges from 1.8K-4.8K per second.  CVSD encodes at 1 bit per sample, so that audio sampled at 38.4 kHz is encoded at 38.4 kbit/s.  The default addresses used are FB98-FB9F, FF98 and FF9F.  It also uses IRQ1.

The best program I have discovered to use the Speech Attachment is MAKETALK from PC Enterprises.  It will allow you to play the vocabulary and build sentences for recording by an external device and also allow you to record and playback to the limits of your disk space.

IBM PC Compact Printer

IBM released this low-cost printer to go with its low cost entry system.  It is a thermal printer and uses an 8-pin head.  It has just one button for line feed and a power switch and LED.  The printer uses the PCjr. serial BERG connector that plugs directly into the PCjr, but adapters exist that can convert it into a DB-25 connector for use with a regular serial port and a PC compatible.

This printer can print 56 characters per second, but only prints from left to right.  It can print 80 characters per line in standard mode, and supports double width mode, compressed mode, compressed/double width mode and underlining.  It prints all the 256 IBM ASCII and Extended ASCII characters except for the 64 block characters at 176-223.  It also supports a 480-bit graphics mode.

The Compact Printer uses an 8.5" wide paper roll.  The rolls typically are not perforated, so the user must cut or tear pages to length.  The lack of perforations makes it ideal for banners and graphics.  Staples and OfficeDepot sell 8.5" rolls, typically 98' or 164'.  Thermal printers do not need ink ribbons, ink or toner cartridges, so their operational cost is strictly from the paper.

The printer has a data transfer rate of 1200bps and uses 1 start bit, 8 data bits, no parity and 2 stop bits.  In order to obtain reliable operation, as in no missing or skipped characters, you should use the following parameters with the MODE command :

mode COM2: 1200, n, 8, 2, p

Without the IBM Parallel Printer Attachment, the BIOS assigns the serial port to LPT1.  Thus devices printing only to LPT1 should not have a problem.  If you have a Parallel Port attached, then it will be assigned to LPT1.  You can redirect LPT1 to COM1 or COM2, depending on which your printer is designated, by the command :

mode LPT1:=COM1: or

mode LPT1:=COM2:

The last issue with this printer is loading the paper.  First, you lift the smoky colored cover.  Next, there is a tab on the left side that you push in, allowing the paper roll enough room to fit inside the housing.  Fit the cardboard portion of the roll onto the two pegs.  The end of the paper must be feeding upwards and counterclockwise.  Release the latch on the side to let the printer allow the paper to be fed to the thermal head.  Take the edge of the paper, fold it in a U shape, and guide it down behind the beige plastic bar.  Use the paper feed button until the paper catches.  Gently adjust the paper, once you can see it through the underside of the thermal element so that it is straight and then close the latch on the side to hold the paper in place.  Make sure you have enough paper so that a little bit of paper appears over the plastic cover when you put it down.

Tandy Mod

One upgrade you may want to make to your system board is to make it more compatible with games that support the 160x200x16, 320x200x16 or 640x200x4 graphics modes only with a Tandy 1000.  Some games (essentially just about every PC game released after 1985) will allow you to select Tandy graphics, but when you play these games on a stock PCjr., you will only see every other line.  The Tandy mod will fix this problem.  A good guide to the mod with instructions can be found here : http://vintagemashups.net/2011/12/ibm-pcjr-tandy-1000-graphics-mod/

Other problems may prevent a game from working on a PCjr., including when a game auto-detects a Tandy 1000, keyboard or joystick input issues, graphical anomalies due to the differences between the Tandy and PCjr. graphics controllers, disk-based copy protection failures.  You may need to set the audio multiplexer to output 3-voice music before starting a game.

Of PCjr. games, the only game I know of that doesn't like the Tandy mod is ScubaVenture, which will throw a line out of place about every time the screen scrolls.  The line is solid, which makes it more difficult or impossible for the player to pass it without losing a life.  Mouser also shows some graphical garbage on the top of the screen with the Tandy mod, but it does not interfere with game play.

Memory Sidecars

If you are not fortunate enough to obtain a jrIDE, you can add memory expansions that were sold for the PCjr. if you can find one.  These typically come with 128KB or more of RAM, and without any modifications you can add up to 512KB of RAM in this way to the system.  IBM's Memory Expansion is configured through four dipswitches on the back of the sidecar.  Only one switch should be "ON" for each Expansion, the rest must be OFF.  You could attach up to four expansions, and the first expansion should have switch 1 ON, the second expansion switch 2 ON, the third expansion switch 3 ON and the fourth expansion switch 4 ON.

The IBM Memory Expansion can be modded to have 512KB on a single sidecar.  You must remove the sixteen 64Kx1 DRAM chips and replace them with 256Kx1 DRAM chips.  Just to the right of the large 74S409 chip, you will see three solder pads closely aligned in a row, with a trace connecting the left and center pads.  You must cut that trace and connect the center and right pads.  It may be possible to mod this card to 736KB, but I do not know how.

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