Classic Computer Magazine Archive Article from Compute! magazine

Readers Feedback

The Editors and Readers of COMPUTE!

If you have any questions, comments, or suggestions you would like to see addressed in this column, write to "Readers' Feedback," COMPUTE!, P.O. Box 5406, Greensboro, NC 27403. Due to the volume of mail we receive, we regret that we cannot provide personal answers to technical questions.

Assemblers And Monitors

I am a little confused about the difference between an assembler and a machine language monitor. Would you please explain the functions of each?

Adam C. Stuart

Simply put, an assembler is a program designed for one specific purpose—helping you write machine language programs. A monitor can be used for that purpose, too, but can also perform other memory-management tasks. Most programmers use an assembler for writing long ML programs and a monitor for writing short, experimental routines or debugging the code produced by an assembler.

To illustrate the difference, let's say that you have a short machine language program beginning at location 49152 ($C000) on the Commodore 64. A monitor allows you to examine the contents of any memory location. If you type M C000 C00C from the monitor, the following display might appear:

: C000 A9 42 20 06 C0 60 20 D2

: C008 FF 20 D2 FF 60 00 00 00

This memory display, like other monitor output, is in hexadecimal (base 16) notation. The numbers in the leftmost column are memory addresses; the numbers to the right show the actual contents of each successive location. Unless you're very familiar with hex notation and the 6502 instruction set, it's difficult to understand the program in this form. As a convenience, the monitor can translate machine language instructions from a series of raw numbers into more descriptive mnemonic labels. This process is called disassembly. Here's how a monitor would disassemble the numbers seen in the display above:

, C000 A9 42 LDA #$42

, C002 20 06 C0 JSR $C006

, C005 60 RTS

, C006 20 D2 FF JSR $FFD2

, C009 20 D2 FF JSR $FFD2

, C00C RTS

Each three-letter mnemonic stands for a single ML instruction. In this example, the LDA (LoaD A) instruction loads the ASCII value for the letter B (hex $42) into the computer's A register, also called the accumulator. The JSR (Jump to SubRoutine) instruction calls a subroutine, much like GOSUB in BASIC. RTS (ReTurn from Subroutine) terminates a routine, much like RETURN in BASIC.

The converse of disassembly is assembly, which lets you write a program by typing in mnemonics rather than numbers. To assemble the first line of the above program, for instance, you would type this line into the machine language monitor:

A C000 LDA #$42

This puts the numbers $A9 and $42 into memory locations $C000 and $C001, where the computer interprets them as LoaD A with $42.

In addition to memory display, disassembly, and assembly, a monitor can perform other general tasks such as moving the contents of one memory area to another area, filling memory with a certain value, saving and loading an area of memory to tape or disk, and so forth. Monitors are so useful, in fact, that several computers, including the Commodore PET, Apple II, and Commodore 128, include one as a built-in feature.

An assembler, as the name implies, is intended to do only one job—assemble an ML program from mnemonics. Since it usually can't disassemble the contents of memory, do memory moves, etc., an assembler is less versatile than a monitor. And programming with an assembler requires two steps instead of one. First you write a text file containing all the program instructions; this file is called the source code. Then you run the assembler, which translates the source code into executable object code. At first, the assembler sounds more cumbersome to use. But except for very short programs, it's considerably more convenient than a monitor. To illustrate, here is what the source code for this program might look like (this example is written in a format for the Commodore 64 PAL assembler; other assemblers are very similar):

100 sys 700

110 .opt p4

120 *=49152

130 letter = 66

140 chrout = $ffd2

150 ; print 'b' twice

160 lda #letter

170 jsr print2

180 rts

190 print2 = *

200 jsr $ffd2:jsr $ffd2

210 rts

220 .end

