Archive for October, 2011

UDRE doesn't do what I thought it did

Friday, October 7th, 2011

I was having a very frustrating problem trying to make my Arduino behave as the keyboard for my XT - one particular piece of code (a 1ms delay loop) seemed to be taking much longer to run on the Arduino than it should, causing the Arduino to think that the clock low pulse from the XT was shorter than it was, causing it to fail to recognize the "reset keyboard" command.

After much hair-pulling, I tracked it down to the UDRE (UART (Univeral Asynchronous Receiver/Transmitter) Data Register Empty) interrupt, which fires to tell the program that a space has been cleared in the UART transmission buffer so the program can queue up the next byte that needs to be sent over serial (which is usually nothing, since the Arduino doesn't need to send anything to the host PC at that point). Or at least, that's what I thought it did - however, it turns out that it's not "a space has been cleared" but "a space is available" - i.e. it's level triggered, not edge triggered. That means that if we don't put anything out onto the serial line when the interrupt is received, it'll just fire again as soon as interrupts are turned on again. That explains why my 1ms delay loop was taking 20ms - it was spending most of its time servicing spurious interrupts instead of counting down. The fix was simple, just use the "transmit complete" interrupt instead of UDRE.

One reason that this was so hard to debug was that every time I tried to add code to debug it (by sending debugging information over the serial line) it went away (which is obvious in retrospect - if the serial line is busy most of the time, it doesn't interrupt so much). Sometimes thinking hard about what the problem could be is actually quicker than doing experiments to debug a problem.

Having found that, I realized that I had written some other code which assumes the UDRE was edge-triggered - the code for my Physical Tone Matrix. I made the same change there and now the menu screen appears and disappears instantly rather than sweeping down the screen like a DOS directory listing on an 8088. Unfortunately that means that the menu switch is now too sensitive - it flickers on an off while you're pressing the switch so you sometimes have to press it a few times to get it into the state you want. I'll change the capacitor for a larger one next time I have it open.

Import taxes to level the playing field

Thursday, October 6th, 2011

There's a big hurdle for the US manufacturing sector in that many products are much cheaper to produce in China or Taiwan. Part of the reason for this is that those countries have much less strict standards on things like pay, employee working conditions and pollution controls. Another way of looking at it is that US companies are saving money and skirting important social and environmental rules by outsourcing their manufacturing to countries which don't have these rules - with excellent consequences in terms of increased profits and cheaper products, but disastrous consequences in terms of the environment, the welfare of those who make the products, and US manufacturing jobs.

It seems to me that the US government should use its power to tax imports to level the playing field for US manufacturers by removing the incentive to manufacture elsewhere. In other words, the import tax on something should be the difference between what it costs to make something in the US and what it actually cost to make due to laxer regulations. Then, manufacturing for things sold in the US would (over time) move to the optimal locations based on where they were being sold and the where the raw materials were mined or recycled.

Suddenly making all our electronics more expensive by (maybe) a factor of 10 would be enormously disruptive so I suggest ramping up the tax gradually over a period of (say) 10 years or so. That would lessen the blow and give the US manufacturing companies some time to bootstrap. It also gives a great incentive to China to improve working conditions and emissions since doing so essentially wouldn't cost them anything (it would be covered by the corresponding reductions in import taxes).

In the long term, I would expect that the final cost of the manufactured products in question would stay about the same or even become cheaper than what they would be without these taxes. That's because as it becomes more expensive to hire people to do a menial job, it becomes more cost-effective to automate that job. The machine costs more to begin with (you need clever people to build and program it) but once it's up and running the unit cost per produced item is much lower.

There's a lot more to it than that, of course - China still has a big advantage in the expertise it has developed in building things, China sells to other places besides the US, and there are currency, debt, and trade treaty issues which further complicate matters in ways I don't completely understand. Still, I think it's an interesting idea to consider.

Trick for making double-sided PCBs

Wednesday, October 5th, 2011

I've now made several PCBs using the magazine toner transfer method. The same technique can be used to make double-sided PCBs (if you start with double-sided copper-clad board) but it is tricky to get the two sides lined up correctly, especially on larger boards. Here is a trick I found to make it easier.

When making the PCB design, make a row of squares of "copper" on the page off to one side, the same on both sides. When you print out the transfers these squares will become squares of toner. Put the two pages together, toner-side to toner-side and hold them up to a bright light. Adjust them until you can see that the squares are in the same place on both pages. Then, a quick press with the hot iron will melt the toner and stick the two aligned pages together. Then you can slip the board in between the two pages, iron on both sides and it should come out nicely aligned.

Subpixel image resampling results

Tuesday, October 4th, 2011

I implemented my cleartype for images idea and here are the results.




(This image, by the way, is part of the schematic of the original IBM CGA card - specifically, the composite DAC stage which I've mentioned before.)

The first image was resampled by Paint Shop Pro 4.12 (I know it's ancient, but I never got on with any of the newer versions). This resampling algorithm works directly on the sRGB values (it's not gamma corrected) so whenever there's a grey pixel in the output image, it's too dark.

The second image was resampled using proper sRGB<->linear conversion and an ideal sinc filter (which means it's very slow - several seconds per image). If you zoom into this, you'll notice some "ripples" around the horizontal and vertical lines which are due to the band-limited resampling - getting rid of them would require higher spatial frequenices than this image can accurately reproduce, so really the image is about as correct as it can be. Because the ripples are clipped on the high side, this does make the image slightly darker on average than it should be, but the difference isn't noticable to the human eye).

The third image was resampled by the "cleartype for images" algorithm (again with a sinc filter in linear space) using a band-limit of the subpixel resolution. As you can see, it's noticably sharper but does have annoying "fringes" of colour as thin lines move from one subpixel to another.

The fourth image is the same as the third except that the band-limit is that of the pixel resolution rather than that of the subpixel resolution (but the filters are still centered on the subpixels for the corresponding channels). This completely eliminates the fringing (yay!). As expected, it's not actually sharper than the non-cleartype image but some of the near vertical lines are smoother and the text is much more legible than any of the other versions.

Here's the same four methods with a colour image:




First let's look at the one with incorrect gamma - notice that a lot of the sharpness in the detailed regions is gone.

The second image is much better - the details remain sharp.

The third image is a mess - details exhibit aliasing problems because when the image has detail in just one channel, the band-limit frequency is three times the pixel frequency.

The fourth image is pretty similar to the second but there are a few places where sharp, near-vertical lines are a bit smoother, for example the brightly lit part on the left of the hat.

So, I think this experiment is a success. The downside is that I now need to go back through all my previous blog posts and resample the images again to improve them.

What is the CGA aspect ratio exactly?

Monday, October 3rd, 2011

Somebody asked on the Vintage Computer Forums about what the CGA aspect ratio is supposed to be. The answer is usually given as 4:3 (pixel aspect ratio of 5:6), but I was inspired me to find out what the relevant standards say it ought to be, exactly.

The relevant standard in question is SMPTE 170M - composite analogue video signal (upon which CGA is based). This gives an aspect ratio of 4:3, but that is for the full composite picture which 242.5 lines rather than the CGA's 200. The width is given in terms of timings - 63.556 microseconds per scanline total minus 1.5+9.2 microseconds for the blanking period, with a tolerance of +0.3/-0.2 microseconds, so between 52.556 and 53.056 microseconds altogether. Since the full horizontal period consists of 455 CGA low-res pixels horizontally, the full NTSC active area is the equivalent of (376.25-379.83)x242.5 CGA pixels. Re-arranging, that gives us a screen aspect ratio for CGA of between 1.362 and 1.375 - slightly wider than the usually quoted value.

However, no TV or composite monitor of the time was manufactured to have aspect ratio tolerances as precise as 3% - 4:3 would have been well inside the error bars.

How to set 200-line text modes on EGA

Sunday, October 2nd, 2011

If you tell an EGA card that it's connected to a monitor capable of 350-line modes by setting the appropriate switches on the card itself, it will by default use these 350-line modes for its text mode (using the 14-scanline character set instead of the 8-scanline one, yielding higher fidelity text).

But sometimes you want a 200-line text mode. In particular, there is an obscure 160x100 16 colour mode of the CGA which was obtained by using 80-column text mode, filling the text characters with the "left vertical bar" or "right vertical bar" characters (221 and 222 repectively), disabling blinking and setting up the CRTC for 100 visible rows of 2-scanline characters. This was used by some Windmill Software games and a few others. With VGA you can do the same thing with 400-line text mode (by using 100 visible rows of 4-scanline characters).

But how do you do it with EGA? One way is to program all the registers directly (as one must do on CGA) using the timings, sync polarity and palette from 200-line graphics modes and all other settings from the 350-line text modes. As mentioned in yesterday's post, we must use the palette 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 instead of the usual 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f because the monitor will interpret bit 4 as intensity instead of secondary green in 200-line modes.

Another way (which may be either more or less compatible with clone EGA cards) is to fool the BIOS into thinking a 200-line monitor is connected. The EGA BIOS reads the card's switches only once at boot time and then stores the results in BIOS memory at 0x40:0x88 and uses this value instead of the hardware value at mode-setting time. The low nybble of the value at this location is 3 or 9 for 350-line monitors and the corresponding values for 200-line monitors are 2 and 8 respectively. So an alternate algorithm is to check the byte at this address, decrement the low nybble if it's 3 or 9, store it back, do the "int 0x10" to set text mode, set the Maximum Scan Line Register to 1, disable blink and fill the text characters with a vertical bar.

Here is the Vintage Computer Forum thread that inspired me to find this out.

Why the EGA can only use 16 of its 64 colours in 200-line modes

Saturday, October 1st, 2011

This was a question which puzzled me when I first found out about it, but now that I understand all the history behind it, it makes perfect sense.

The IBM PC (5150) was originally designed output to an NTSC television in mind - hence the 4.77MHz clock speed (4/3 the NTSC color carrier frequency - allowing the video output and CPU clock to share a crystal). It was thought that home users would generally hook their PCs up the TV rather than having a separate, expensive, monitor. Another major limiting factor in the design of the CGA was the price of video memory - the 16Kb on the card would have been fairly expensive at the time (it was as much as the amount of main memory in the entry level PC). TV resolution is 912x262 at CGA 2-colour pixel sizes in non-interlaced mode, but TVs (especially CRTs) don't show all of the image - some of those scanlines and pixels are devoted to sync signals and others are cropped out because they would be distorted due to the difficulties of approximating high frequency sawtooth waves with high-voltage analog circuitry. So 320x200 4-colour and 640x200 2-colour packed pixel modes were chosen because they were a good fit for both 16Kb of memory and TV resolutions.

That system did work quite well for many home users - lots of CGA games have 16-colour composite output modes. But it wasn't so good for business users. These users tended not to care so much about colour but did care about having lots of columns of text - 80 was a common standard for interfacing with mainframes and for printed documents. But 80-column text on a TV or composite monitor is almost completely illegible, especially for colour images - alternating columns of black and white pixels in a mode with 320 pixels horizontally gets turned into a solid colour by NTSC. So for business users, IBM developed a completely separate video standard - MDA. This was a much simpler monochrome text device with 4Kb of memory - enough for 80 columns by 25 rows of text. To display high quality text, IBM decided on a completely different video standard - 370 scanlines (350 active) by 882 pixels (720 active) at 50Hz, yielding a 9x14 pixel grid for high-fidelity (for the time) character rendering. In terms of timings, the character clock is similar (but not identical) to that of the CGA 80-column text mode (presumably 16.257MHz crystals were the closest they could source to a design target of 16.108MHz). To further emphasize the business target of the MDA card, the printer port was built into the same card (a printer would have been de-rigour for a business user but a rare luxury for a home user). Business users would also usually have purchased an IBM 5151 (green-screen monitor designed for use with MDA) and IBM 5152 (printer).

CGA also had a digital TTL output for displaying high quality 16-colour 80-column text (at a lower resolution than MDA) on specially designed monitors such as the IBM 5153 - this seems to have been much more popular than the composite output option over the lifetime of these machines. The two cards used different memory and IO addresses, so could coexist in the same machine - real power users would have had two monitors, one for CGA and one for MDA (and maybe even a composite monitor as well for games which preferred that mode). The 9-pin digital connectors for CGA and MDA were physically identical and used the same pins for ground (1 and 2), secondary intensity (7), horizontal sync (8) and vertical sync (9) but CGA used 3, 4 and 5 for primary red, primary green and primary blue respectively whereas MDA used pin 7 for its primary video signal. MDA also used a negative-going pulse to indicate vertical sync while the CGA's vertical sync pulse is positive-going.

So for a while these two incompatible standards coexisted. The next major graphics standard IBM designed was the EGA, and one of the major design goals for this card was to be an upgrade path for both home and business users that did not require them to buy a new monitor - i.e. it should be compatible with both CGA and MDA monitors. This was accomplished by putting a 16.257MHz crystal on the card and having a register bit to select whether that or the 14.318MHz one would be used for the pixel clock (and by having the on-board video BIOS ROM program the CRTC appropriately). By 1984, it was not out of the question to put 128Kb of RAM on a video card, though a cheaper 64Kb option was also available. 64Kb was enough to allow the highest CGA resolution (640x200) with each pixel being able to display any of the CGA's 16 colours - these would have been the best possible images that CGA monitors such as the IBM 5153 could display. It was also enough for 4 colours at the higher 640x350 resolution - allowing graphics on MDA monitors. With 128Kb you got the best of both worlds - 16 colours (from a palette of 64) at 640x350.

IBM made a special monitor (the 5154) for use with the EGA. This monitor could display both 200-line and 350-line images (deciding which to use by examining the vertical sync pulse polarity), and allowed users would be able to take advantage of all 64 colours available in 350-line modes. The video connector was again physically the same and pins 1, 3, 4, 5, 8 and 9 had identical functions, but pins 2, 6 and 7 were repurposed as secondary red, green and blue signals respectively, allowing all 64 possible colours. But they wanted this monitor to be compatible with CGA cards as well, which meant that in 200 line mode it needed to interpret pins 3-6 as RGBI instead of RGBg and ignore pins 2 and 7. So even with a 5154, the EGA needed to generate a 4-bit signal when connected to a CGA monitor, disabling pins 2 and 7.

I guess the designers thought that sacrificing 48 of EGA's colours in 200-line modes was a small price to pay for making the EGA monitor compatible with CGA cards. Presumably they thought that if you had an EGA card and an EGA monitor you would be using 350-line mode anyway, or be running legacy CGA software which wouldn't miss those extra colours.

One thing I haven't mentioned here is the PCjr graphics. For the purposes of the discussion above it's essentially the same as CGA (it has the same outputs) but it's more flexible and slower due to the use of system RAM as video RAM, as many 8-bit microcomputers did in the 80s.