<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://www.temlib.org/AtariForumWiki/index.php?action=history&amp;feed=atom&amp;title=CW_CHAPTER_5</id>
	<title>CW CHAPTER 5 - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://www.temlib.org/AtariForumWiki/index.php?action=history&amp;feed=atom&amp;title=CW_CHAPTER_5"/>
	<link rel="alternate" type="text/html" href="https://www.temlib.org/AtariForumWiki/index.php?title=CW_CHAPTER_5&amp;action=history"/>
	<updated>2026-07-26T07:36:25Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.39.2</generator>
	<entry>
		<id>https://www.temlib.org/AtariForumWiki/index.php?title=CW_CHAPTER_5&amp;diff=11622&amp;oldid=prev</id>
		<title>&gt;Wongck at 15:35, 12 October 2011</title>
		<link rel="alternate" type="text/html" href="https://www.temlib.org/AtariForumWiki/index.php?title=CW_CHAPTER_5&amp;diff=11622&amp;oldid=prev"/>
		<updated>2011-10-12T15:35:58Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 11:35, 12 October 2011&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l834&quot;&gt;Line 834:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 834:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Back to [[Assembly_language_tutorials]]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Back to [[Assembly_language_tutorials]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Category:&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Programming&lt;/del&gt;]]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Category:&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Assembly Language Workshop&lt;/ins&gt;]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>&gt;Wongck</name></author>
	</entry>
	<entry>
		<id>https://www.temlib.org/AtariForumWiki/index.php?title=CW_CHAPTER_5&amp;diff=11621&amp;oldid=prev</id>
		<title>&gt;Silver Surfer: Added category</title>
		<link rel="alternate" type="text/html" href="https://www.temlib.org/AtariForumWiki/index.php?title=CW_CHAPTER_5&amp;diff=11621&amp;oldid=prev"/>
		<updated>2009-05-02T17:24:13Z</updated>

		<summary type="html">&lt;p&gt;Added category&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 13:24, 2 May 2009&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l834&quot;&gt;Line 834:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 834:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Back to [[Assembly_language_tutorials]]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Back to [[Assembly_language_tutorials]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;[[Category:Programming]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>&gt;Silver Surfer</name></author>
	</entry>
	<entry>
		<id>https://www.temlib.org/AtariForumWiki/index.php?title=CW_CHAPTER_5&amp;diff=11620&amp;oldid=prev</id>
		<title>&gt;Zorro 2 at 14:06, 24 October 2006</title>
		<link rel="alternate" type="text/html" href="https://www.temlib.org/AtariForumWiki/index.php?title=CW_CHAPTER_5&amp;diff=11620&amp;oldid=prev"/>
		<updated>2006-10-24T14:06:05Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
CHAPTER 5: INTRODUCING THE VDI&lt;br /&gt;
-------------------------------&lt;br /&gt;
&lt;br /&gt;
[NOTE: Words enclosed in asterisks (i.e. *word*) should be &lt;br /&gt;
read as italicized text. This text file is copyright 1993 by &lt;br /&gt;
Clayton Walnum. All rights reserved.]&lt;br /&gt;
&lt;br /&gt;
GEM (Graphics Environment Manager) is made up of many &lt;br /&gt;
libraries of functions, each of which handles certain &lt;br /&gt;
portions of the system's activities. These libraries are &lt;br /&gt;
grouped into two major units, called the AES (Applications &lt;br /&gt;
Environment Services) and the VDI (Virtual Device &lt;br /&gt;
Interface). The AES, which we've been using since the &lt;br /&gt;
beginning of the book, contains the functions we need to &lt;br /&gt;
handle windows, dialog boxes, menu bars, and event &lt;br /&gt;
processing. The VDI controls most of the ST's graphic &lt;br /&gt;
capabilities and provides some mouse and cursor control &lt;br /&gt;
functions, as well.&lt;br /&gt;
	The VDI plays an important role in making your graphics &lt;br /&gt;
programs operate on many different devices. Unfortunately, &lt;br /&gt;
one of the crucial elements in the graphics interface, GDOS &lt;br /&gt;
(Graphics Device Operating System), is not built into the &lt;br /&gt;
current operating system. GDOS is the portion of the VDI &lt;br /&gt;
that links the graphics functions to the drivers needed to &lt;br /&gt;
assure that the graphics operate properly on all graphics &lt;br /&gt;
devices. GDOS also makes it possible to load different fonts &lt;br /&gt;
into your ST, using the standard VDI functions.&lt;br /&gt;
	At this time, however, we're concerned only with one &lt;br /&gt;
device: the screen.&lt;br /&gt;
 &lt;br /&gt;
--The VDI functions--&lt;br /&gt;
&lt;br /&gt;
The VDI provides a series of functions that let us quickly &lt;br /&gt;
draw many graphic shapes. This simplifies the development of &lt;br /&gt;
programs that rely heavily on graphics. If you programmed an &lt;br /&gt;
8-bit Atari (or still do), think of all the work involved in &lt;br /&gt;
drawing a circle. The VDI provides a function that will draw &lt;br /&gt;
any size circle we want--with a single call. There are also &lt;br /&gt;
functions for drawing ellipses, lines, rectangles, rounded &lt;br /&gt;
rectangles, arcs, pie slices and a number of other useful &lt;br /&gt;
graphics.&lt;br /&gt;
	And it doesn't stop there. Each graphic function has a &lt;br /&gt;
group of related attributes that may be set before the &lt;br /&gt;
graphic is drawn, allowing various types of lines, fills and &lt;br /&gt;
colors.&lt;br /&gt;
&lt;br /&gt;
--The Program--&lt;br /&gt;
&lt;br /&gt;
This chapter's sample program shows how to set up your &lt;br /&gt;
program to use the VDI. It also includes a demonstration of &lt;br /&gt;
some of the VDI's graphics capabilities. Specifically, when &lt;br /&gt;
the program is run, you will see the different types of line &lt;br /&gt;
styles available through the VDI. To exit the program, press &lt;br /&gt;
your Return key.&lt;br /&gt;
 &lt;br /&gt;
--The VDI Arrays--&lt;br /&gt;
&lt;br /&gt;
Calling VDI functions is a lot like calling AES functions. &lt;br /&gt;
In both cases, you must place appropriate values into &lt;br /&gt;
control and input arrays, and then call the function by &lt;br /&gt;
using a *trap #2* instruction. Look at the data section of &lt;br /&gt;
this chapter's sample program. There, you'll find the usual &lt;br /&gt;
AES parameter block (*apb*). Right below that, you'll see &lt;br /&gt;
something called *vpb*. Yep. That's a VDI parameter block. &lt;br /&gt;
Although these parameter blocks work the same way--that is, &lt;br /&gt;
they both tell the OS where to find the arrays it needs--&lt;br /&gt;
they contain different values. The VDI, for example, doesn't &lt;br /&gt;
use the *addr_in* or *addr_out* arrays. Let's look at the &lt;br /&gt;
*vpb* in detail.&lt;br /&gt;
	The first value is the address of a control array. In &lt;br /&gt;
our *apb* we have a 0 in this location because we found it &lt;br /&gt;
easier to have different control arrays for each function, &lt;br /&gt;
and then plug the address of the appropriate array into the &lt;br /&gt;
*apb* when we needed it. But because the values in the VDI &lt;br /&gt;
control array vary from one function call to another, it's &lt;br /&gt;
clumsy to try to set them up ahead of time.&lt;br /&gt;
	The *int_in* and *int_out* arrays are the same as those &lt;br /&gt;
in the *apb*. We can use the same arrays for either an AES &lt;br /&gt;
or VDI call. But the VDI *apb* has something a little &lt;br /&gt;
different, arrays called *pts_in* and *pts_out*. These &lt;br /&gt;
arrays usually contain coordinates for the VDI's drawing &lt;br /&gt;
functions. For example, the starting and ending screen &lt;br /&gt;
coordinates for a line would go into the *pts_in* array &lt;br /&gt;
before calling the function.&lt;br /&gt;
&lt;br /&gt;
--Initializing the VDI--&lt;br /&gt;
&lt;br /&gt;
When we use the VDI in our programs, we must set up &lt;br /&gt;
something called a virtual workstation. To do this, we do &lt;br /&gt;
the following:&lt;br /&gt;
&lt;br /&gt;
1) Get a handle to the physical screen.&lt;br /&gt;
2) Open a virtual workstation.&lt;br /&gt;
3) Clear the virtual workstation.&lt;br /&gt;
&lt;br /&gt;
Look at this chapter's program listing. After the usual &lt;br /&gt;
program initialization, which concludes with the call to &lt;br /&gt;
*appl_init*, we begin the VDI initialization. The first step &lt;br /&gt;
is performed by calling the AES function #77, *graf_handle*, &lt;br /&gt;
like this:&lt;br /&gt;
&lt;br /&gt;
move.l  #graf_handle,apb&lt;br /&gt;
jsr     aes&lt;br /&gt;
move    int_out,gr_handle&lt;br /&gt;
 &lt;br /&gt;
	This returns the handle for the currently open device &lt;br /&gt;
