GEM-VDI CALLS PART I by Manus
Originally published in ST NEWS Volume 1 Issue 4, launched on
September 7th 1986.
While others are exploring GFA BASIC, I am going to tell you all
about GEM VDI calls as used in good old ST BASIC.
By the way, sorry for my clumsy English, but it is about 16 years
ago, that I had my last lesson in English.
Yes, it is possible to use GEM-routines in your Basic to draw
rectangles, to put your text in different modes and so on.
To do this, we use special addresses in which we poke the
necessary values.
The meaning of these addresses are:
INPUT:
CONTRL Instruction-number.
CONTRL + 2 Number of input-coordinates of a PTSIN-field.
CONTRL + 6 Number of input-data in a INTIN-field.
INTIN Input-field (like color, textform and so on).
PTSIN Input-field of two together belonging data.
(like the coordinates of a rectangle)
OUTPUT:
CONTRL + 4 Number of output-coordinates.
CONTRL + 8 Number of output-data.
INTOUT Output-field (like present textform).
PTSOUT Output-field of two together belonging data.
IMPORTANT:
These addresses are 16-bits. This means that a cell CONTRL+1 does
not exist.
If you have changed the length of a bit by POKE, you will have to
set this back by "DEF SEG=0", before you can call the GEM-
routines.
Through the statements GEMSYS and VDISYS we can call these AES-
and the VDI-routines.
The GEM-SUBROUTINES have the following syntax:
* The first line contains the name of the subroutine.
* Then the variable that you have to use.
* And then the values you can use.
The variables and subroutines used are the names of the chapters
and forms to make things clear to you. You are free to use other
names for the variables and the subroutines, but remember: don't
use the same name for two different things.
You can MERGE the subroutine you want to use or you can make one
big file with all subroutines.
TEXTMODE :
The Atari ST has different kinds of textforms like double strike,
italics, underlined and so on.
This is done by switching byte 0 to 4 of the variable called
TEXTKIND:
BIT: VALUE: TEXTMODE:
0 1 Double strike
1 2 Light
2 4 Italics
3 8 Underlined
4 16 Hollow
The syntax is:
TEXTKIND = ...... (maximum is 32,normal is 0)
gosub TEXTMODE
The subroutine is:
65000 TEXTMODE:
65002 ' -----> TEXTKIND
65004 ' 0 = normal 1 = double strike 2 = light
65006 ' 4 = italics 8 = underlined 16 = hollow
65008 ' or combinations
65010 '
65012 poke contrl , 106
65014 poke contrl + 2, 0
65016 poke contrl + 6, 1
65018 poke intin, TEXTKIND
65020 vdisys
65022 return
Try this:
5 ' merge "TEXTMODE.bas"
9 '
10 fullw 2: clearw 2
20 data 1,2,4,8,16,3,5,9,10,0
30 for a = 1 to 10
40 read TEXTKIND
50 gosub TEXTMODE
60 gotoxy 14, a + 4: print "ATARI ST"
70 next a
80 waiting = inp(2)
90 end
TEXTSIZE :
You can also change the size of the text. This means however, that
you can not use the PRINT-statement anymore. You have to use the
routine "TEXTOUTPUT". (see next routine)
The syntax is:
SIZE = ......
gosub TEXTSIZE
The subroutine is:
65030 TEXTSIZE:
65032 ' -----> SIZE:
65034 ' < 9 = very small 9 = small
65036 ' 10 - 15 = normal 16 - 17 = big
65038 ' 18 - 19 = very big
65040 '
65042 poke contrl , 107
65044 poke contrl + 2, 0
65046 poke contrl + 6, 1
65048 poke intin, SIZE
65050 vdisys
65052 return
Try this once:
5 ' merge "TEXTSIZE.bas"
6 ' merge "TEXTOUTPUT.bas"
7 '
10 fullw 2: clearw 2
20 data 8,9,10,16,18,20
30 for a = 1 to 6
40 read SIZE
50 gosub TEXTSIZE
60 xpos = 220: ypos = 80 + a * 30: TEXT$ = "ST NEWS"
70 gosub TEXTOUTPUT
80 next a
90 SIZE =15: gosub TEXTSIZE
100 waiting = inp(2)
110 end
TEXTOUTPUT :
These routine gives a string on scale on the monitor. The
coordinates of the beginning are XPOS and YPOS. These begin-
coordinates are free to use.
The syntax is:
XPOS = ......
YPOS = ......
TEXT$= "............"
gosub TEXTOUTPUT
The subroutine is:
65060 TEXTOUTPUT:
65062 ' -----> TEXT$ ; XPOS ; YPOS
65064 ' text on scale
65066 for i = 0 to len(TEXT$) - 1
65068 poke intin + i * 2, asc(mid$(TEXT$, i + 1, 1))
65070 next i
65072 poke intin + i * 2, 0
65074 poke contrl , 8
65076 poke contrl + 2, 1
65078 poke contrl + 6, len(TEXT$) + 1
65080 poke ptsin , XPOS + 1
65082 poke ptsin + 2, YPOS + 38
65084 vdisys
65086 return
TEXT ANGLE :
An other option is to show the text in a different angle.
Unfortunate this is only possible in steps of 90 degrees.
The syntax is:
ANGLE = ...... (= 0 ; 900 ; 1800 ; 2700 )
gosub TEXTANGLE
The subroutine is:
65100 TEXTANGLE:
65102 ' -----> ANGLE (= 0 ; 900 ; 1800 ; 2700 )
65104 '
65106 poke contrl ,13
65108 poke contrl + 2,0
65110 poke contrl + 6,1
65112 poke intin, ANGLE
65114 vdisys
65116 return
Try this:
5 ' merge "TEXTANGLE.bas"
6 ' merge "TEXTOUTPUT.bas"
9 '
10 fullw 2: clearw 2
20 for ANGLE = 2700 to 0 step -900
30 gosub TEXTANGLE
40 XPOS = 300: YPOS = 150: TEXT$ = " ---> ATARI ST"
50 gosub TEXTOUTPUT
60 next
70 waiting = inp(2)
80 end
TEXTFORM :
This function defines the form of the text; must the text
overwrite the background or must a result to be shown after a
logical operation.
There are 4 forms of output on the screen:
FORM: MEANING:
------ -----------------
1 Overwrite
2 Mix
3 XOR-operation
4 Mix and Reverse
The syntax is:
FORM = ..... (1 to 4)
gosub TEXTFORM
Form 1 is the normal form. The text overwrites the background.
In form 2 the output is mixed with the existing background. This
is very useful for graphics, because normally there is a little
white square behind a sign.
With form 3 there is an Exclusive OR-operation. This means that a
screenpoint is only set when one of the two bits has the value 1.
The screenpoint is blank when both bits have the value 0 or 1.
In form 4 the output is the same as in form 2, except for an
additional inversion.
The subroutine is:
65130 TEXTFORM:
65132 ' -----> FORM ( 1 = 4 )
65134 '
65138 poke contrl ,32
65140 poke contrl + 2,0
65142 poke contrl + 6,1
65144 poke intin, FORM
65146 vdisys
65148 return
An example is:
5 ' merge "TEXTFORM.bas"
9 '
10 fullw 2: clearw 2
20 linef 100, 100, 400, 100
30 linef 100, 100, 100, 300
40 linef 100, 300, 400, 300
50 linef 200, 100, 200, 300
60 linef 400, 100, 400, 300
70 linef 300, 100, 300, 300
80 color 1, 1, 1, 2, 2: fill 110, 110
90 color 1, 1, 1, 6, 2: fill 210, 110
100 color 1, 1, 1, 8, 2: fill 310, 110
110 for FORM = 4 to 1 step -1
120 gosub TEXTFORM
130 gotoxy 9, 6 + FORM * 2
140 print chr$(14) chr$(15);
150 print " S T - C O M P U T E R ";
160 print chr$(14) chr$(15)
170 next
180 waiting = inp(2)
190 end
GRAPHIC :
In the VDI almost any thinkable graphic functions are stored, that
can draw geometric figures, like:
- circle - part of a circle
- rectangle - rectangle with round corners
- ellipse - part of an ellipse
- line - filled parts
Some of these functions are available directly in Basic, others
are only available through GEM-calls.
The most useful routines are described in the following part.
RECTANGLE :
Unfortunately, there is no instruction in Basic to draw
rectangles.
With a VDI-routine we can draw a rectangle and even fill it with a
chosen screen, faster then the FILL-instruction in Basic.
The routine needs only the two coordinates of the opposite angles,
the sequence is not important.
The syntax is:
XPOS1 = ..... : YPOS1 = .....
XPOS2 = ..... : YPOS2 = .....
gosub RECTANGLE
This routine (like all other GEM-routines) needs a full opened
OUTPUT-field, because the output of a VDI-instruction is done
directly on the output-field, that is present at that time.
We have to recalculate the coordinates, because the beginning of
the coordinates in Basic is different then in a output-field.
The deviation is in the X-direction 1 pixel and in the Y-direction
38 pixels. The adjustment is done in lines 64012/64018.
The subroutine is:
64000 RECTANGLE:
64002 ' -----> XPOS1 ; YPOS1 ; XPOS2 ; YPOS2
64004 poke contrl ,11
64006 poke contrl + 2,2
64008 poke contrl + 6,0
64010 poke contrl + 10,1
64012 poke ptsin ,XPOS1 + 1
64014 poke ptsin + 2,YPOS1 + 38
64016 poke ptsin + 4,XPOS2 + 1
64018 poke ptsin + 6,YPOS2 + 38
64020 vdisys
64022 return
An example:
5 ' merge "RECTANGLE.bas"
9 '
10 fullw 2: clearw 2
20 color 1, 1, 1, 9, 2
30 XPOS1 = 100 : YPOS1 = 100 : XPOS2 = 300 : YPOS2 = 300
40 gosub RECTANGLE
50 color 1, 1, 1, 9, 3
60 XPOS1 = 150 : YPOS1 = 150 : XPOS2 = 230 : YPOS2 = 260
70 gosub RECTANGLE
80 waiting = inp(2)
90 end
RECTANGLE WITH ROUND ANGLES :
This routine draws also a rectangle, but now with round angles.
Like the previous routine we have to give the coordinates of two
opposite angles. There are two possibilities:
to draw the rectangle and to draw and fill the rectangle.
The syntax is: XPOS1 = ..... : YPOS1 = .....
XPOS2 = ..... : YPOS2 = .....
FILLING = .....
gosub RECTANGLEROUND
The variable FILLING means: FILLING = 0 only the rectangle
FILLING <>0 filled rectangle
The color of the filling has to be declared first with the COLOR-
instruction. The subroutine is:
64030 RECTANGLEROUND:
64032 ' -----> XPOS1 ; YPOS1 ; XPOS2 ; YPOS2
64034 ' FILLING 0 or <>0
64036 poke contrl ,11
64038 poke contrl + 2,2
64040 poke contrl + 6,0
64042 if FILLING=0 then poke contrl+10,8 else poke contrl+10,9
64044 poke ptsin ,XPOS1 + 1
64046 poke ptsin + 2,YPOS1 + 38
64048 poke ptsin + 4,XPOS1 + 1
64050 poke ptsin + 6,XPOS2 + 38
64052 vdisys
64054 return
An example:
5 ' merge "RECTANGLE.bas"
6 ' merge "RECTANGLEROUND.bas"
9 '
10 color 1, 1, 1, 5, 2
15 fullw 2: clearw 2
20 XPOS1 = 100 : YPOS1 = 100 : XPOS2 = 300 : YPOS2 = 300
30 gosub RECTANGLE
40 XPOS1 = 200 : YPOS1 = 80 : XPOS2 = 400 : YPOS2 = 200
50 FILLING = 1
60 color 1, 1, 1, 22, 2
70 gosub RECTANGLEROUND
80 waiting = inp(2)
90 end
LINES :
An other possibility of GEM-VDI is to change lines. We can change
the next things:
- thickness of the line
- pattern
- form on the beginning and the end of the line.
You can use this routines also for ellipse and rectangle.
LINE-THICKNESS :
With this routine you can define the thickness of the lines, which
have to be drawn on the screen.
The syntax is:
THICK = .....
gosub LINETHICKNESS
To return to the standard thickness: call the routine with the
variable THICK = 1.
The routine is:
64220 LINETHICKNESS:
64222 ' ----> THICK
64224 poke contrl ,16
64226 poke contrl + 2,1
64228 poke contrl + 6,0
64230 poke ptsin ,THICK
64232 poke ptsin + 2,0
64234 vdisys
64236 return
Try this:
5 ' merge "LINETHICKNESS.bas"
9 '
10 fullw 2: clearw 2
20 for THICK = 37 to 1 step -4
30 gosub LINETHICKNESS
40 x = 20 + THICK * 15
50 linef x, 100, x, 300
60 next
70 waiting = inp(2)
80 end
LINE-PATTERN :
With this routine you can define in which form the line has to be
drawn, with points or with dashes.
There are available : 6 line-patterns and 1 free to define.
The pre-defined patterns and their values are:
VALUE BIT-PATTERN (16 Bits):
----- ----------------------
1 1111111111111111
2 1111111111110000
3 1111000011100000
4 1111111000111000
5 1111111100000000
6 1111000110011000
7 free to define
The syntax is:
PATTERN = .....
gosub LINEPATTERN
To return to the standard value, call the routine with the
variable PATTERN = 1.
The routine is:
64240 LINEPATTERN:
64242 ' -----> PATTERN
64244 ' 1 - 7
64246 poke contrl ,15
64248 poke contrl + 2,0
64250 poke contrl + 6,1
64252 poke intin, PATTERN
64254 vdisys
64256 return
As usual, an example:
5 ' merge "LINEPATTERN.bas"
9 '
10 fullw 2: clearw 2
20 for PATTERN = 1 to 7
30 gosub LINEPATTERN
40 y = 60 + 20 * PATTERN
50 linef 50, y, 550, y
52 z = 20 + 70 * PATTERN
55 circle z, 250, 30
60 next
70 waiting = inp(2)
80 end
LINE-ENDS :
Normally all lines are angular at the beginning and at the end,
but with the next subroutine you can change this in two other
forms. You can define as well the form of the beginning of the
line as the form at the end.
The values are:
- round forms 2
- arrow 1
- angular 0
The syntax is:
BEGINFORM = .....
ENDFORM = .....
gosub LINESEND
The subroutine is:
64200 LINESEND:
64201 ' -----> BEGINFORM ; ENDFORM
64202 poke contrl ,108
64204 poke contrl + 2,1
64206 poke contrl + 6,0
64208 poke intin ,BEGINFORM
64210 poke intin + 2,ENDFORM
64212 vdisys
64214 return
An example is:
5 ' merge "LINETHICKNESS.bas"
6 ' merge "LINESEND.bas"
9 '
10 fullw 2: clearw 2
20 BEGINFORM = 2 : ENDFORM = 1: gosub LINESEND
30 for THICK = 21 to 1 step -4
40 gosub LINETHICKNESS
50 y = 20 + THICK * 12
60 linef 400,y ,100 , y
70 next
80 waiting = inp(2)
90 end
The next example shows you what you can do with these routines.
I hope that these routines are useful for your programming in
Basic and perhaps next time more routines in ST NEWS.
4 ' merge "RECTANGLEROUND.bas"
5 ' merge "LINETHICKNESS.bas"
6 ' merge "LINESENDS.bas"
7 ' merge "LINEPATTERN.bas"
8 ' merge "TEXTFORM.bas"
9 '
100 ' measuring a rectangle
110 fullw 2: clearw 2
120 thick = 3: gosub LINETHICKNESS
130 xpos1 = 100 : ypos1 = 200 : xpos2 = 300 : ypos2 = 240
140 gosub RECTANGLEROUND
150 thick = 1: gosub LINETHICKNESS
160 pattern = 4: gosub LINEPATTERN
170 linef 80, 220, 320, 220
180 pattern = 1: gosub LINEPATTERN
190 linef 100, 230, 100, 280
200 linef 300, 230, 300, 280
210 linef 295, 240, 340, 240
220 linef 295, 200, 340, 200
230 endform = 1 : beginform = 1: gosub LINESEND
240 linef 330, 200, 330, 240
250 linef 100, 270, 300, 270
255 endform = 0 : beginform = 0: gosub LINESEND
260 textkind = 4 :gosub TEXTMODE
270 gotoxy 11, 16: print "200 mm"
280 gotoxy 20, 12: print "40 mm"
290 textkind = 0: gosub TEXTMODE
300 waiting = inp(2)
310 end
This program is also added on the ST NEWS disk as ST BASIC
program.
Disclaimer
The text of the articles is identical to the originals like they appeared
in old ST NEWS issues. Please take into consideration that the author(s)
was (were) a lot younger and less responsible back then. So bad jokes,
bad English, youthful arrogance, insults, bravura, over-crediting and
tastelessness should be taken with at least a grain of salt. Any contact
and/or payment information, as well as deadlines/release dates of any
kind should be regarded as outdated. Due to the fact that these pages are
not actually contained in an Atari executable here, references to scroll
texts, featured demo screens and hidden articles may also be irrelevant.