This assembler lets you write, save, and reload the ML source code as if it were a BASIC program, using sequentially numbered program lines. (Other assemblers provide similar functions.) just as in BASIC, you can combine more than one statement on a single line (see line 200). Descriptive names can be given to constants (line 130), variables, ROM routines (140), and memory locations within the program itself (190). Assemblers also permit more flexibility of expression than monitors: Usually, decimal and hexadecimal numbers can be used interchangeably, and the assembler can evaluate strings and complex expressions as well. In this program, for instance, you can replace LDA #LETTER with LDA #$42, LDA #66, LDA #"B", or even LDA #6+6*10).

The ability to use labels makes well-written assembler code much more readable than a monitor disassembly. The instruction JSR PRINT2, for instance, is more informative than JSR $C006. Labels also eliminate the need for tedious address calculations and simplify the process of relocating a program from one area of memory to another. When writing this program for an assembler, you don't need to know where the routine PRINT2 will actually end up in memory; the assembler handles such details for you automatically. With a monitor, on the other hand, you need to calculate the actual address of the subroutine before you can type in the JSR instruction that calls it. To move this program from location 49152 to 24576, you would simply change the origin statement in line 120 to*=24576 and reassemble the code. The assembler automatically adjusts everything to fit the new location.

Even greater flexibility is offered through pseudo-ops (pseudo-operations), which control various assembler functions. For instance, the .OPT pseudo-op(line 110) tells the assembler where to send its output. By changing this instruction you can send output to memory, a disk file, the screen, or a printer. Assembling to a printer is particularly useful for making documentation, since the output includes everything you would see in a monitor disassembly (addresses, opcodes, and mnemonics) as well as all the comments and so forth contained in the assembler source file.

Other assembler pseudo-ops let you perform more advanced operations such as a conditional assembly, which can include different segments of code (perhaps specific to various computers) in the assembly only when certain IF tests are satisfied. For long programs, a linked assembly allows you to assemble two or more separate source files into a single object file. The latter method was used to assemble the SpeedScript word processor, since the source code for that program is too long to fit in the computer's memory all at once.

Atari BASIC Errors

Only recently have I become obsessed with home computers. As a novice, I decided to start with an Atari 400 (a 1982 model, I believe) and a cassette recorder. After many hours spent typing in your programs, I was constantly rewarded with error messages. I finally discovered that the BASIC cartridge accompanying the computer had since been revised twice. Not being able to locate the revision C cartridge in Dallas, I wrote Atari, No answer yet. Can you provide any insight? Also, is the 400 capable of using a disk drive, or am I stuck with tape?

Tom Rowan

It's true that Atari BASIC has been revised twice since your Atari was made, but it's unlikely that this is the source of your problems. The two revisions— known as revision B and revision C— mainly fix bugs in the original Atari BASIC cartridge. These bugs, however, don't cause spurious error messages. Usually they either lock up the computer entirely or mangle text strings. Your error messages are almost certainly due to mistakes in the programs, not problems with your BASIC.

You don't say whether the error messages appear when you're typing the programs or running the programs. Atari BASIC is one of the few BASIC languages that has instant syntax checking, so if you get an error immediately after typing a line and pressing RETURN, it usually means that a BASIC command was mistyped, a parenthesis was omitted, or the command is being used improperly. Examine the line carefully for any typos. If you can't find any, refer to the Atari BASIC Reference Manual to see if the command usage is legal. For example, the statement A=CHR$(A$) generates an error because the CHR$ function is intended for concerting a number into a string, and the variable A$ is already a string.

Error messages encountered while you're trying to run a program are not due to syntax errors. Usually they indicate that the program is asking the computer to do something impossible. For example, the one-line program 10 GOTO 20 generates the message ERROR 12 AT LINE 10. If you look up this error number in the Atari BASIC Reference Manual, it means Line Not Found. The command GOTO 20 tells the computer to branch to line 20, but this program has no line 20. (If you're typing in listings from COMPUTE!, you can avoid most of these mistakes by using our "Automatic Proofreader" program found in every issue.)

