Classic Computer Magazine Archive ANTIC VOL. 4, NO. 1 / MAY 1985

the toolbox

HANDY USR ROUTINES

Machine language power from BASIC

by ERNIE NEGUS

A collection of short but powerful USR machine language routines that can be usefully plugged into your your BASIC programs for any Atari computer. Antic Disk subscribers ENTER "D:USERCALL.LST" and follow the instructions in the article.

BASIC's USR command lets you use speedy, memory-efficient machine language subroutines from the comfort of BASIC. Although these subroutines are tricky to type, they let your BASIC programs access a wider variety of functions, run faster and occupy less memory.
   Simply put, machine code is a series of numbers stored in memory. Each number stands for an instruction to the computer. Once you have the address of this code, the USR function lets you run it from BASIC.
   Machine code can be stored in several ways. Here, the code is stored in character strings. We can now use BASIC's ADR function to find the beginning address of the character string, and put this value into our USR call.
   Since the computer interprets each character as a machine code instruction, a single mistyped character could cause your computer to lock up when you RUN the program.
   You must type in each character string exactly as it appears, checking each line with TYPO II. Refer to the Special Atari Character charts in the Antic listings section if you need additional help.
   Also, please note that you only need to type the dot-matrix listing printouts marked with TYPO II codes. The typeset example lines below each listing simply indicate how these listings should be called up in these demonstrations or in your own BASIC programs.
   All USR calls have the general form: X = USR(z, p1, p2, p3) where z is the decimal address of the machine language routine, and p1, p2 and p3 are input values (parameters) which the machine language routine will use. While some USR calls do not need parameters, others demand several. Any parameters you use must be numbers between 0 and 65,535.
   Here are some short USR routines which use machine language to manipulate bits, perform multiple PEEKs and POKEs, evaluate Boolean expressions, and even play music.
   Let's examine our USR routines and see how they work:
 
 BBYTE

15 ANS=USR(BBYT,pl,p2,p3,p4,p5,p6,p7,p8)

This routine converts binary numbers to decimal. In our example, the mysterious-looking character string is the machine language subroutine. The ADR function determines the decimal address of the subroutine. This address is stored in the Variable BBYT. Our final result will be stored in ANS.
   We'll use this routine to convert 00001111 to decimal:

   First, type in the machine language string as shown in line 10.
Now, type:
   15 ANS=USR(BBYT,0,0,0,0,l,1,l,l)
   17 PRINT ANS

   When you RUN this demonstration, ANS will be equal to 15, the decimal equivalent of 00001111.
   USR routines which do not return values to your BASIC program, such as MPOK, must also be equated to a BASIC variable. Programmers often call these "dummy" variables because they aren't used in any calculations, but are required by BASIC syntax rules.
 
 DPEK

25 ANS = USR(DPEK,<address>)

   This routine performs a double PEEK at any given decimal address. Its BASIC equivalent is:

ANS = PEEK (<address>) + PEEK (<address + 1>) * 256

   Please note that items within angle brackets, such as <address>, tell you what type of data the USR routine requires. If you wanted to perform a double PEEK at address 1536, for example, you would type:

25 ANS = USR(DPEK,15 36)
 
 MPOK

35 DUMMY= USR(MPOK,<address>,<bytel>, <byte2>...)

   MPOK will POKE any number of bytes into successive memory locations, beginning at the specified decimal address.
 
 DPOK

45 DUMMY= USR(DPOK,<address>,<wordl>, <word2>...)

   DPOK works just like MPOK, except DPOK will POKE any number of words into successive memory locations.
 
HI

55 ANS = USR(HI,<word>)

   HI returns the high byte of any word. Its BASIC equivalent is:ANS INT(WORD/256)
 
 LOW

65 ANS = USR(LOW,<word>)

   LOW returns the low byte of any word. Its BASIC equivalent is:

ANS =WORD-INT(WORD/256)* 256
 
 BAND

75 ANS=USR(BAND,pl,p2,p3...)

   BAND performs a logical "AND" on the bits of any number of parameters. BAND can be used to separate missiles and test the direction bits of the joystick ports.
 
 BOR

85 ANS=USR(BOR,pl,p2,p3...)

   BOR performs a logical "OR" on the bits of any number of parameters. BOR can be used to set bits and alter display list options.
 
 BXOR

95 ANS=USR(BXOR,pl,p2,p3...)

   BXOR performs a logical "Exclusive OR" on the bits of any number of parameters. The routine can be used to control blinking characters and flashing colors.
 
 BROT

105 ANS = USR(BROT,<address>,<direction>,<carry>)

   BROT will rotate the bits of a byte in RAM. In line 75, <address> is the decimal address of this byte, <direction>, is the direction of rotation (use 0 for right rotation, 1 for left rotation), and <carry> initializes the carry bit. ANS will contain the carry condition after the rotation.
   BROT can be used to rotate characters and players, and convert decimal numbers to binary numbers.
 
 RORB

115 DUMMY= USR(RORB,<start>,<end>,<skip>)
 
 ROLB

125 DUMMY= USR(ROLB,<start>,<end>,<skip>)

   RORB and ROLB will rotate bytes from decimal address <start> to address <end>, while skipping every <skip> bytes. Of course, the difference between <start> and <end> should be evenly divisible by <skip>. Otherwise, your program may lock up.
   These routines can be used for coarse scrolling, animating characters, moving players and missiles vertically, and changing display lists.
 
 MUSIC

   This routine lets the computer play simple tunes from data stored in MUSDAT$. Each note in MUSDAT$ is represented by two bytes. The first byte of each pair is the pitch value of the note. Consult your BASIC reference manual for appropriate pitch values. The second byte is the duration of the note, in jiffies.
   Whole notes require approximately 60 jiffies, quarter notes use approximately 15 jiffies. In our example, MUSDAT $ holds the data for the last two bars of "Mary Had A Little Lamb."
   USR routines are easy to use and can breathe new life into tired BASIC programs.

Listing: USERCALL.BAS Download

Ernie Negus is a computer engineer for Intel in Oregon, working mainly on state-of the-art hard disks, 32-bit microprocessors and quad density floppies.