Disinformation 4

On tiny .COM files


Column IndexAnsible Information Home PageDavid Langford Home Page

Have you noticed that there's a yawning social gap between two classes of software users? If you sit all day bashing copy into a user-hostile word processor or laboriously simulating Sir Clive Sinclair on the spreadsheet, that's applications software, and your hands are not deemed to be soiled. (We won't discuss the state of your brain.) But should you stoop to write a one-line batch file or play around with MSBASIC, you've slithered into the murky world of development, and on the whole it seems that higher social status is enjoyed by collectors of night-soil.

I was properly put in my place during visits to AT Computerworlds, W.H. Smith Business Centres and the like. "An... assembler?" they said in alarm. (Pause while exquisitely clad salesperson retreats to the back room and the Penguin Dictionary of Computing.) "Oh, that's development software. We don't stock that kind of thing because -- " (all together now) "there's no call for it."

Thus you are spared a column about the MicroSoft Macro Assembler, you lucky people, and I'm left to wonder whether it's only bootleg copies which cause the Apricot PC to hang up as a cunning means of indicating an assembly error....

In fact, you don't need an assembler to fudge up tiny .COM files for tasks like screen manipulation. They are not as mysterious as they seem. Remember how .BAT files once appeared enigmatic? Remember the sudden rush of illumination on finding they contained instructions in almost plain text, and could be created and edited with your word processor? Well, .COM files contain plain machine code with no frills, and to create a very simple one requires only three assets: (a) patience, which as a reader of Apricot plc manuals you should by now have; (b) a little information, with which I am about to bore you rigid; and (c) a copy of the fabulous DEBUG, as supplied to all my own customers and available on Deals For Readers disk AP002 (plug).

For my money, the shortest .COM file to do anything even remotely useful is BEEP.COM, which simply provokes the Apricot to go beep when it's run. You can then include the line BEEP at the end of long batch files, for an audible "I've finished!" signal. BEEP.COM runs to just eight bytes, and requires knowledge of no more than two assembler commands. Here's how to create it from scratch.

First, load up DEBUG.

At the prompt (usually a hyphen), type A 100 and Return. This tells DEBUG to expect assembler instructions and to start the resulting machine code at memory location 100. Alarming numbers will replace the prompt: four digits of current segment address (which you can ignore), followed by a colon, followed by four digits of address within the current segment. So, in the following, it's only the stuff on the right which you actually need to type (ending each line with Return):

     209A:0100   MOV AH,2
     209A:0102   MOV DL,7
     209A:0104   INT 21
     209A:0106   INT 20
     209A:0108
     -

Entering a blank line at the end (Return only) takes you back to the hyphen prompt. Now, what do these lines actually do? MOV AH,2 "moves" the value of 2 into the AH register: 2 is the MS-DOS function code meaning "display the character in register DL". The next line pops a 7 (ie. ASCII character 7, or Control-G, which produces a beep) into DL. All the work is then done by the INT 21, an "interrupt" which asks MS-DOS to do what the AH function code is telling it. INT 20 stops the program (there are lots of ways to end .COM programs, but this is the shortest).

At this point you have the entire dwarf program in memory in the eight locations from 100 to 107 inclusive. You can even run it from DEBUG, by typing G, which should produce a beep and the message "Program terminated normally". Let's write it to a file.

Type: R CX. This shows you the current value of the CX register and gives you a chance to change it: a colon prompts you to enter a new value. Because we have an 8-byte program and CX controls the number of bytes DEBUG will write to disk, the value to enter is 8. (This is always easy to work out: it's 100 less than the last memory location figure displayed when entering the code. Remember that 209A:0108?)

Now type: N BEEP.COM to give your file a name.

And then: W to write it to disk. Leave DEBUG with Q.

When you've wearied of the ecstasy of your very first machine-code program and can stop making the air hideous with beeps, you might like to reflect that any other hexadecimal number, from 0 to FF, can be substituted for the 7 in that MOV DL,7 command. This means you can write tiny .COM files to generate any character, including those with ASCII codes 127 to 254 (hex 7F to FE) -- which with a few exceptions like the pound and yen signs can't be typed at the keyboard. (New users might like to know that several "specials" can be typed using Control with the keys in the top row: eg. Control-4 for the yen sign, though on the PC/Xi the symbol on the front of this key is =/= [the "not-equals" symbol].)

Character codes 0 to 31 (hex 00 to 1F) produce "control characters" like Return (hex 0D) or Linefeed (hex 0A). But the font also contains displayable characters with these codes: silly faces, playing-card graphics, male and female symbols, musical notes.... As noted in Release 1.3, you can display them by sending Escape and 8 to the screen before the relevant character code. This suggests a tiny utility for generating them... enter the assembler instructions as above, but don't enter the comments!

     
     MOV AH,2        "print character" code
     MOV DL,1B       Escape (1B hex, 27 decimal)
     INT 21          MS-DOS call to print
     MOV DL,38       character "8" ASCII code
     INT 21          MS-DOS again to print it
     MOV DL,[0082]   read command line
     AND DL,1F       get command line character into range 0-31
     INT 21          again, print it
     INT 20          end

Call this one LIT.COM and save it as above: it runs to 15 (hex) bytes. The first four and last two lines should make sense. The enigmatic MOV DL,[0082] gets the first character from the "command line", so if you run this program by typing LIT A from MS-DOS, the A (character code 41 hex) is what will go into register DL. The next command does what assembler programmers call "masking": AND DL,1F chops out any bits in DL which aren't in the number 1F (hex), or 31 (decimal), or 00011111 (binary). This conveniently means that capital "A" (binary 01000001) and small "a" (binary 01100001) are both stripped down to 1 (in any base you like). Character 1 is also known as Control-A. So LIT A gives you ASCII character 1, LIT B gives you character 2, and by the time you've worked through to LIT _ for character 31 (decimal) you'll doubtless have had quite enough.

Do you really have to waste your days doing INT 21 commands to send stuff to the screen one character at a time? Thankfully, no. Our last example is a teensy file which can be adapted to send almost anything you like to the screen -- anything except a dollar sign.

     MOV AH,9        MS-DOS "print *string*" code
     MOV DX,0109     set start address for string
     INT 21          kick MS-DOS into life
     INT 20          kick program to death
     DB 'Put any character string here' 0D 0A
     DB 'Mix quotes with ASCII codes: ' 2A 7F ' ' EC 
     DB ' Finish with a dollar sign.$'

Since the four instructions which make up the program are always the same, the string will always start at location 0109. When you finish entering DB (which stands for Define Bytes) lines, make sure to note the last address and set CX accordingly before saving the file. This way of writing chunks of stuff to the screen can be a lot quicker than multi-line .BAT files... as well as looking more impressive. ("My dear, anyone can write a batch file....")

Most irritating conversation of the month: a dealer who proudly announced that although Apricot User arrived in the box with every Apricot machine, he took the magazines out and thus prevented buyers learning how extortionate his prices were. I wonder if he visits Dixons and obliterates their price tags with a spray-can? For a small fee I will be prepared to disclose his name and title....


Column IndexAnsible Information Home PageDavid Langford Home Page