If you'd still like a revision C Atari BASIC cartridge—worth having for only $15—you can order one from Atari. (Atari Corp., Customer Relations, 390 Caribbean Drive, Sunnyvale, CA 94088.) Be patient, though. It takes quite some time for Atari to fill these orders.

The Atari 400 is quite capable of using a disk drive if it has at least 16K of Random Access Memory (RAM). Early 400s had only 8K RAM. You can find out how much memory your 400 has by plugging in BASIC, typing NEW, and entering PRINT FRE(0). A 16K machine should return a number around 13000. However, we recommend at least 32K for use with a disk drive. A drive requires that you load a special program called a Disk Operating System (DOS), and this would consume more than half the available memory on a 16K system, leaving very little room for your BASIC program. The 400 can be upgraded to 48K or 64K, but the memory board installation isn't trivial. Also, for a few dollars more you could probably buy a new 800XL or 65XE.

Commodore 128 Sprites

I really enjoy programming with my new Commodore 128. However, using sprites has left me quite frustrated. The system guide's explanation of sprites doesn't explain how you can have more then eight sprite definitions in memory. Is there any way to do this?

Matt Lindquist

The Commodore 128 has room for only eight sprite shapes in its sprite definition area (memory locations 3584-4095). However, BASIC 7.0 includes a command (SPRSAV) which lets you move sprite shapes from strings into the sprite definition area and vice versa. Here is one form of SPRSAV:


This command moves the definition for sprite 1 into the string A$. Now the shape data is stored for later use. Here's the opposite form of SPRSAV:


This command moves the shape data stored in A$ into the definition area for sprite 1. Of course, you can replace the name A$ with any legal string variable name.

The following program draws 16 sine waves on the screen, each positioned a little differently, then saves the sprites in the array A$ using the SSHAPE command. After all the shapes have been drawn and saved, sprite 1 is displayed on the screen. SPRSAV is then used to flip between the various sprite shapes. The rapid display of shapes makes the sine wave appear to move.

(Note: The underlined up-arrow (?) in line 30 means to hold down the SHIFT key while pressing the up-arrow key. This will produce the pi (?) symbol.)


20 DIM A$ (16)

30 FOR V=0 TO ?*2 STEP ?/8

40 GRAPHIC 1,1

50 FOR X=0 TO 23 STEP .2:Y=INT(11+10*SIN(X/2+V)):DR AW 1,X,Y:NEXT

60 SSHAPE A$(SN),0,0,23,20


80 SPRITE 1,1,2,1,1,1,0

90 MOVSPR 1,120,80:MOVSPR 1,90#3


Apple Double Hi-Res Graphics

I'm having trouble understanding how the double high-resolution graphics mode works on my Apple IIc, How does the computer store the color and dot information? Is it possible to convert a normal hi-res picture to double hi-res format?

Robert Colello

An Apple II that has 128K of Random Access Memory (any Apple IIc, or a IIe with extended 80-column card) can display pictures that have twice as many pixels across as normal hi-res pictures: that's 560 pixels in double hi-res versus the normal 280-pixel resolution. This display mode works in about the same way as 80-column text mode. For every byte of normal display memory, there's another byte with the same address in another bank of memory, called auxiliary RAM. In normal hi-res mode, one byte of display data tells the computer how to draw seven pixels on the screen. In double hi-res, 14 dots can be drawn in the same space on the screen. The first seven dots are read from auxiliary memory and the second set comes from main RAM.

One double hi-res screen occupies 16K of memory between addresses 819216383 ($2000-$3FFF) in each bank. Unlike standard hi-res, there's only one double hi-res screen, so it's not practical to create animation with page flipping.

Here are some routines that will help you get started with double hi-res graphics. When run, they create machine language programs called DCONVERT and DHGRSAVE. If you load a normal hi-res picture into hi-res screen 1 (at 8192) then BRUN the DCONVERT program, it converts the picture to double hi-res format and displays it.

