home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Big Blue Disk 15
/
bbd15.zip
/
BITS&PCS.TXT
< prev
next >
Wrap
Text File
|
1987-10-19
|
8KB
|
134 lines
|D╔══════════════════╗════════════════════════════════════════════════════════════
|D║ |5The Happy Hacker |D║════════════════════════════════════════════════════════════
|D╚══════════════════╝════════════════════════════════════════════════════════════
^C^1Bits 'N PC's
^Cby
^CGeorge Leritte
This time we have another installment on interfacing assembly language and a
couple of short routines for your BASIC programs, one that's new and one that's
a revision of an earlier routine. In Turbo Pascal, there is a function for
moving parts of memory from one spot to another. Sometimes, there is a need for
doing that in BASIC. Our SMOVE routine does just that, and it does it pretty
quickly, too. In issue 9, we published a video scrolling routine that used BIOS
interrupt 10 to scroll parts of the screen. One of our readers complained that
he got lost in the shuffle towards the last part of the discussion. Admittedly,
passing the variables the way we did it is not the best way to do things, but it
did get the job done. We will correct it this month with the code in BASIC, the
assembly language source code, and the object file for inclusion in your
compiled BASIC versions.
For those of you who weren't here in Issue 9, I'll offer a short refresher on
BIOS interrupt 10. BIOS interrupt 10 controls the video services offered on the
IBM PC. With it, you can set or determine the video mode, set or determine the
cursor location and size, write to the screen, or scroll windows on your
computer and other nice things. The problem is interfacing them with your
programs. For the screen scroll routine, the registers are loaded with the
desired values and the interrupt call is performed. For the interrupt 10
scroll window service, the registers and the information needed is:
AH: 6 (for scrolling up) or 7 (for scrolling down)
AL: number of lines to scroll (0 to clear window)
BH: attribute to be used for blanked area
CH: row coordinate of upper left corner of window
CL: column coordinate of upper left corner of window
DH: row coordinate of lower right corner of window
DL: column coordinate of lower right corner of window
Note that the row coordinates range from 0 to 24 and the column coordinates
range from 0 to the screen width minus one, not 1 to 25 and 1 to the screen
width as in BASIC.
The implications become obvious. You can scroll all or part of the screen by
using this interrupt. From BASIC, once the assembly language is complete, you
load the routine into memory and determine its starting location. The BASIC
manuals suggest putting it in a location outside BASIC's data space. This is
fine, as long as you have enough memory. Today's computers almost always have
at least 256K of RAM, so memory shouldn't be a problem. However, putting
routines in absolute memory locations can cause problems if you have a lot of
memory resident software, since you cannot guarantee the memory location you
selected will not be in BASIC's data segment anyway. Since I started doing this
on a 128K machine, and like to have it in BASIC's data space where I can keep an
eye on it, and since it occupies only 22 bytes of memory, I place the routine in
an array variable and use BASIC's VARPTR function to get the starting address of
the routine. I also don't have to fool with segments using the DEF SEG
statement, since the routine is in the data segment.
You pass the parameters to the routine with the call statement. If you have
loaded the routine in the array scr%(), the syntax is:
scroll%=varptr(scr%(0))
call scroll% (ch%,cl%,dh%,dl%,attribute%,lines%,direction%)
The varptr statement is precautionary because if you define a new variable
(not redefine an old one), the location of the array will move and you will
crash your program. I put the two statements together in a subroutine and call
it when needed. Also note the parameters passed are integers. The subroutine
is expecting integers and you must define them with the type identifer % or with
a defint statement at the beginning of your program. The first four variables
in the example line correspond to the register values needed for the interrupt
and the last three are the attribute to be used in the blank window, the number
of lines to scroll, and the direction to scroll the window. If the routine
doesn't work, the first place to check is the order and value of the parameters
you're passing. Check the sample program on the disk to see how I've done it.
In a compiled program, you simply use the call scroll statement and compile
your program to object code, then link it with the command LINK PROGNAME+SCROLL.
This is why the object code to the routine is on the disk and also why the line
'public scroll' is in the assembly listing. This tells the link program that
the name SCROLL is an external routine. I used this routine in the conversion
of Rock and Roll Quiz for this issue.
The SCROLL.BAS file on this disk is the interpreted BASIC source code for a
demo. The SCROLL.ASM file is the source code for the assembly language routine,
and the SCROLL.OBJ is the object code needed for use with a compiler.
Sometimes you may have a need for moving data from one place to another
quickly and for..next loops are just too slow. The solution is our SMOVE
routine. SMOVE means short move--memory moves within the data segment. I've
written a long move version--moves anywhere in memory, but it's too easy to
crash the computer with it, so, I'm sorry to say, you won't see it here. If you
like you can modify SMOVE, but any crashes are your fault.
SMOVE uses the MOVS assembly language instruction. MOVS means 'Move String'.
There are two versions, MOVSB and MOVSW, move string-bytes and move string-
words. If you load register CX with the number of bytes or words to move, you
can move sections of memory very quickly with REP MOVS. Don't worry about the
'string' label. They had to call it something.
For arguments sake, let's say you had a large array of numbers to fill with a
repeating sequence of numbers. You could do it with code like this:
10 dim t%(1999)
20 for i=0 to 49
30 for j=0 to 39: t%(I*50+j)= j+1: next j
40 next i
If you created a small array of 40 elements, and then copy repeatedly the small
array into the larger, you could load the large array quicker. With SMOVE, you
can do this 12 to 13 times quicker than the above code.
With the routine loaded in the sm%() array and the data you want to move in
the f%() array, the syntax of SMOVE is:
smove%=varptr(sm%(0)): from_offset%=varptr(f%(0)): to_offset%=varptr(t%(0))
call smove% (from_offset%,to_offset%,no_bytes%)
The variables from_offset% and to_offset% are the memory locations of the
data you are moving. To change the destination in the array, change the index
of the t%() variable. The variable, no_bytes%, is the number of bytes to move.
See the sample program on this disk.
As with SCROLL, the variables being passed must be integers. Also, limit the
definitions of new variables between calls. The assembly language source code
and the object code is on disk. Use the object code with your compiled programs
just like the example for SCROLL.
The SMOVE.BAS file on this disk is the interpreted BASIC source code for a
demo. The SMOVE.ASM file is the source code for the assembly language routine,
and the SMOVE.OBJ is the object code needed for use with a compiler.
Well, that's all for now. If you come up with any interesting uses for these
routines, let us know. Happy computing.