(the screen) or workstation, as well as the size of the &lt;br /&gt;
system font. Because GEM is capable of having many programs &lt;br /&gt;
in memory at once, each requires some identification, to &lt;br /&gt;
keep commands for one program from corrupting another. This &lt;br /&gt;
is accomplished by assigning each program a handle. The &lt;br /&gt;
variable *gr_handle* in the above call is an integer value &lt;br /&gt;
that identifies the current workstation. After the call, &lt;br /&gt;
this value is found in the first element of the *int_out* &lt;br /&gt;
array.&lt;br /&gt;
	The *graf_handle* call also returns some information &lt;br /&gt;
about the system font. The width of a character cell will be &lt;br /&gt;
in *int_out+2*, the cell height will be in *int_out+4*, the &lt;br /&gt;
width of a box that can enclose a character will be in &lt;br /&gt;
*int_out+6*, and the height of the box will be in &lt;br /&gt;
*int_out+8*. We won't be using any of this character &lt;br /&gt;
information now, but you should know where to find it when &lt;br /&gt;
you need it.&lt;br /&gt;
 &lt;br /&gt;
--The Virtual Workstation--&lt;br /&gt;
&lt;br /&gt;
The *graf_handle* call returns the handle to the physical &lt;br /&gt;
workstation. What we really need for our program is a handle &lt;br /&gt;
to a virtual workstation. It's kind of tough to explain the &lt;br /&gt;
difference, but I'll give it a shot.&lt;br /&gt;
	A particular device may have many virtual workstations, &lt;br /&gt;
but only one physical workstation. The physical workstation &lt;br /&gt;
is directly associated with the device itself, usually the &lt;br /&gt;
screen. You can think of a virtual workstation as a &lt;br /&gt;
&amp;quot;pretend&amp;quot; device. It has its own section of memory and keeps &lt;br /&gt;
its data and status completely separate from all other &lt;br /&gt;
virtual workstations. When you activate an application (such &lt;br /&gt;
as clicking on a desk accessory), it becomes bound to the &lt;br /&gt;
physical workstation. In a sense, it becomes the physical &lt;br /&gt;
workstation.&lt;br /&gt;
	We get the handle for our virtual workstation with a &lt;br /&gt;
call to the VDI function #100, *v_opnvwk*, like this:&lt;br /&gt;
 &lt;br /&gt;
	move    #100,contrl&lt;br /&gt;
	clr     contrl+2&lt;br /&gt;
	move    #11,contrl+6&lt;br /&gt;
	move    gr_handle,contrl+12&lt;br /&gt;
	movea.l #int_in,a5&lt;br /&gt;
	move    #9,d5&lt;br /&gt;
loop:&lt;br /&gt;
	move    #1,(a5)+&lt;br /&gt;
	dbra    d5,loop&lt;br /&gt;
	move    #2,int_in+20&lt;br /&gt;
	jsr     vdi&lt;br /&gt;
	move    contrl+12,vws_handle&lt;br /&gt;
 &lt;br /&gt;
	This function expects the system attributes to be in &lt;br /&gt;