To save this or any other double hires picture to disk, BRUN the DHGRSAVE program, then enter BSAVE filename ,A$2000,L$4000 (replace filename with the name of your choice). The graphics image is saved in the same format used by Dazzle Draw and other double hi-res programs. If you save the image file on a ProDOS disk, you can then load it with Dazzle Draw and modify the picture.

80 FOR I =24576 TO I + 161: READ A: POKE I, A:NEXT

90 PRINT CHR$ (4);”BSAVE DCONVERT, A$6000, L$A2"

100 DATA 141,126,192,173,94,192,173,87,192,173,82

110 DATA 192,141,13,192,141,0,192,173,80,192,169

120 DATA 0,133,254,169,32,133,255,160,0,177,254

130 DATA 72,72,41,15,170,189,146,96,141,163,96

140 DATA 104,74,74,74,74,41,7,170,189,146,76

150 DATA 141,162,96,104,16,11,173,163,96,201,128

160 DATA 173,162,96,42,144,27,78,163,96,136,48

170 DATA 10,177,254,8,10,10,40,106,74,145,254

180 DATA 200,173,162,96,44,59,96,240,2,9,64

190 DATA 145,254,173,163,96,41,127,141,5,192,145

200 DATA 254,141,4,192,200,192,40,208,168,165,254

210 DATA 105,127,133,254,144,2,230,255,165,255,201

220 DATA 64,208,150,165,254,105,39,133,254,201,120

230 DATA 208,136,96,0,3,12,15,48,51,60,63

240 DATA 192,195,204,207,240,243,252,255

80 FOR A=4096 TO A+47: READ I: POKE A,I: NEXT

90 PRINT CHR$ (4);"BSAVE DHGR SAVE, A$1000, L$30"

100 DATA 160,0,132,252,132,254,169,32,133,253,169

110 DATA 64,133,255,141,1,192,173,87,192,177,252

120 DATA 145,254,141,85,192,177,252,141,84,192,145

130 DATA 252,200,208,239,230,253,230,255,165,253,201

140 DATA 64,208,229,96

Saving PCjr Screens

I have been experiencing trouble with BSAVEing SCREEN 5 on my PCjr For some reason, the computer loads only half the picture when I try to bring it back into memory.

Marc Ramirez

The PCjr was designed to be as compatible as possible with the IBM PC, but there are several differences, most notably the lack of DMA (Direct Memory Access) hardware that speeds certain operations on the PC. On the other hand, the PCjr has better color graphics than the PC. Its SCREEN 5 mode gives you 320 X 200 resolution with 16 simultaneous screen colors. These don't represent fixed colors as in the PC-compatible modes. Instead, each of the 16 colors can be redefined to use any of the 16 possible colors, making available the advantages of color indirection.

The IBM PC color/graphics card contains 16K of onboard RAM for its own use. Because the RAM is part of the color card, there is no conflict when both the screen and the microprocessor want to access memory at the same time. However, references to addresses $B8000-$BC000 are redirected to the color card's memory, which permits the microprocessor to update screen memory and redraw the screen directly.

The PCjr, however, has no memory at $B8000. Screen memory is taken from the main store of RAM, usually at location $18000. This explains why the PCjr is slower than its big brother. The graphics chips need to access screen memory constantly while building the screen, and since this memory is on the main address bus, the microprocessor can't get at memory to execute instructions while the graphics chips are using it.

However, IBM realized that many commercial programs try to update the screen by storing values directly into screen memory at $B8000. To keep the PCjr compatible with these programs, IBM modified the address circuitry to redirect references to $B8000 to the actual screen memory area. However, only 16K of memory is redirected. Since a SCREEN 5 screen is 32K long, this explains why you're seeing only half of the picture.

When you use the sequence

DEF SEG=&HB800:BSAVE "screen" ,0,32768!

the first 16K of memory is saved from the area at $18000, but the rest of the picture is saved from $BD000-$C0FFF, since this memory range is not relocated. This second half is just whatever random bits are read when this nonexistent memory is saved. Instead, you need to use

DEF SEG=&H1800:BSAVE "screen",0,32768!

to save the screen, and

DEF SEG=&H1800:BLOAD "screen"

to load it back. If you try to load images saved from the original range of $B8000-$C0FFF, the second interleaved half of the picture will be garbage. If you use two or more graphics screens, the additional screens are stored behind the first one at lower memory locations. The first SCREEN 5 screen would be at $18000, the second would be stored at $10000, and so forth.

TurboDisk With 64 SpeedScript

Now that the commented source code for SpeedScript is available in book form, I have found ways to make the program work in all kinds of situations. Here are a couple of SpeedScript modifications I have found very useful.

Only two POKEs are needed to allow you to use "TurboDisk" (the fast load utility published in the April 1985 issue of COMPUTE!) with SpeedScript. First, load in your copy of SpeedScript (version 3.0 or higher). Now enter these POKEs in direct mode (without line numbers). Be sure to press RETURN after typing each line:

POKE 2481,191

POKE 4938,8

Now resave the program, using a different filename (perhaps SPEEDSCRIPT.TURB) to differentiate it from the original. To use the modified program, simply activate TurboDisk as usual, then load and run SpeedScript. You'll find that text files are loaded much faster than usual. If you exit SpeedScript, you must reactivate TurboDisk with SYS 49152.

A second useful change has to do with word wrap—SpeedScript's ability to automatically move a word down to the next line when it's too big to fit on the current line. Word wrap is great for making text readable, but creates headaches when you need to align the right margin or line up decimal points past the fortieth column. The following program replaces SpeedScrip’ts Verify command (which I have never used) with a function that toggles word wrap on and off. Type in the following program and save a copy, then run it and follow the prompts (tape users note the line change below).






49152 DATA 162,35,189,12,192

49157 DATA 157,26,20,202,16

49162 DATA 247,96,173,219,8

49167 DATA 201,177,208,17,169

49172 DATA 169,141,219,8,169

49177 DATA 32,141,220,8,165

49182 DATA 197,201,31,240,250

49187 DATA 96,169,177,141,219

49192 DATA 8,169,251,141,220

49197 DATA 8,96

After POKEing a short ML routine into memory, the program instructs you to load SpeedScript (3.0 or higher), enter SYS 49152, then run SpeedScript. Try toggling word wrap on and off by pressing CTRL-V (ordinarily the Verify function).

If you use tape instead of disk, you may not want to give up the Verify function but can easily afford to live without the Directory command, which is useless with tape anyway. In line 49157 of the program, change the 26 to 98. Then change the checksum value in line 10 from 6412 to 6484.

When you're satisfied that the modification works, exit SpeedScript. Disk users should enter POKE 2895,23 to change the Verify command from CTRL-V to CTRL-W (for Word wrap). Tape users should enter POKE 2898,23 to change the Directory command from CTRL-4 to CTRL-W. After that's done, resave SpeedScript under a new filename that reflects the change.

Bruce S. Gordon

Thanks for the suggestions. Incidentally, the penalty you pay for turboloading with SpeedScript is that available text memory is reduced from 43,445 characters to 39,299 characters.

Improved Atari Line Delete

Like many BASIC programmers, I usually number my programs with an increment of 10. Often, however, after editing and debugging, there is no longer any pattern to line numbering. This short utility program has a little more versatility than "Line Deleter For Atari," published in the January 1986 issue of COMPUTE!. As in the former, LIST the utility to disk or cassette, then load your BASIC program and ENTER this utility. Type GOTO 32700 in direct mode, then input the beginning and end range to be deleted. You can now delete only existing line numbers. When the deletion is finished, press RETURN to remove the utility from your BASIC program.



32702 ? CHR$(125) : X=PEEK(138)+PEEK(139)*256