the *int_in* array. (In this example, we're loading the &lt;br /&gt;
values into *int_in* using a loop.) These attributes &lt;br /&gt;
determine default values for system attributes such as &lt;br /&gt;
default colors, fill patterns, and line styles. (For those &lt;br /&gt;
of you familiar with C, the *int_in* array in this call &lt;br /&gt;
serves the same function as C's *work_in* array.) In the &lt;br /&gt;
above example, we place a 1 in elements 1 through 10 of the &lt;br /&gt;
*int_in* array, and a 2 in the eleventh element of the &lt;br /&gt;
*int_in* array. This is the standard way to initialize these &lt;br /&gt;
attributes.&lt;br /&gt;
	You should note the manner in which the control array &lt;br /&gt;
is used, since all VDI calls require similar parameters in &lt;br /&gt;
this array. The first element of the control array must &lt;br /&gt;
contain the opcode for the VDI function we wish to call. &lt;br /&gt;
*Contrl+2* must contain the number of point pairs that will &lt;br /&gt;
be found in the *pts_in* array, in this case, 0. *Contrl+6* &lt;br /&gt;
must contain the number of integer values that are in the &lt;br /&gt;
*int_in* array. In this function call, *int_in* will contain &lt;br /&gt;
11 values, so we place an 11 in *contrl+6*. Finally, &lt;br /&gt;
*contrl+12* must contain the device handle. In most VDI &lt;br /&gt;
calls, this value will be the handle to our virtual &lt;br /&gt;
workstation. However, because we don't yet have that handle, &lt;br /&gt;
we use the graphics handle that was returned by the call to &lt;br /&gt;
*graf_handle*.&lt;br /&gt;
	After the call to *v_opnvwk*, our *int_out* and &lt;br /&gt;
*pts_out* arrays will contain much information about the &lt;br /&gt;
virtual device's current attributes, as follows:&lt;br /&gt;
&lt;br /&gt;
	control+4 -- 6 = # of point pairs in pts_out&lt;br /&gt;
	control+8 -- 45 = # of integers in int_out&lt;br /&gt;
	control+12 -- Device handle (0 if no device opened)&lt;br /&gt;
&lt;br /&gt;
	int_out, work_out[0] -- Maximum horizontal screen coord.&lt;br /&gt;
	int_out+2, work_out[1] -- Maximum vertical screen coord.&lt;br /&gt;
	int_out+4, work_out[2] -- Device coordinate units flag:&lt;br /&gt;
		0 = Device can display a precisely scaled image.&lt;br /&gt;
		1 = Device cannot display a precisely scaled image.&lt;br /&gt;
	int_out+6, work_out[3] -- Width of a pixel in microns.&lt;br /&gt;
	int_out+8, work_out[4] -- Height of a pixel in microns.&lt;br /&gt;
	int_out+10, work_out[5] -- Number of font heights:&lt;br /&gt;
		0 = continuous scaling.&lt;br /&gt;
	int_out+12, work_out[6] -- Number of line types.&lt;br /&gt;
	int_out+14, work_out[7] -- Number of line widths:&lt;br /&gt;
		0 = Continuous scaling.&lt;br /&gt;
	int_out+16, work_out[8] -- Number of marker styles.&lt;br /&gt;
	int_out+18, work_out[9] -- Number of marker sizes:&lt;br /&gt;
		0 = Continuous scaling.&lt;br /&gt;
	int_out+20, work_out[10] -- Number of supported text fonts.&lt;br /&gt;
	int_out+22, work_out[11] -- Number of pattern styles.&lt;br /&gt;
	int_out+24, work_out[12] -- Number of hatch styles.&lt;br /&gt;
	int_out+26, work_out[13] -- Number of available colors.&lt;br /&gt;
	int_out+28, work_out[14] -- Number of generalized drawing &lt;br /&gt;
						primitives.     &lt;br /&gt;
	int_out+30 to int_out+48&lt;br /&gt;
	work_out[15] to work_out[24] -- Code numbers for available      &lt;br /&gt;
						generalized drawing primitives:&lt;br /&gt;
		1 = filled bar.&lt;br /&gt;
		2 = arc.&lt;br /&gt;
		3 = pie slice.&lt;br /&gt;
		4 = filled circle.&lt;br /&gt;
		5 = filled ellipse.&lt;br /&gt;
		6 = elliptical arc.&lt;br /&gt;
		7 = elliptical pie slice.&lt;br /&gt;
		8 = rounded rectangle.&lt;br /&gt;
		9 = filled rounded rectangle.&lt;br /&gt;
		10 = justified graphics text.&lt;br /&gt;
		-1 = end of GDP list.&lt;br /&gt;
	int_out+50 to int_out+68&lt;br /&gt;
	work_out[25] to work_out[34] -- Code numbers for graphics&lt;br /&gt;
				operations available to the GDPs:&lt;br /&gt;
		0 = lines.&lt;br /&gt;
		1 = markers.&lt;br /&gt;
		2 = graphics text.&lt;br /&gt;
		3 = fills.&lt;br /&gt;
		4 = none.&lt;br /&gt;
	int_out+70, work_out[35] -- Color flag:&lt;br /&gt;
		0 = no colors available on device.&lt;br /&gt;
		1 = colors available on device.&lt;br /&gt;
	int_out+72, work_out[36] -- Text rotation flag:&lt;br /&gt;
		0 = device cannot rotate text.&lt;br /&gt;
		1 = device can rotate text.&lt;br /&gt;
	int_out+74, work_out[37] -- Fill flag:&lt;br /&gt;
		0 = device cannot fill areas.&lt;br /&gt;
		1 = device can fill areas.&lt;br /&gt;
	int_out+76, work_out[38] -- Cell array flag:&lt;br /&gt;
		0 = device not capable of cell array operation.&lt;br /&gt;
		1 = device capable of cell array operation.&lt;br /&gt;
	int_out+78, work_out[39] -- Number of available colors:&lt;br /&gt;
		0 = more than 32,767.&lt;br /&gt;
		1 = Black and white&lt;br /&gt;
		2 or more = Number of colors available.&lt;br /&gt;
	int_out+80, work_out[40] -- Locator input devices:&lt;br /&gt;
		1 = keyboard.&lt;br /&gt;
		2 = keyboard and mouse (or other device)&lt;br /&gt;
	int_out+82, work_out[41] -- Valuator input devices:&lt;br /&gt;
		1 = keyboard.&lt;br /&gt;
		2 = other device.&lt;br /&gt;
	int_out+84, work_out[42] -- Choice devices:&lt;br /&gt;
		1 = function keys.&lt;br /&gt;
		2 = other keypad.&lt;br /&gt;
	int_out+86, work_out[43] -- Text input devices:&lt;br /&gt;
		1 = keyboard.&lt;br /&gt;
	int_out+88, work_out[44] -- Type of workstation:&lt;br /&gt;
		0 = output.&lt;br /&gt;
		1 = input.&lt;br /&gt;
		2 = input and output.&lt;br /&gt;
		3 = reserved&lt;br /&gt;
		4 = metafile output.&lt;br /&gt;
	pts_out, work_out[45] -- Minimum character width.&lt;br /&gt;
	pts_out+2, work_out[46] -- Minimum character height.&lt;br /&gt;
	pts_out+4, work_out[47] -- Maximum character width.&lt;br /&gt;
	pts_out+6, work_out[48] -- Maximum character height.&lt;br /&gt;
	pts_out+8, work_out[49] -- Minimum line width.&lt;br /&gt;
	pts_out+10, work_out[50] -- 0.&lt;br /&gt;
	pts_out+12, work_out[51] -- Maximum line width.&lt;br /&gt;
	pts_out+14, work_out[52] -- 0.&lt;br /&gt;
	pts_out+16, work_out[53] -- Minimum marker width.&lt;br /&gt;
	pts_out+18, work_out[54] -- Minimum marker height.&lt;br /&gt;
	pts_out+20, work_out[55] -- Maximum marker width.&lt;br /&gt;
	pts_out+22, work_out[56] -- Maximum marker height.&lt;br /&gt;
&lt;br /&gt;
	Don't let all this information intimidate you. Right &lt;br /&gt;
now, we're only concerned with the three values returned in &lt;br /&gt;
*contrl+4*, *contrl+8*, and *contrl+12*. *Contrl+12* will &lt;br /&gt;
contain the handle to our virtual workstation, *contrl+4* &lt;br /&gt;
will contain the number of points (two values each) returned &lt;br /&gt;
in *pts_out*, and *contrl+8* will contain the number of &lt;br /&gt;
integers returned in *int_out*. For this function call, &lt;br /&gt;
*contrl+4* should contain a 6 after the call, which mean six &lt;br /&gt;
pairs of integers have been returned in *pts_out*, and &lt;br /&gt;
*contrl+8* should contain a 45, the number of integers &lt;br /&gt;
returned in *int_out*. For every VDI call, *contrl+4* and &lt;br /&gt;
*contrl+8* are used the same way. You can always check them &lt;br /&gt;
to see how many values have been returned by a VDI function.&lt;br /&gt;
	Finally, in the above example, notice that we are &lt;br /&gt;
calling a subroutine called *vdi* to perform a VDI function. &lt;br /&gt;
The *vdi* subroutine works similarly to the *aes* &lt;br /&gt;
subroutine, setting up the VDI function and then doing a &lt;br /&gt;
*trap #2*.&lt;br /&gt;
&lt;br /&gt;
--Clearing the Workstation--&lt;br /&gt;
&lt;br /&gt;
The last step in getting the VDI initialized is to clear the &lt;br /&gt;
workstation. Clearing a workstation ensures that all the &lt;br /&gt;
devices have been flushed and the screen has been erased. In &lt;br /&gt;
other words, it presents us with a blank slate upon which &lt;br /&gt;
our program can begin to operate. To clear a workstation, we &lt;br /&gt;
call VDI function #3, *v_clrwk*, like this:&lt;br /&gt;
&lt;br /&gt;
move    #3,contrl&lt;br /&gt;
clr     contrl+2&lt;br /&gt;
clr     contrl+6&lt;br /&gt;
move    vws_handle,contrl+12&lt;br /&gt;
jsr     vdi&lt;br /&gt;
&lt;br /&gt;
	As you can see, this function has no special &lt;br /&gt;
parameters, nor does it return any values. It simply does &lt;br /&gt;
its business and returns control to the program. Notice &lt;br /&gt;
again, how we're using the control array. Because we have no &lt;br /&gt;
values in the *pts_in* and *int_in* arrays, we set both &lt;br /&gt;
*contrl+2* and *contrl+6* to 0. When calling a VDI function, &lt;br /&gt;
you also must be sure that the virtual workstation handle is &lt;br /&gt;
in *contrl+12*. In the above example, we show the &lt;br /&gt;
workstation handle being placed in *contrl+12*. However, in &lt;br /&gt;
the sample program, this instruction is missing. Why? &lt;br /&gt;
Because the handle is already in *contrl+12*, where it was &lt;br /&gt;
placed by the call to *v_opnvwk*. The handle will stay in &lt;br /&gt;
*contrl+12*, right where we want it, until we overwrite it.&lt;br /&gt;
&lt;br /&gt;
--Polylines--&lt;br /&gt;
&lt;br /&gt;
Now that we've got our workstation set up, we can get down &lt;br /&gt;
to business. The first graphic we'll experiment with is the &lt;br /&gt;
polyline. Those of you who are up on your linguistics know &lt;br /&gt;
that the prefix &amp;quot;poly&amp;quot; means &amp;quot;many.&amp;quot; A polyline is one or &lt;br /&gt;
more lines connected from point to point, which allows the &lt;br /&gt;
programmer to draw complex shapes with a single function &lt;br /&gt;
call.&lt;br /&gt;
	But before we draw our polylines, we need to set some &lt;br /&gt;
line attributes, like color, width, and end style. Any lines &lt;br /&gt;
drawn after we've set the attributes will use those &lt;br /&gt;
attributes. Also, the line attributes stay in effect until &lt;br /&gt;
we change them again.&lt;br /&gt;
	To set a line's color, we use a call to VDI function &lt;br /&gt;
#17, *vsl_color*, like this:&lt;br /&gt;
&lt;br /&gt;
move    #17,contrl&lt;br /&gt;
clr     contrl+2&lt;br /&gt;
move    #1,contrl+6&lt;br /&gt;
move    vws_handle,contrl+12&lt;br /&gt;
move    color,int_in&lt;br /&gt;
jsr     vdi&lt;br /&gt;
&lt;br /&gt;
	Here, *color* is an integer from 0 to the device &lt;br /&gt;
maximum (low resolution=15, medium resolution=3, and high &lt;br /&gt;
resolution=1). If we use a number higher than the maximum, &lt;br /&gt;
the function will default to color 1. On the ST, the default &lt;br /&gt;
color palette, starting with 0 and ending with 15, is white, &lt;br /&gt;
black, red, green, blue, cyan, yellow, magenta, white, &lt;br /&gt;
black, light red, light green, light blue, light cyan, light &lt;br /&gt;
yellow and light magenta. The actual color value set is &lt;br /&gt;
returned in *int_out*.&lt;br /&gt;
     When we're drawing lines, we can also choose an end &lt;br /&gt;
style with a call to VDI function #108, *vsl_ends*:&lt;br /&gt;
&lt;br /&gt;
move    #108,contrl&lt;br /&gt;
clr     contrl+2&lt;br /&gt;
move    #2,contrl+6&lt;br /&gt;
move    vws_handle,contrl+12&lt;br /&gt;
move    ends,int_in&lt;br /&gt;
move    ends,int_in+2&lt;br /&gt;
jsr     vdi&lt;br /&gt;
&lt;br /&gt;
In this case, *ends* is an integer value from 0 to 2. A &lt;br /&gt;
value of 0 will yield a square end, 1 will get us an arrow, &lt;br /&gt;
and 2 will result in a rounded end. Here we're using *ends* &lt;br /&gt;
as both the beginning and ending line style, but each end of &lt;br /&gt;
the line can have a different end style if we like. To do &lt;br /&gt;
this, we'd put the first end style in *int_in* and the &lt;br /&gt;
second end style in *int_in+2*. This function returns no &lt;br /&gt;
values.&lt;br /&gt;
     Finally, we can set the thickness of our lines with a &lt;br /&gt;
call to VDI function #16, *vsl_width*:&lt;br /&gt;
&lt;br /&gt;
move    #16,contrl&lt;br /&gt;
move    #1,contrl+2&lt;br /&gt;
clr     contrl+6&lt;br /&gt;
move    vws_handle,contrl+12&lt;br /&gt;
move    width,pts_in&lt;br /&gt;
clr     pts_in+2&lt;br /&gt;
jsr     vdi&lt;br /&gt;
&lt;br /&gt;
	The variable *width*, which is placed into the first &lt;br /&gt;
element of *pts_in*, must be an odd positive integer. The &lt;br /&gt;
line will be set to the closest width less than or equal to &lt;br /&gt;
the value of *width*. Notice that, for some strange reason, &lt;br /&gt;
*pts_in+2* must contain a 0. The actual width set is &lt;br /&gt;
returned in the first element of *pts_out*.&lt;br /&gt;
	Once we have the attributes set, we can draw our first &lt;br /&gt;
line. We do this with a call to VDI function #6, *v_pline*:&lt;br /&gt;
&lt;br /&gt;
move    #6,contrl&lt;br /&gt;
move    #2,contrl+2&lt;br /&gt;
clr     contrl+6&lt;br /&gt;
move    vws_handle,contrl+12&lt;br /&gt;
move    x1,pts_in&lt;br /&gt;
move    y1,pts_in+2&lt;br /&gt;
move    x2,pts_in+4&lt;br /&gt;
move    y2,pts_in+6&lt;br /&gt;
jsr     vdi&lt;br /&gt;
&lt;br /&gt;
	In this call, *x1* and *y1* are the X and Y coordinates &lt;br /&gt;
of one end of the line. The integers *x2* and *y2* are, of &lt;br /&gt;
course, the X and Y coordinates of the other end of the &lt;br /&gt;
line. In the example program, we're using *v_pline* to draw &lt;br /&gt;
only single lines. However, as we said before, this function &lt;br /&gt;
can be used to draw many connected lines. For example, to &lt;br /&gt;
extend the above example so that it draws two connected &lt;br /&gt;
lines, we could do something like this:&lt;br /&gt;
&lt;br /&gt;
move    #6,contrl&lt;br /&gt;
move    #3,contrl+2&lt;br /&gt;
clr     contrl+6&lt;br /&gt;
move    vws_handle,contrl+12&lt;br /&gt;
move    x1,pts_in&lt;br /&gt;
move    y1,pts_in+2&lt;br /&gt;
move    x2,pts_in+4&lt;br /&gt;
move    y2,pts_in+6&lt;br /&gt;
move    x3,pts_in+8&lt;br /&gt;
move    y3,pts_in+10&lt;br /&gt;
jsr     vdi&lt;br /&gt;
&lt;br /&gt;
	Notice that we are now loading a 3 into *contrl+2*, &lt;br /&gt;
because the *pts_in* array now contains three points. &lt;br /&gt;
(Remember, a point is really two values.) We've also loaded &lt;br /&gt;
the values *x3* and *y3* (the new point) into the next two &lt;br /&gt;
elements of the *pts_in* array. These values are the next &lt;br /&gt;
point to which the *v_pline* function should draw. We could &lt;br /&gt;
continue drawing lines by adding more and more points to the &lt;br /&gt;
*pts_in* array. We just must be sure that the value in &lt;br /&gt;
*contrl+2* is the total number of points in the array, &lt;br /&gt;
otherwise the function will ignore some of the points.&lt;br /&gt;
     If we're drawing a polyline at the smallest width, we &lt;br /&gt;
can choose between six system line types with a call to VDI &lt;br /&gt;
function #15, *vsl_type*:&lt;br /&gt;
&lt;br /&gt;
move    #15,contrl&lt;br /&gt;
clr     contrl+2&lt;br /&gt;
move    #1,contrl+6&lt;br /&gt;
move    vws_handle,contrl+12&lt;br /&gt;
move    type,int_in&lt;br /&gt;
jsr     vdi&lt;br /&gt;
&lt;br /&gt;
Here, *type* is an integer value from 1 to 7 as follows:&lt;br /&gt;
 &lt;br /&gt;
     1 solid        ________________&lt;br /&gt;
     2 long dash    ___ ___ ___ ___&lt;br /&gt;
     3 dots         ...............&lt;br /&gt;
     4 dash dot     __.__.__.__.__.&lt;br /&gt;
     5 dash         __ __ __ __ __ __&lt;br /&gt;
     6 dash dot dot __..__..__..__..__&lt;br /&gt;
     7 user defined&lt;br /&gt;
 &lt;br /&gt;
	Type 7 lets you set up your own line types, but we're &lt;br /&gt;
not going to get into that now. This function returns, in &lt;br /&gt;
*int_out*, the actual line type set.&lt;br /&gt;
	Now that we've covered the basics of setting up the VDI &lt;br /&gt;
and calling graphics functions, let's take a quick look at &lt;br /&gt;
some of the other graphics you can draw with the VDI.&lt;br /&gt;
&lt;br /&gt;
--Rectangles--&lt;br /&gt;
&lt;br /&gt;
We can use *v_pline* to draw a standard square-cornered box, &lt;br /&gt;
but the VDI also supplies a function that will let us draw &lt;br /&gt;
rectangles with rounded corners. To do this, we call VDI &lt;br /&gt;
function #11, sub-function #8, *v_rbox*:&lt;br /&gt;
&lt;br /&gt;
move    #11,contrl&lt;br /&gt;
move    #2,contrl+2&lt;br /&gt;
clr     contrl+6&lt;br /&gt;
move    #8,contrl+10&lt;br /&gt;
move    vws_handle,contrl+12&lt;br /&gt;
move    x1,pts_in&lt;br /&gt;
move    y1,pts_in+2&lt;br /&gt;
move    x2,pts_in+4&lt;br /&gt;
move    y2,pts_in+6&lt;br /&gt;
jsr     vdi&lt;br /&gt;
&lt;br /&gt;
	Here, we must supply the pixel coordinates of the &lt;br /&gt;
upper-left and lower-right corners. We place these values &lt;br /&gt;
into the *pts_in* array. Also note that this function call &lt;br /&gt;
requires that you place a sub-function number (8) into &lt;br /&gt;
*contrl+10*. The line attributes--color, style and width--&lt;br /&gt;
are used with *v_rbox*, allowing a wide variety of &lt;br /&gt;
rectangles. This function returns no values.&lt;br /&gt;
	You can also draw a filled rounded rectangle, using VDI &lt;br /&gt;
function #11, sub-function #9, *v_rfbox*:&lt;br /&gt;
&lt;br /&gt;
move    #11,contrl&lt;br /&gt;
move    #2,contrl+2&lt;br /&gt;
clr     contrl+6&lt;br /&gt;
move    #9,contrl+10&lt;br /&gt;
move    vws_handle,contrl+12&lt;br /&gt;
move    x1,pts_in&lt;br /&gt;
move    y1,pts_in+2&lt;br /&gt;
move    x2,pts_in+4&lt;br /&gt;
move    y2,pts_in+6&lt;br /&gt;
jsr     vdi&lt;br /&gt;
&lt;br /&gt;
	This function uses the currently active fill pattern, &lt;br /&gt;
which we'll learn to set later on.&lt;br /&gt;
	To draw a filled rectangle with square corners, use VDI &lt;br /&gt;
function #11, sub-function #1, *v_bar*:&lt;br /&gt;
&lt;br /&gt;
move    #11,contrl&lt;br /&gt;
move    #2,contrl+2&lt;br /&gt;
move    #0,contrl+6&lt;br /&gt;
move    #1,contrl+10&lt;br /&gt;
move    vws_handle,contrl+12&lt;br /&gt;
move    x1,pts_in&lt;br /&gt;
move    y1,pts_in+2&lt;br /&gt;
move    x2,pts_in+4&lt;br /&gt;
move    y2,pts_in+6&lt;br /&gt;
jsr     vdi&lt;br /&gt;
&lt;br /&gt;
	As you may suspect, this function, too, uses the &lt;br /&gt;
current fill pattern.&lt;br /&gt;
&lt;br /&gt;
--Circles, Ellipses, and Arcs--&lt;br /&gt;
&lt;br /&gt;
     GEM's VDI provides several functions for drawing &lt;br /&gt;
various types of curved lines and shapes. If you'd like to &lt;br /&gt;
draw a filled circle, just use VDI Function #11, sub-&lt;br /&gt;
function #4, *v_circle*:&lt;br /&gt;
&lt;br /&gt;
move    #11,contrl&lt;br /&gt;
move    #3,contrl+2&lt;br /&gt;
move    #0,contrl+6&lt;br /&gt;
move    #4,contrl+10&lt;br /&gt;
move    vws_handle,contrl+12&lt;br /&gt;
move    centerx,pts_in&lt;br /&gt;
move    centery,pts_in+2&lt;br /&gt;
move    #0,pts_in+4&lt;br /&gt;
move    #0,pts_in+6&lt;br /&gt;
move    radius,pts_in+8&lt;br /&gt;
move    #0,pts_in+10&lt;br /&gt;
jsr     vdi&lt;br /&gt;
&lt;br /&gt;
	Here, *centerx* and *centery* are the X and Y &lt;br /&gt;
coordinates of the circle's center, and *radius* is the &lt;br /&gt;
circle's radius. Note that *pts_in+4*, *pts_in+6*, and &lt;br /&gt;
*pts_in+10* all contain dummy arguments of 0. The *v_circle* &lt;br /&gt;
function, like *v_rfbox*, uses the current fill attributes.&lt;br /&gt;
	You can draw ellipses, too. An ellipse looks something &lt;br /&gt;
like a squashed circle or a solid oval and is drawn by a &lt;br /&gt;
call to VDI function #11, sub-function 5, *v_ellipse*:&lt;br /&gt;
&lt;br /&gt;
move    #11,contrl&lt;br /&gt;
move    #2,contrl+2&lt;br /&gt;
move    #0,contrl+6&lt;br /&gt;
move    #5,contrl+10&lt;br /&gt;
move    vws_handle,contrl+12&lt;br /&gt;
move    x,pts_in&lt;br /&gt;
move    y,pts_in+2&lt;br /&gt;
move    hrad,pts_in+4&lt;br /&gt;
move    vrad,pts_in+6&lt;br /&gt;
jsr     vdi&lt;br /&gt;
&lt;br /&gt;
	Here, the parameters *x* and *y* denote the ellipse's &lt;br /&gt;
center point, and *hrad* and *vrad* are the X and Y radiuses &lt;br /&gt;
in pixels. Once again, the active fill attributes are used. &lt;br /&gt;
No values are returned from the function.&lt;br /&gt;
	Arcs are curved lines and are easy to draw with VDI &lt;br /&gt;
function #11, sub-function #2, *v_arc*:&lt;br /&gt;
&lt;br /&gt;
move    #11,contrl&lt;br /&gt;
move    #4,contrl+2&lt;br /&gt;
move    #2,contrl+6&lt;br /&gt;
move    #2,contrl+10&lt;br /&gt;
move    vws_handle,contrl+12&lt;br /&gt;
move    angle1,int_in&lt;br /&gt;
move    angle2,int_in+2&lt;br /&gt;
move    x,pts_in&lt;br /&gt;
move    y,pts_in+2&lt;br /&gt;
move    #0,pts_in+4&lt;br /&gt;
move    #0,pts_in+6&lt;br /&gt;
move    #0,pts_in+8&lt;br /&gt;
move    #0,pts_in+10&lt;br /&gt;
move    rad,pts_in+12&lt;br /&gt;
move    #0,pts_in+14&lt;br /&gt;
jsr     vdi&lt;br /&gt;
&lt;br /&gt;
	The parameters *x*, *y*, and *rad* are the X,Y-&lt;br /&gt;
coordinates of the center and the radius, respectively. The &lt;br /&gt;
integers *angle1* and *angle2* are the beginning and ending &lt;br /&gt;
angles of the arc, in tenths of degrees (that is, values &lt;br /&gt;
from 1 to 3600). Note that *pts_in+4*, *pts_in+6*, &lt;br /&gt;
*pts_in+8*, *pts_in+10*, and *pts_in+14* all contain dummy &lt;br /&gt;
arguments that must contain zeroes. No value is returned &lt;br /&gt;
from the function.&lt;br /&gt;
	The final call in this family of functions allows you &lt;br /&gt;
to draw pie slices, which help you to draw pie charts. To &lt;br /&gt;
draw a pie slice, use a call to VDI function #11, sub-&lt;br /&gt;
function #3, *v_pieslice*:&lt;br /&gt;
&lt;br /&gt;
move    #11,contrl&lt;br /&gt;
move    #4,contrl+2&lt;br /&gt;
move    #2,contrl+6&lt;br /&gt;
move    #3,contrl+10&lt;br /&gt;
move    vws_handle,contrl+12&lt;br /&gt;
move    angle1,int_in&lt;br /&gt;
move    angle2,int_in+2&lt;br /&gt;
move    x,pts_in&lt;br /&gt;
move    y,pts_in+2&lt;br /&gt;
move    #0,pts_in+4&lt;br /&gt;
move    #0,pts_in+6&lt;br /&gt;
move    #0,pts_in+8&lt;br /&gt;
move    #0,pts_in+10&lt;br /&gt;
move    rad,pts_in+12&lt;br /&gt;
move    #0,pts_in+14&lt;br /&gt;
jsr     vdi&lt;br /&gt;
&lt;br /&gt;
	The parameters here are the same as those for the arc &lt;br /&gt;
function. However, the body of the pie slice will be colored &lt;br /&gt;
by whatever fill pattern is active. This function returns no &lt;br /&gt;
values.&lt;br /&gt;
&lt;br /&gt;
--Polymarkers--&lt;br /&gt;
&lt;br /&gt;
     Polymarkers are a number of predefined shapes you can &lt;br /&gt;
use in your graphics. To draw them, you call VDI function &lt;br /&gt;
#7, *v_pmarker*:&lt;br /&gt;
&lt;br /&gt;
move    #7,contrl&lt;br /&gt;
move    #3,contrl+2&lt;br /&gt;
move    #0,contrl+6&lt;br /&gt;
move    vws_handle,contrl+12&lt;br /&gt;
move    x1,pts_in&lt;br /&gt;
move    y1,pts_in+2&lt;br /&gt;
move    x2,pts_in+4&lt;br /&gt;
move    y2,pts_in+6&lt;br /&gt;
move    x3,pts_in+8&lt;br /&gt;
move    y3,pts_in+10&lt;br /&gt;
jsr     vdi&lt;br /&gt;
	&lt;br /&gt;
	The parameter placed in *contrl+2* is the number of &lt;br /&gt;
markers you want to draw. The X,Y coordinates for the &lt;br /&gt;
markers are stored in the *pts_in* array. The above example &lt;br /&gt;
shows three markers being drawn, but you can draw as many as &lt;br /&gt;
you need. This function returns no values.&lt;br /&gt;
     What do these markers look like? You have a choice of &lt;br /&gt;
six predefined shapes which (from 1 to 6, respectively) are &lt;br /&gt;
dot, plus sign, asterisk, square, diagonal cross, and &lt;br /&gt;
diamond. To set the polymarker type, call VDI function #18, &lt;br /&gt;
*vsm_type*:&lt;br /&gt;
&lt;br /&gt;
move    #18,contrl&lt;br /&gt;
move    #0,contrl+2&lt;br /&gt;
move    #1,contrl+6&lt;br /&gt;
move    vws_handle,contrl+12&lt;br /&gt;
move    type,int_in&lt;br /&gt;
jsr     vdi&lt;br /&gt;
&lt;br /&gt;
	Here, *type* is a value from 1 to 6. If you should &lt;br /&gt;
choose a value out of this range, the function will select &lt;br /&gt;
the asterisk as a default. The value chosen will be returned &lt;br /&gt;
in *int_out*.&lt;br /&gt;
     There are two other attributes that affect polymarkers: &lt;br /&gt;
color and height. Color is set with a call to VDI function &lt;br /&gt;
#20, *vsm_color*:&lt;br /&gt;
&lt;br /&gt;
move    #20,contrl&lt;br /&gt;
move    #0,contrl+2&lt;br /&gt;
move    #1,contrl+6&lt;br /&gt;
move    vws_handle,contrl+12&lt;br /&gt;
move    color,int_in&lt;br /&gt;
jsr     vdi&lt;br /&gt;
&lt;br /&gt;
	Here, *color* is a value from 0 to the device maximum. &lt;br /&gt;
All the rules of the *vsl_color* call apply in this case. &lt;br /&gt;
The actual color set is returned in *int_out*.&lt;br /&gt;
     You can change the size of all polymarkers, except the &lt;br /&gt;
dot (which always appears in the smallest size), with a call &lt;br /&gt;
to VDI function #19, *vsm_height*:&lt;br /&gt;
&lt;br /&gt;
move    #19,contrl&lt;br /&gt;
move    #1,contrl+2&lt;br /&gt;
move    #0,contrl+6&lt;br /&gt;
move    vws_handle,contrl+12&lt;br /&gt;
move    #0,pts_in&lt;br /&gt;
move    height,pts_in+2&lt;br /&gt;
jsr     vdi&lt;br /&gt;
&lt;br /&gt;
	The parameter *height* is the polymarker's size on the &lt;br /&gt;
Y-axis. The actual height will be the greatest height &lt;br /&gt;
available on the device, less than or equal to the height &lt;br /&gt;
parameter. This will be returned in *pts_out+2*. Note that, &lt;br /&gt;
in the above function call, *pts_in* is always 0, with the &lt;br /&gt;
requested height being placed in *pts_in+2*.&lt;br /&gt;
&lt;br /&gt;
--Fill Patterns--&lt;br /&gt;
&lt;br /&gt;
GEM supplies many patterns we can use to fill our figures. &lt;br /&gt;
There's a series of functions to let us set these patterns &lt;br /&gt;
up the way we want them. The first step is a call to VDI &lt;br /&gt;
function #23, *vsf_interior*:&lt;br /&gt;
&lt;br /&gt;
move    #23,contrl&lt;br /&gt;
move    #0,contrl+2&lt;br /&gt;
move    #1,contrl+6&lt;br /&gt;
move    vws_handle,contrl+12&lt;br /&gt;
move    pattern,int_in&lt;br /&gt;
jsr     vdi&lt;br /&gt;
&lt;br /&gt;
	Here, *pattern* is a value from 0 to 4. The values are &lt;br /&gt;
interpreted as follows:&lt;br /&gt;
 &lt;br /&gt;
 0  Hollow (background color)&lt;br /&gt;
 1  Solid&lt;br /&gt;
 2  Pattern&lt;br /&gt;
 3  Hatch&lt;br /&gt;
 4  User-defined&lt;br /&gt;
 &lt;br /&gt;
	The actual pattern set is returned in *int_out*.&lt;br /&gt;
	If you choose style 0 or 1, you need go no further, but &lt;br /&gt;
style 2 allows you to choose between 24 different patterns, &lt;br /&gt;
and style 3 provides 12 hatch styles. You choose the pattern &lt;br /&gt;
you wish to use, with a call to VDI function #24, &lt;br /&gt;
*vsf_style*:&lt;br /&gt;
&lt;br /&gt;
move    #24,contrl&lt;br /&gt;
move    #0,contrl+2&lt;br /&gt;
move    #1,contrl+6&lt;br /&gt;
move    vws_handle,contrl+12&lt;br /&gt;
move    fill,int_in&lt;br /&gt;
jsr     vdi&lt;br /&gt;
&lt;br /&gt;
Here, *fill* is a value from 0 to 23. Consult your reference &lt;br /&gt;
manual to see what these styles look like. The fill that was &lt;br /&gt;
actually set is returned in *int_out*.&lt;br /&gt;
     The color of the fill is selected with a call to VDI &lt;br /&gt;
function #25, *vsf_color*:&lt;br /&gt;
&lt;br /&gt;
move    #25,contrl&lt;br /&gt;
move    #0,contrl+2&lt;br /&gt;
move    #1,contrl+6&lt;br /&gt;
move    vws_handle,contrl+12&lt;br /&gt;
move    color,int_in&lt;br /&gt;
jsr     vdi&lt;br /&gt;
&lt;br /&gt;
	All the rules for the *vsl_color* function apply here, &lt;br /&gt;
also, with the actual color that was set returned in &lt;br /&gt;
*int_out*.&lt;br /&gt;
     Finally, you can choose between a visible or invisible &lt;br /&gt;
border for your fill with a call to VDI function #104, &lt;br /&gt;
*vsf_perimeter*:&lt;br /&gt;
&lt;br /&gt;
move    #104,contrl&lt;br /&gt;
move    #0,contrl+2&lt;br /&gt;
move    #1,contrl+6&lt;br /&gt;
move    vws_handle,contrl+12&lt;br /&gt;
move    flag,int_in&lt;br /&gt;
jsr     vdi&lt;br /&gt;
&lt;br /&gt;
	Here, a *flag* value of 0 will give you an invisible &lt;br /&gt;
border. Any other value will cause the border to be drawn in &lt;br /&gt;
the current fill color.&lt;br /&gt;
&lt;br /&gt;
--Conclusion--&lt;br /&gt;
&lt;br /&gt;
     Now that you've been introduced to many of the graphics &lt;br /&gt;
functions available to you through the VDI, study the sample &lt;br /&gt;
program to see them in action, then take some time and &lt;br /&gt;
experiment with the VDI on your own. See if you can write a &lt;br /&gt;
program to draw a simple picture, or maybe a graph.&lt;br /&gt;
&lt;br /&gt;
--Summary--&lt;br /&gt;
&lt;br /&gt;
* The VDI (Virtual Device Interface) controls most of the &lt;br /&gt;
ST's graphic capabilities and provides some mouse and cursor &lt;br /&gt;
control functions, as well.&lt;br /&gt;
&lt;br /&gt;
* You call VDI functions much like you call AES functions, &lt;br /&gt;
by placing appropriate values into control and input arrays, &lt;br /&gt;
and then calling the function by using a *trap #2* &lt;br /&gt;
instruction.&lt;br /&gt;
&lt;br /&gt;
* To initialize the VDI, you must get a handle to the &lt;br /&gt;
physical screen, open a virtual workstation, and finally &lt;br /&gt;
clear the workstation.&lt;br /&gt;
&lt;br /&gt;
* The AES function #77, *graf_handle*, obtains a handle to &lt;br /&gt;
the physical workstation and returns information about the &lt;br /&gt;
system font.&lt;br /&gt;
&lt;br /&gt;
* The VDI function #100, *v_opnvwk*, obtains a handle to a &lt;br /&gt;
virtual workstation.&lt;br /&gt;
&lt;br /&gt;
* The VDI function #3, *v_clrwk*, clears a workstation, &lt;br /&gt;
flushing all devices and clearing the screen.&lt;br /&gt;
&lt;br /&gt;
* The VDI functions *vsl_color* (#17), *vsl_ends* (#108), &lt;br /&gt;
*vsl_width* (#16), and *vsl_type* (#15) set various line &lt;br /&gt;
attributes.&lt;br /&gt;
&lt;br /&gt;
* The VDI function #6, *v_pline*, draws polylines.&lt;br /&gt;
&lt;br /&gt;
* Other shapes can be drawn using the VDI functions *v_rbox* &lt;br /&gt;
(#11,8), *v_rfbox* (#11,9), *v_bar* (#11,1), *v_circle* &lt;br /&gt;
(#11,4), *v_ellipse* (#11,5), *v_arc* (#11,2), and &lt;br /&gt;
*v_pieslice* (#11,3).&lt;br /&gt;
&lt;br /&gt;
* Polymarkers are drawn by VDI function #7, *v_pmarker*.&lt;br /&gt;
&lt;br /&gt;
* The polymarker attributes can be set by the VDI functions &lt;br /&gt;
*vsm_type* (#18), *vsm_color* (#20), and *vsm_height* (#19).&lt;br /&gt;
&lt;br /&gt;
* The current fill pattern's attributes can be set by the &lt;br /&gt;
VDI functions *vsf_interior* (#23), *vsf_style* (#24), &lt;br /&gt;
*vsf_color* (#25), and *vsf_perimeter* (#104).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[CW_PROG5.S]] (Source of the chapiter)&amp;lt;br&amp;gt;&lt;br /&gt;
[[CW_PROG5MAC.S]] (Source of the chapiter)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Back to [[Assembly_language_tutorials]]&lt;/div&gt;</summary>
		<author><name>&gt;Zorro 2</name></author>
	</entry>
</feed>