32703 B=PEEK(136)+PEEK(137)*256 : X=B:QQ=0:POSITION 2,2

32704 LN=PEEK(X)+PEEK(X+1 ) *256

32705 IF LN

32706 IF LN=32700 THEN 32710

32707 ? LN:QQ=QQ+1:IF QQ= 18 THEN 32710

32708 IF LN>=EN THEN 32710

32709 X=X+PEEK(X+2):GOTO 32704


32711 POKE 842,13:POSITION 2,0 :STOP

32712 POKE 842,12:GOTO 32700

32713 ? CHR$ (125):(POSITION 2,2 : FOR SS=32700 TO 32714:? SS:NEXT SS:?"POKE 842,12"

32714 POKE 842,13:POSITION 2,0:STOP

Gary Rindosh

Thank you for the program.

Dvorak Keyboard For 64

After 25 years of typing the "qwerty" way, I'd like to take advantage of a Dvorak keyboard toggle included in a SpeedScript enhancement program for the Commodore 64. What resources are available to help me learn the Dvorak system? Are keyboard caps for the 64 available so that I can cover up the normal keys with Dvorak caps? It's going to be hard giving up the old system, but everything I've heard about the speed and efficiency of the Dvorak keyboard makes me eager to give it a try.

John Willis

If your enhancement program can emulate the Dvorak keyboard within SpeedScript, then no hardware is required to convert from the conventional typewriter key arrangement—often called qwerty— to the Dvorak scheme. Many office supply stores carry stick-on keycap labels that should suit your needs. We're assuming that you have a diagram which shows the Dvorak keyboard.

The advantage of stick-on labels is that you can still use the computer for other purposes that don't involve a Dvorak keyboard. Most commercial software and virtually all type-in programs in publications like COMPUTEI assume that you have a normal 64 keyboard. If you can find or fabricate blank stick-on labels, you could divide each label into two segments—indicate the Dvorak key on one half and the normal 64 key on the other. This would allow you to switch from Dvorak to qwerty applications at will

If you don't use the computer for anything other than word processing and decide to convert permanently to the Dvorak scheme, you could rearrange the existing keycaps. This operation doesn't require any special tools or electronics expertise. While you have the old keycaps off, you can take advantage of the opportunity to clean the keyboard, too. However, rearranging the keycaps will void any warranty that may be in effect, since you must open the case of the computer. And though the operation is reversible, you should consider it semipermanent because of the time involved in switching the keycaps.

To rearrange the keycaps, remove the three Phillips screws in the bottom of the computer's case, then gently separate the two halves of the case. Carefully unplug the two sets of wires that join the upper and lower halves, then remove the eight Phillips screws that hold the keyboard assembly to the upper half. The 64's keycaps are held on by friction, so you can lever them effusing a thin-bladed screwdriver or similar device. The alphanumeric keycaps are all the same size and can be interchanged freely. Of course, you shouldn't disturb keys such as RESTORE, which serve a special purpose. While the keycaps are off, you may want to clean the area around each keyswitch. In many cases, cleaning is all that's needed to fix keys that stick or bounce (repeat when they shouldn't).

To replace a keycap, press it gently but firmly onto the shaft of the keyswitch. After all the keycaps are back in place, reverse the disassembly procedure: Screw the keyboard assembly back into the upper half of the case, then replace the two sets of wires that join the halves. Finally, rejoin the two halves of the case, turn the computer over, and replace the three screws on the bottom. If you've never performed the operation before, you should plan to spend a couple of hours removing, cleaning, and replacing the keycaps.

By the way, you might be interested to learn that there is some controversy surrounding the efficiency claims for the Dvorak keyboard. Most of the frequently quoted statistics (like 35-50 percent increase in speed and 90 percent reduction in finger travel) come from August Dvorak's own research. An independent investigation by Donald Olson and Laurie Jasinski, published in the February 1986 issue of BYTE magazine, suggests that these figures are inflated. While agreeing that the Dvorak arrangement is somewhat more efficient, that article reports that the actual reduction in finger travel is less than 30 percent. It also quotes a University of California study which concluded that a speed increase of 5-10 percent was more realistic.

Automatic IBM Screen Printing

Some time ago I created a BASICA program which allows me to create graphics pictures much like a graphics editor. The program uses every graphics function in the manual, and even saves your work. But in order to print my creations on the printer, I have to press Shift-PrtSc. Is there any way to add a Print Screen function to my program?

William Green

Fortunately, it's quite easy to call the ROM BIOS routine that supports screen printing. The following program fragment does the trick by POKEing a tiny machine language program into a reserved space at the top ofBASIC'S memory area. The ML just executes INT5:RETF to call the Print Screen routine and return to BASIC. This program is adapted from COMPUTE!s Mapping the IBM PC and PCjr, by Russ Davies.

When incorporating this routine into your program, the line with the CLEAR statement must be the first line in your program, Otherwise, any previously defined variables mill be erased. Once the machine language is POKEd into memory, your program can execute the statement CALL PRTSCto make a printout.



120 DATA &HCD&H05,&HCB


Atari DOS 3.0 Vs. 2.5

I have purchased an Atari 1050 disk drive with DOS 3.0. I recently heard that this DOS is no good, and that I should use DOS 2.0 or 2.5. What is so wrong with DOS 3.0, and why shouldn't I use it? Is DOS 2.5 the best one yet for the 1050, and where can I get it?

Gary Cerasoli

Before getting to your questions, let's briefly review the history of Atari disk operating systems:

DOS 1.0 was introduced with the 400/800 computers and 810 disk drive in 1979. It was workable, but suffered from some bugs and unimplemented features. Also, the entire DOS was always resident in RAM (Random Access Memory). Although this was convenient—the DOS menu appeared instantly when you typed the DOS command—it consumed too much memory in a period when few people had more than 24K or 32K of RAM.

DOS 2.0, also known as 2.0S (single density), replaced DOS 1.0 in late 1980/early 1981. It fixed the bugs in DOS 1.0, added significant new features, and conserved memory by keeping only part of itself in RAM. The disk-resident portion of DOS 2.0 loads into memory only when you type the DOS command.

DOS 3.0 was introduced with the dual mode 1050 disk drive in 1983. The 1050 works in the traditional Atari single density mode (88K of storage per disk) as well as an enhanced-density mode (127K of storage per disk). DOS 3.0 was designed to support the enhanced-density mode and to be easier to use. But most Atari users found DOS 3.0 to be clumsy and inconvenient, especially when swapping disks with other people or when mixing single-density and enhanced-density disks. Although the 1050 drive automatically adjusts itself for either density, DOS 3.0 disks and 2.0 disks are incompatible with each other.

To solve these problems, DOS 2.5 was introduced in 1985. This numbering scheme sometimes confuses people, since 2.5 was released two years after 3.0, but 2.5 is so named because it is closely related to DOS 2.0. In fact, the 2.5 menu is almost identical to the 2.0 menu, save for one additional option (Format Single). The advantage of 2.5 is that it works with both single- and enhanced-density disks on the 1050 drive as well as single-density disks on the older 810 drives. This makes life easier for people who have both formats in their disk libraries and for those who swap disks with other users.

DOS 2.5 is available free from most Atari dealers and user groups. It comes with utilities for converting 3.0 files to 2.0/2.5 format, for customizing your copy of 2.5, and for automatically booting up a RAM disk on the 130XE computer.

There's a chance that 2.5 may be superseded in the near future by yet another DOS. Atari is thinking about introducing a 31/2-inch disk drive for the 400/800/XL/XE line, and the much greater capacity of this format (at least 320K per side) would require a completely new DOS with support for subdirectories and other advanced file-management features.