Line A: Difference between revisions

From Atari Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
Line 1: Line 1:
  +
==Introduction==
<pre>
 
THE LONG-AWAITED Line-A DOCUMENT
 
   
  +
In order to provide ''quick-and-dirty'' access to the [[Assembly language|assembler-level]] graphics routines, [[Atari]] engineers have set up the [[MC68000]]'s '''Line A''' [[exception]] as an interface to several useful routines. The Line A interface is faster than going through [[GEM]]'s [[VDI]] and has some extra features. Also, Line A calls require less application
  +
code than their VDI counterparts. Of course, Line A does not replace the VDI completely, but if an application only needs a few primitive graphics functions (and wants maximum performance), then Line A is sufficient and optimal.
   
  +
The Line-A interface is provided for the hacker-at-heart and no claims are made about its ease of use. The interface may seem
In order to provide "quick-and-dirty" access to the assembler-
 
  +
unusually inconsistent, but it was not designed; it simply fell out as a freebie from the low-level VDI primitives interface. That is, these routines are the heart of the VDI.
level graphics routines, ATARI engineers have set up the 68000's
 
Line-A exception as an interface to several useful routines. The
 
Line-A interface is faster than going through GEM's VDI and has
 
some extra features. Also, Line-A calls require less application
 
code than their VDI counterparts. Of course, Line-A doesn't
 
replace the VDI completely, but if an application only needs a
 
few primitive graphics functions (and wants maximum performance),
 
then Line-A is sufficient (and optimal).
 
   
  +
The Line-A interface consists of 15 opcodes. The calls to Line-A are assembled as 1-word instructions, the highest 4 bits of which are 1010 ($A, hence Line A) and the lower 12 [[bit|bits]] of which are used as the [[opcode]] field. Following is a description of the 15 opcodes:
The Line-A interface is provided for the hacker-at-heart and
 
no claims are made about its ease of use. The interface may seem
 
unusually inconsistent, but it was not designed; it simply fell
 
out as a freebie from the low-level VDI primitives interface.
 
That is, these routines are the heart of the VDI.
 
   
  +
<div style="border:1px solid #fff; padding:3px !important;overflow:hidden;width:40em;float:center;text-align:center;margin-left:1.5em;border-width:.5em 0 .8em 1.4em;">
The Line-A interface consists of 15 opcodes. The calls to
 
  +
{| class="wikitable" style="text-align:left;font-size:90%;background:#efefef;border:1px solid #666;width:100%;"
Line-A are assembled as 1-word instructions, the highest 4 bits
 
  +
|+ style="font-size:12pt;padding:0.2em 0;border:1px solid #666;border-bottom:0;" | '''''Line A opcodes'''''
of which are 1010 ($A, hence Line-A) and the lower 12 bits of
 
  +
! Opcode !! Description
which are used as the opcode field. Following is a description
 
  +
|-
of the 15 opcodes:
 
  +
| 0 || [[#init|Initialization]]
  +
|-
  +
| 1 || [[#put_pixel|Put pixel]]
  +
|-
  +
| 2 || [[#get_pixel|Get pixel]]
  +
|-
  +
| 3 || [[#line|Line]]
  +
|-
  +
| 4 || [[#horizontal_line|Horizontal line]]
  +
|-
  +
| 5 || [[#filled_rectangle|Filled rectangle]]
  +
|-
  +
| 6 || [[#filled_polygon|Line-by-line filled polygon]]
  +
|-
  +
| 7 || [[#bitblt|BitBlt]]
  +
|-
  +
| 8 || [[#textblt|TextBlt]]
  +
|-
  +
| 9 || [[#show_mouse|Show mouse]]
  +
|-
  +
| 10 || [[#hide_mouse|Hide mouse]]
  +
|-
  +
| 11 || [[#transform_mouse|Transform mouse]]
  +
|-
  +
| 12 || [[#undraw_sprite|Undraw sprite]]
  +
|-
  +
| 13 || [[#draw_sprite|Draw sprite]]
  +
|-
  +
| 14 || [[#copy_raster_form|Copy raster form]]
  +
|-
  +
| 15 || Seedfill (exists only in versions of TOS after the first release)
  +
|}
  +
</div> </br>
   
  +
The Line A routines have some features that the VDI does not support. <tt>BitBlt</tt> supports half-tone patterns on the source and <tt>TextBlt</tt> supports all 16 <tt>BitBlt</tt> logic operations, not just the four [[GEM]] [[VDI]] writing modes. In addition to these straight-forward extensions, Line A also allows the adventurous programmer to experiment with special effects. The <tt>BitBlt</tt> is especially generous in this area.
0 = Initialization.
 
1 = Put pixel.
 
2 = Get pixel.
 
3 = Line.
 
4 = Horizontal line.
 
5 = Filled rectangle.
 
6 = Line-by-line filled polygon.
 
7 = BitBlt.
 
8 = TextBlt.
 
9 = Show mouse.
 
10 = Hide mouse.
 
11 = Transform mouse.
 
12 = Undraw sprite.
 
13 = Draw sprite.
 
14 = Copy raster form.
 
   
  +
==Description of graphics routines==
15 = Seedfill. (exists only in versions of TOS after the 1st release)
 
   
  +
<span id="init"></span>
The Line-A routines have some features that the VDI doesn't
 
  +
<div style="border:1px solid #fff; padding:5px !important;overflow;hidden;width:90%;float:center;text-align:left;margin-left:1.5em;border-width:.5em 0 .8em 1.4em;">
support. BitBlt supports half-tone patterns on the source and
 
  +
{| class="wikitable" style="text-align:left;font-size:95%;background:#F0F8FF;border:1px solid #666;width:100%;cellpadding:4;cellspacing:5"
TextBlt supports all 16 BitBlt logic operations, not just the 4
 
  +
! colspan="2" style="background:#00BFFF;font-size:12pt;height:40px" |'''Initialization (0)'''
GEM VDI writing modes. In addition to these straight-forward
 
  +
|-valign="top"
extensions Line-A also allows the adventurous programmer to
 
  +
| '''Code:'''
experiment with special effects. The BitBlt is especially
 
  +
| <tt>dc.w $A000 ; Init Line A.</tt>
generous in this area.
 
  +
|-valign="top"
  +
| '''Input:''' || None
  +
|-valign="top"
  +
|width="10%"|'''Output:'''
  +
|width="90%"|<tt>d0</tt> = pointer to the base address of Line A interface variables </br>
  +
<tt>a0</tt> = pointer to the base address of Line A interface variables </br>
  +
<tt>a1</tt> = pointer to the array of pointers to the three [[system font]] headers </br>
  +
<tt>a2</tt> = pointer to array of pointers to the fifteen Line A routines
  +
|-valign="top"
  +
|width="10%"|'''Note:'''
  +
|width="90%"|The value returned in <tt>a0</tt> is the sine qua non of the Line A interface. Inputs to all the other Line-A operations are made relative to this value, i.e., the Line A interface variables are contained in a structure pointed to by <tt>a0</tt>. The offsets of these variables in the structure are given below.
  +
|-valign="top"
  +
|width="10%"|'''Bugs:'''
  +
|width="90%"|In the first TOS release, a2 is not returned as described above. Instead, it is preserved across the Line A call. See example program #2 at the end of this document for the technique that makes <tt>a2</tt> point to the proper place.
  +
|}
  +
</div>
   
  +
<span id="put_pixel"></span>
  +
<div style="border:1px solid #fff; padding:5px !important;overflow;hidden;width:90%;float:center;text-align:left;margin-left:1.5em;border-width:.5em 0 .8em 1.4em;">
  +
{| class="wikitable" style="text-align:left;font-size:95%;background:#F0F8FF;border:1px solid #666;width:100%;cellpadding:4;cellspacing:5"
  +
! colspan="2" style="background:#00BFFF;font-size:12pt;height:40px" |'''Put pixel (1)'''
  +
|-valign="top"
  +
| '''Code:''' || <tt>dc.w $A001 ; Plot a pixel at x,y.</tt>
  +
|-valign="top"
  +
|width="10%"|'''Input:'''
  +
|width="90%"|[[Intin|<tt>INTIN[0]</tt>]] = [[pixel value]] </br>
  +
[[Ptsin|<tt>PTSIN[0]</tt>]] = x coordinate </br>
  +
[[Ptsin|<tt>PTSIN[1]</tt>]] = y coordinate
  +
|-valign="top"
  +
| '''Output:''' || None
  +
|-valign="top"
  +
|width="10%"|'''Note:'''
  +
|width="90%"|For a discussion of the [[Contrl|<tt>CONTRL</tt>]], [[Intin|<tt>INTIN</tt>]], [[Ptsin|<tt>PTSIN</tt>]], [[Intout|<tt>INTOUT</tt>]], and [[Ptsout|<tt>PTSOUT</tt>]] arrays, see the GEM VDI manual.
  +
|}
  +
</div>
   
  +
<span id="get_pixel"></span>
  +
<div style="border:1px solid #fff; padding:5px !important;overflow;hidden;width:90%;float:center;text-align:left;margin-left:1.5em;border-width:.5em 0 .8em 1.4em;">
  +
{| class="wikitable" style="text-align:left;font-size:95%;background:#F0F8FF;border:1px solid #666;width:100%;cellpadding:4;cellspacing:5"
  +
! colspan="2" style="background:#00BFFF;font-size:12pt;height:40px" |'''Get pixel (2)'''
  +
|-valign="top"
  +
| '''Code:''' || <tt>dc.w $A002 ; Get the pixel at x,y.</tt>
  +
|-valign="top"
  +
|width="10%"|'''Input:'''
  +
|width="90%"|[[Ptsin|<tt>PTSIN[0]</tt>]] = x coordinate </br>
  +
[[Ptsin|<tt>PTSIN[1]</tt>]] = y coordinate
  +
|-valign="top"
  +
| '''Output:''' || <tt>d0</tt> = pixel value.
  +
|}
  +
</div>
   
  +
<span id="line"></span>
(0) Initialization
 
  +
<div style="border:1px solid #fff; padding:5px !important;overflow;hidden;width:90%;float:center;text-align:left;margin-left:1.5em;border-width:.5em 0 .8em 1.4em;">
  +
{| class="wikitable" style="text-align:left;font-size:95%;background:#F0F8FF;border:1px solid #666;width:100%;cellpadding:4;cellspacing:5"
  +
! colspan="2" style="background:#00BFFF;font-size:12pt;height:40px" |'''Line (3)'''
  +
|-valign="top"
  +
| '''Code:''' || <tt>dc.w $A003 ; Draw a line between (x1,y1) and (x2,y2).</tt>
  +
|-valign="top"
  +
|width="10%"|'''Input:'''
  +
|width="90%"|<tt>X1</tt> = x1 coordinate </br>
  +
<tt>Y1</tt> = y1 coordinate </br>
  +
<tt>X2</tt> = x2 coordinate </br>
  +
<tt>Y2</tt> = y2 coordinate </br>
  +
<tt>COLBIT0</tt> = bit value for plane 0 </br>
  +
<tt>COLBIT1</tt> = bit value for plane 1 </br>
  +
<tt>COLBIT2</tt> = bit value for plane 2 </br>
  +
<tt>COLBIT3</tt> = bit value for plane 3 </br>
  +
<tt>LNMASK</tt> = line style mask </br>
  +
<tt>WMODE</tt> = writing mode </br>
  +
<tt>LSTLIN</tt> = always set this to -1, if using xor mode else ignore it
  +
|-valign="top"
  +
|'''Output:''' || <tt>LNMASK</tt> is rotated to align with right-most endpoint.
  +
|-valign="top"
  +
|'''Quirks:'''
  +
|
  +
* If the line is horizontal, <tt>LNMASK</tt> is a word-aligned pattern, not a line style. That is, a bit other thanbit 15 of <tt>LNMASK</tt> may be used at the left-most endpoint.
  +
* As the foregoing references imply, the line is always drawn from left to right, not from (<tt>X1,Y1</tt>) to (<tt>X2,Y2</tt>). Thus, <tt>LNMASK</tt> is always applied from left to right.
  +
|-valign="top"
  +
|'''Note:'''
  +
|Because of the quirks, an application cannot depend upon the phase of the <tt>LNMASK</tt> being properly updated between calls to line-drawing primitives. If the phase is critical, the application must compute and init <tt>LNMASK</tt> before each line is drawn.
   
  +
<tt>LNMASK</tt> is applied to the line-drawing DDA algorithm along the direction of greater delta. If delta Y is greater than delta X, then <tt>LNMASK</tt> is applied in the Y direction.
... ...
 
dc.w $A000 ; Init the Line-A.
 
... ...
 
   
  +
These line-drawing quirks and notes apply to the [[GEM]] [[VDI]], too.
input: none.
 
  +
|}
  +
</div>
   
  +
<span id="horizontal_line"></span>
output: d0 = ptr to the base address of Line-A interface variables.
 
  +
<div style="border:1px solid #fff; padding:5px !important;overflow;hidden;width:90%;float:center;text-align:left;margin-left:1.5em;border-width:.5em 0 .8em 1.4em;">
a0 = ptr to the base address of Line-A interface variables.
 
  +
{| class="wikitable" style="text-align:left;font-size:95%;background:#F0F8FF;border:1px solid #666;width:100%;cellpadding:4;cellspacing:5"
a1 = ptr to array of ptrs to the 3 system font headers.
 
  +
! colspan="2" style="background:#00BFFF;font-size:12pt;height:40px" |'''Horizontal line (4)'''
a2 = ptr to array of ptrs to the 15 Line-A routines.
 
  +
|-valign="top"
  +
| '''Code:''' || <tt>dc.w $A004 ; Draw a line from (x1,y1) to (x2,y1).</tt>
  +
|-valign="top"
  +
|width="10%"|'''Input:'''
  +
|width="90%|<tt>X1</tt> = x1 coordinate </br>
  +
<tt>Y1</tt> = y1 coordinate </br>
  +
<tt>X2</tt> = x2 coordinate </br>
  +
<tt>COLBIT0</tt> = bit value for plane 0 </br>
  +
<tt>COLBIT1</tt> = bit value for plane 1 </br>
  +
<tt>COLBIT2</tt> = bit value for plane 2 </br>
  +
<tt>COLBIT3</tt> = bit value for plane 3 </br>
  +
<tt>WMODE</tt> = writing mode </br>
  +
<tt>PATPTR</tt> = ptr to the fill pattern </br>
  +
<tt>PATMSK</tt> = pattern index</br>
  +
<tt>MFILL</tt> = multi-plane pattern flag
  +
|-valign="top"
  +
| '''Output:''' || None
  +
|}
  +
</div>
   
  +
<span id="filled_rectangle"></span>
note: The value returned in a0 is the sine qua non of the Line-A
 
  +
<div style="border:1px solid #fff; padding:5px !important;overflow;hidden;width:90%;float:center;text-align:left;margin-left:1.5em;border-width:.5em 0 .8em 1.4em;">
interface. Inputs to all the other Line-A operations are
 
  +
{| class="wikitable" style="text-align:left;font-size:95%;background:#F0F8FF;border:1px solid #666;width:100%;cellpadding:4;cellspacing:5"
made relative to this value, i.e., the Line-A interface
 
  +
! colspan="2" style="background:#00BFFF;font-size:12pt;height:40px" |'''Filled rectangle (5)'''
variables are contained in a structure pointed to by a0.
 
  +
|-valign="top"
The offsets of these variables in the structure are given
 
  +
| '''Code:''' || <tt>dc.w $A005 ; Draw a filled rectangle with upper left corner at (x1,y1) and lower right corner at (x2,y2).</tt>
below.
 
  +
|-valign="top"
  +
|width="10%"|'''Input:'''
  +
|width="90%|<tt>X1</tt> = x1 coordinate </br>
  +
<tt>Y1</tt> = y1 coordinate </br>
  +
<tt>X2</tt> = x2 coordinate </br>
  +
<tt>Y2</tt> = y2 coordinate </br>
  +
<tt>COLBIT0</tt> = bit value for plane 0 </br>
  +
<tt>COLBIT1</tt> = bit value for plane 1 </br>
  +
<tt>COLBIT2</tt> = bit value for plane 2 </br>
  +
<tt>COLBIT3</tt> = bit value for plane 3 </br>
  +
<tt>WMODE</tt> = writing mode </br>
  +
<tt>PATPTR</tt> = ptr to the fill pattern </br>
  +
<tt>PATMSK</tt> = fill pattern index</br>
  +
<tt>MFILL</tt> = multi-plane fill pattern flag</br>
  +
<tt>CLIP</tt> = clipping flag</br>
  +
<tt>XMINCL</tt> = x minimum for clipping</br>
  +
<tt>XMAXCL</tt> = x maximum for clipping</br>
  +
<tt>YMINCL</tt> = y minimum for clipping</br>
  +
<tt>YMAXCL</tt> = y maximum for clipping
  +
|-valign="top"
  +
| '''Output:''' || None
  +
|}
  +
</div>
   
  +
<span id="filled_polygon"></span>
bugs: In the first TOS release, a2 is not returned as described
 
  +
<div style="border:1px solid #fff; padding:5px !important;overflow;hidden;width:90%;float:center;text-align:left;margin-left:1.5em;border-width:.5em 0 .8em 1.4em;">
above. Instead, it is preserved across the Line-A call.
 
  +
{| class="wikitable" style="text-align:left;font-size:95%;background:#F0F8FF;border:1px solid #666;width:100%;cellpadding:4;cellspacing:5"
See Example Program #2 at the end of this document for the
 
  +
! colspan="2" style="background:#00BFFF;font-size:12pt;height:40px" |'''Line-by-line filled polygon (6)'''
technique that makes a2 point to the proper place.
 
  +
|-valign="top"
  +
| '''Code:''' || <tt>dc.w $A006 ; Draw 1 scan-line of a filled polygon.</tt>
  +
|-valign="top"
  +
|width="10%"|'''Input:'''
  +
|width="90%|<tt>PTSIN[]</tt> = array of polygon vertices </br>
  +
<tt>CONTRL[1]</tt> = n = number of vertices </br>
  +
<tt>Y1</tt> = y coordinate of scan-line to fill </br>
  +
<tt>COLBIT0</tt> = bit value for plane 0 </br>
  +
<tt>COLBIT1</tt> = bit value for plane 1 </br>
  +
<tt>COLBIT2</tt> = bit value for plane 2 </br>
  +
<tt>COLBIT3</tt> = bit value for plane 3 </br>
  +
<tt>WMODE</tt> = writing mode </br>
  +
<tt>PATPTR</tt> = ptr to the fill pattern </br>
  +
<tt>PATMSK</tt> = fill pattern index</br>
  +
<tt>MFILL</tt> = multi-plane fill pattern flag</br>
  +
<tt>CLIP</tt> = clipping flag</br>
  +
<tt>XMINCL</tt> = x minimum for clipping</br>
  +
<tt>XMAXCL</tt> = x maximum for clipping</br>
  +
<tt>YMINCL</tt> = y minimum for clipping</br>
  +
<tt>YMAXCL</tt> = y maximum for clipping
  +
|-valign="top"
  +
| '''Output:''' || <tt>X1</tt> and <tt>X2</tt> are clobbered.
  +
|-valign="top"
  +
| '''Note:''' || The first end point must be repeated at the end of the list of n end points.
  +
|}
  +
</div>
   
  +
<span id="bitblt"></span>
(1) Put pixel
 
  +
<div style="border:1px solid #fff; padding:5px !important;overflow;hidden;width:90%;float:center;text-align:left;margin-left:1.5em;border-width:.5em 0 .8em 1.4em;">
  +
{| class="wikitable" style="text-align:left;font-size:95%;background:#F0F8FF;border:1px solid #666;width:100%;cellpadding:4;cellspacing:5"
  +
! colspan="2" style="background:#00BFFF;font-size:12pt;height:40px" |'''BitBlt (7)'''
  +
|-valign="top"
  +
| '''Code:''' || <tt>dc.w $A007 ; Perform a BIT BLock Transfer.</tt>
  +
|-valign="top"
  +
|width="10%"|'''Input:'''
  +
|width="90%|<tt>a6</tt> = ptr to a structure of input parameters
  +
|-
  +
| '''Output:''' || None
  +
|-
  +
| colspan="2" height="20pt" | .
  +
{|style="text-align:left;font-size:95%;background:#F0F8FF;border:1px solid #666;width:100%;cellpadding:4;cellspacing:5"
  +
! colspan="2" style="background:#B0C4DE;font-size:12pt;height:30px" |'''BitBlt parameter block offsets'''
  +
|-
  +
|<pre><nowiki>
  +
B_WD equ +00 ; width of block in pixels
  +
B_HT equ +02 ; height of block in pixels
   
  +
PLANE_CT equ +04 ; number of consecutive planes to blt {*}
... ...
 
dc.w $A001 ; Plot a pixel at x,y.
 
... ...
 
   
  +
FG_COL equ +06 ; foreground color (logic op index:hi bit) {*}
input: INTIN[0] = pixel value.
 
  +
BG_COL equ +08 ; background color (logic op index:lo bit) {*}
PTSIN[0] = x coordinate.
 
  +
OP_TAB equ +10 ; logic ops for all fore and background combos (see below)
PTSIN[1] = y coordinate.
 
  +
; contents of OP_TAB
  +
; +00 byte logic operation employed when foreground and background color
  +
; bits for current plane are both clear (0)
   
  +
; +01 byte logic operation employed when current plane's foreground color
output: none.
 
  +
; bit is clear (0) and background color bit is set (1)
   
  +
; +02 byte logic operation employed when current plane's foreground color
note: For a discussion of the CONTRL, INTIN, PTSIN, INTOUT, & PTSOUT
 
  +
; bit is set (1) and background color bit is clear (0)
arrays, see the GEM VDI manual.
 
 
 
(2) Get pixel
 
 
... ...
 
dc.w $A002 ; Get the pixel at x,y.
 
... ...
 
 
input: PTSIN[0] = x coordinate.
 
PTSIN[1] = y coordinate.
 
 
output: d0 = pixel value.
 
 
 
(3) Line
 
 
... ...
 
dc.w $A003 ; Draw a line between (x1,y1) and (x2,y2).
 
... ...
 
 
input: X1 = x1 coordinate.
 
Y1 = y1 coordinate.
 
X2 = x2 coordinate.
 
Y2 = y2 coordinate.
 
COLBIT0 = bit value for plane 0.
 
COLBIT1 = bit value for plane 1.
 
COLBIT2 = bit value for plane 2.
 
COLBIT3 = bit value for plane 3.
 
LNMASK = line style mask.
 
WMODE = writing mode.
 
LSTLIN = always set this to -1, if using xor mode.
 
else ignore it.
 
 
output: LNMASK is rotated to align with right-most endpoint.
 
 
quirks: 1) If the line is horizontal, LNMASK is a word-aligned
 
pattern, not a line style. That is, a bit other than
 
bit 15 of LNMASK may be used at the left-most endpoint.
 
 
2) As the foregoing references imply, the line is always
 
drawn from left to right, not from (X1,Y1) to (X2,Y2).
 
Thus, LNMASK is always applied from left to right.
 
 
 
note: Because of the quirks, an application cannot depend upon the
 
phase of the LNMASK being properly updated between calls
 
to line-drawing primitives. If the phase is critical, the
 
application must compute and init LNMASK before each line
 
is drawn.
 
 
LNMASK is applied to the line-drawing DDA algorithm along
 
the direction of greater delta. If delta Y is greater than
 
delta X, then LNMASK is applied in the Y direction.
 
 
These line-drawing quirks and notes apply to the GEM VDI, too.
 
 
 
(4) Horizontal line
 
 
... ...
 
dc.w $A004 ; Draw a line from (x1,y1) to (x2,y1).
 
... ...
 
 
input: X1 = x1 coordinate.
 
Y1 = y1 coordinate.
 
X2 = x2 coordinate.
 
COLBIT0 = bit value for plane 0.
 
COLBIT1 = bit value for plane 1.
 
COLBIT2 = bit value for plane 2.
 
COLBIT3 = bit value for plane 3.
 
WMODE = writing mode.
 
PATPTR = ptr to the fill pattern.
 
PATMSK = pattern index.
 
MFILL = multi-plane pattern flag.
 
 
 
output: none.
 
 
 
(5) Filled rectangle
 
 
... ...
 
dc.w $A005 ; Draw a filled rectangle with upper left corner at
 
; (x1,y1) and lower right corner at (x2,y2).
 
... ...
 
 
input: X1 = x1 coordinate.
 
Y1 = y1 coordinate.
 
X2 = x2 coordinate.
 
Y2 = y2 coordinate.
 
COLBIT0 = bit value for plane 0.
 
COLBIT1 = bit value for plane 1.
 
COLBIT2 = bit value for plane 2.
 
COLBIT3 = bit value for plane 3.
 
WMODE = writing mode.
 
PATPTR = ptr to the fill pattern.
 
PATMSK = fill pattern index.
 
MFILL = multi-plane fill pattern flag.
 
CLIP = clipping flag.
 
XMINCL = x minimum for clipping.
 
XMAXCL = x maximum for clipping.
 
YMINCL = y minimum for clipping.
 
YMAXCL = y maximum for clipping.
 
 
 
output: none.
 
 
 
(6) Line-by-line filled polygon.
 
 
... ...
 
dc.w $A006 ; Draw 1 scan-line of a filled polygon.
 
... ...
 
 
input: PTSIN[] = array of polygon vertices.
 
((x1,y1),(x2,y2)...,(xn,yn),(x1,y1))
 
CONTRL[1] = n = number of vertices.
 
Y1 = y coordinate of scan-line to fill.
 
COLBIT0 = bit value for plane 0.
 
COLBIT1 = bit value for plane 1.
 
COLBIT2 = bit value for plane 2.
 
COLBIT3 = bit value for plane 3.
 
WMODE = writing mode.
 
PATPTR = ptr to the fill pattern.
 
PATMSK = fill pattern mask.
 
MFILL = multi-plane fill pattern flag.
 
CLIP = clipping flag.
 
XMINCL = x minimum for clipping.
 
XMAXCL = x maximum for clipping.
 
YMINCL = y minimum for clipping.
 
YMAXCL = y maximum for clipping.
 
 
 
output: X1 and X2 are clobbered.
 
 
note: The 1st endpoint must be repeated at the end of the list of
 
n endpoints.
 
 
 
(7) BitBlt
 
 
... ...
 
dc.w $A007 ; Perform a BIT BLock Transfer.
 
... ...
 
 
input: a6 = ptr to a structure of input parameters.
 
 
output: none.
 
 
 
BIT BLT PARAMETER BLOCK OFFSETS
 
 
 
B_WD equ +00 ; width of block in pixels
 
B_HT equ +02 ; height of block in pixels
 
 
PLANE_CT equ +04 ; number of consecutive planes to blt {D}
 
 
FG_COL equ +06 ; foreground color (logic op index:hi bit) {D}
 
BG_COL equ +08 ; background color (logic op index:lo bit) {D}
 
OP_TAB equ +10 ; logic ops for all fore and background combos
 
 
S_XMIN equ +14 ; minimum X: source
 
S_XMIN equ +14 ; minimum X: source
 
S_YMIN equ +16 ; minimum Y: source
 
S_YMIN equ +16 ; minimum Y: source
Line 266: Line 280:
 
D_NXPL equ +40 ; offset to next plane from start of current plane
 
D_NXPL equ +40 ; offset to next plane from start of current plane
   
P_ADDR equ +42 ; address of pattern buffer (0:no pattern) {D}
+
P_ADDR equ +42 ; address of pattern buffer (0:no pattern) {*}
 
P_NXLN equ +46 ; offset to next line in pattern (in bytes)
 
P_NXLN equ +46 ; offset to next line in pattern (in bytes)
 
P_NXPL equ +48 ; offset to next plane in pattern (in bytes)
 
P_NXPL equ +48 ; offset to next plane in pattern (in bytes)
Line 273: Line 287:
 
P_BLOCK_LEN equ 76 ; the parameter block must be 76 bytes long
 
P_BLOCK_LEN equ 76 ; the parameter block must be 76 bytes long
   
  +
***Note*** Parameters marked with {*} may be altered during the course of the BIT BLT execution
  +
</nowiki></pre>
  +
|}
  +
{|style="text-align:left;font-size:95%;background:#F0F8FF;border:1px solid #666;width:100%;cellpadding:4;cellspacing:5"
  +
! colspan="2" style="background:#B0C4DE;font-size:12pt;height:30px" |'''Description'''
  +
|-
  +
| <br>
  +
|-
  +
|'''0. Preface'''
   
  +
:Before one floggles one's tormented mind with this tangled nest of arcane knowledge, one ought to be intimately familiar with chapter 6 of the GEM VDI manual. the author assumes that one's knowledge of Raster matters is quite wide and that the rudiments of BIT BLTting are below discussion. If the author is mistaken then he's sorry (and you're about to become lost in the sea of woe, oh ho!).
*** notes ***
 
   
parameters marked with {D} may be altered during the course
 
of the BIT BLT execution
 
   
  +
'''I. Parameter block'''
   
  +
:The BIT BLT is accessed via a 76 byte parameter block. Register <tt>A6</tt> points to the head of this block upon Line A entry. Only the first 52 bytes of the block need be attended to by the abuser. The remaining space is maintained internally by the BLT. Note that in the following explanations, parameters will be refered to by their symbolic offsets into the parameter block.
   
contents of OP_TAB
 
   
  +
'''II. Memory forms'''
   
  +
:Memory forms are something like a cabbage patch. (A cabbage patch is a place for mentally retarded programmers). Let's face it, forms are nothing like a cabbage patch. If you think they are, go back and read chapter 6 in the GEM VDI manual. If you know anything at all about memory forms, you know they are almost entirely but not totally unlike a garbage can. One difference is that memory forms are of two sexes, source and destination. each sex is defined by the same four parameters: Form block address, form block width, offset to next contiguous word, and offset to next plane.
+00 byte logic operation employed when foreground and background color
 
bits for current plane are both clear (0)
 
   
  +
:<tt>S_FORM</tt> and <tt>D_FORM</tt> point to the first words of the source memory form and destination memory forms, respectively. these addresses must fall on word boundaries or severe hardships will fall (as will address exceptions) like plagues upon the ancient Egyptians.
+01 byte logic operation employed when current plane's foreground color
 
bit is clear (0) and background color bit is set (1)
 
   
  +
:<tt>S_NXWD</tt> and <tt>D_NXWD</tt> are offsets to the next word in a plane of the memory form. For example, in the monochrome mode the value is 2 while a value of 4 is used in medium resolution and 8 is applicable to low resolution.
+02 byte logic operation employed when current plane's foreground color
 
bit is set (1) and background color bit is clear (0)
 
   
  +
:<tt>S_NXLN</tt> and <tt>D_NXLN</tt> are form widths for source and destination. (I can't remember which one belongs to the source form and which one belongs to the destination form). These widths must be even byte values, as you know, for they represent the offset from one row of the form to the next and forms must be word aligned and an integral number of words wide. (Hint: the hi rez screen value is 90 while lo and medium rez values are 160)
+03 byte logic operation employed when foreground and background color
 
bits for current plane are both set (1)
 
   
  +
:<tt>S_NXPL</tt> and <tt>D_NXPL</tt> are offsets from the start of one plane to the start of the next plane. because of the ST screen's interleaved plane structure, this value is always two (2). Alternative universes allow for a series of contiguous planes where NXPL values are the number of bytes in each plane. Yhus , it is possible to BLT from the contiguous universe into the interleaved ST universe and vice versa.
   
  +
:The actual bit alligned blocks of memory are defined within the form by an upper left anchor point, a pixel width, and a pixel height: (<tt>S_XMIN, S_YMIN, B_WD,</tt> and <tt>B_HT</tt>). the location in the destination form is defined by an anchor point(<tt>D_XMIN, D_YMIN</tt>). no harm will come if these two areas overlap. Note that no clipping is performed andthere is no checking to determine whether the bit blocks fall within the confines of the encompasing memory forms. finally, the number of planes to be transfered (the number of itterations of the BLT algorithm) is contained in the <tt>PLANE_CT</tt> word.
   
   
  +
'''III. Raster operations'''
   
  +
:<tt>OP_TAB</tt> is a table of four RASTER OP codes. Each of the byte wide entries in <tt>OP_TAB</tt> contain a code for one of the sixteen logical operations between consenting source and destination blocks. For each plane, the logical operation is chosen by indexing into the <tt>OP_TAB</tt> with a value derived from <tt>FG_COL<tt> and <tt>BG_COL<tt> words. For a given plane "n", bit "n" of <tt>FG_COL</tt> is the hi bit of the two bit index value and bit "n" of <tt>BG_COL</tt> is the lo bit of the index value.
   
  +
:For those with a furniture fetish, here is a table:
0. PREFACE
 
 
Before one floggles one's tormented mind with this tangled nest of
 
arcane knowledge, one ought to be intimately familiar with chapter 6
 
of the GEM VDI manual. the author assumes that one's knowledge of Raster
 
matters is quite wide and that the rudiments of BIT BLTting are below
 
discussion. If the author is mistaken then he's sorry (and you're
 
about to become lost in the sea of woe, oh ho!).
 
 
 
I. PARAMETER BLOCK
 
 
the BIT BLT is accessed via a 76 byte parameter block. Register A6 points
 
to the head of this block upon LINE A entry. Only the first 52 bytes of
 
the block need be attended to by the abuser. The remaining space is
 
maintained internally by the BLT. Note that in the following explanations,
 
parameters will be refered to by their symbolic offsets into the parameter
 
block.
 
 
 
II. MEMORY FORMS
 
 
memory forms are something like a cabbage patch. (a cabbage patch is a
 
place for mentally retarded programmers). let's face it, forms are nothing
 
like a cabbage patch. if you think they are, go back and read chapter 6
 
in the GEM VDI manual. if you know anything at all about memory forms,
 
you know they are almost entirely but not totally unlike a garbage can.
 
one difference is that memory forms are of two sexes, source and destination.
 
each sex is defined by the same four parameters: form block address,
 
form block width, offset to next contiguous word, and offset to next plane.
 
 
S_FORM and D_FORM point to the first words of the source memory form
 
and destination memory forms, respectively. these addresses must fall on
 
word boundries or severe hardships will fall (as will address exceptions)
 
like plagues upon the ancient egyptians.
 
 
S_NXWD and D_NXWD are offsets to the next word in a plane of the memory
 
form. for example, in the monochrome mode the value is 2 while a value
 
of 4 is used in medium resolution and 8 is applicable to low resolution.
 
 
S_NXLN and D_NXLN are form widths for source and destination. ( i can't
 
remember which one belongs to the source form and which one belongs to the
 
destination form). These widths must be even byte values, as you know, for
 
they represent the offset from one row of the form to the next and forms
 
must be word aligned and an integral number of words wide. (hint: the
 
hi rez screen value is 90 while lo and medium rez values are 160)
 
 
S_NXPL and D_NXPL are offsets from the start of one plane to the start of
 
the next plane. because of the ST screen's interleaved plane structure,
 
this value is always two (2). alternative universes allow for a series
 
of contiguous planes where NXPL values are the number of bytes in each plane.
 
thus , it is possible to BLT from the contiguous universe into the
 
interleaved ST universe and vice versa.
 
 
 
the actual bit alligned blocks of memory are defined within the form
 
by an upper left anchor point, a pixel width, and a pixel height:
 
(S_XMIN, S_YMIN, B_WD, and B_HT). the location in the destination form
 
is defined by an anchor point (D_XMIN, D_YMIN). no harm will come if
 
these two areas overlap. Note that no clipping is performed andthere is no
 
checking to determine whether the bit blocks fall within the confines of
 
the encompasing memory forms. finally, the number of planes to
 
be transfered (the number of itterations of the BLT algorithm) is
 
contained in the PLANE_CT word.
 
 
 
 
 
III. RASTER OPERATIONS
 
 
OP_TAB is a table of four RASTER OP codes. Each of the byte wide entries
 
in OP_TAB contain a code for one of the sixteen logical operations between
 
consenting source and destination blocks. For each plane, the logical
 
operation is chosen by indexing into the OP_TAB with a value derived from
 
FG_COL and BG_COL words. For a given plane "n", bit "n" of FG_COL is the hi
 
bit of the two bit index value and bit "n" of BG_COL is the lo bit of
 
the index value.
 
 
for those with a furniture fetish, here is a table:
 
   
  +
<pre><nowiki>
 
FG(n) BG(n) OP_TAB entry
 
FG(n) BG(n) OP_TAB entry
 
----- ----- ------------
 
----- ----- ------------
Line 388: Line 334:
 
1 0 third entry
 
1 0 third entry
 
1 1 fourth entry
 
1 1 fourth entry
  +
</nowiki></pre>
   
   
  +
'''IV. Patterns'''
   
  +
:Patterns are word wide, word aligned images that are logically anded with the source prior to the logical combination of source with destination.
   
  +
:Patterns are packed in an imaginary grid anchored at the upper left corner (0,0) of the destination memory form.
 
IV. PATTERNS
 
   
Patterns are word wide, word aligned images that are logically anded
+
:Patterns are 16 bits wide and repeated every 16 pixels horizontally.
with the source prior to the logical combination of source with destination.
 
   
  +
:Patterns are an integral power of 2 in height and repeat vertically at that frequency.
Patterns are packed in an imaginary grid anchored at the upper left corner
 
(0,0) of the destination memory form.
 
   
  +
:The source is shifted into alignment with the destination rectangle prior to the combination of source with pattern. Thus, the relationship between source and pattern is dependent upon the X,Y positioning of the destination rectangle.
Patterns are 16 bits wide and repeated every 16 pixels horizontally.
 
   
  +
:<tt>P_ADDR</tt> points to the first word of the pattern. If this pointer is 0, a pattern is not combined with the source rectangle.
patterns are an integral power of 2 in height and repeat vertically
 
at that frequency.
 
   
  +
:<tt>P_NXLN</tt> is the offset (in bytes) between consecutive words in the pattern. For reasons too inane to go into here, this number should be an integral power of 2 (such as 2,4, or 8)
The source is shifted into alignment with the destination rectangle prior
 
to the combination of source with pattern.
 
Thus, the relationship between source and pattern is dependent upon the
 
X,Y positioning of the destination rectangle.
 
   
  +
:<tt>P_NXPL</tt> is the offset (in bytes) from the beginning of a plane to the beginning of the next plane. In the case of a single plane pattern used in a multi plane environment, this value would be zero. thus, the same pattern is repeated through all planes.
   
P_ADDR points to the first word of the pattern. If this pointer is 0, a
+
:<tt>P_MASK</tt> works with <tt>P_NXLN</tt> to specify the length of the pattern. The length (in words) of the pattern must be an integral power of 2.
pattern is not combined with the source rectangle.
 
   
  +
:If <tt>P_NXLN</tt> = 2 ** n then <tt>P_MASK</tt> = (length in words -1) << n ... I don't know why. go ask your father.
P_NXLN is the offset (in bytes) between consecutive words in the pattern.
 
For reasons too inane to go into here, this number should be an integral
 
power of 2 (such as 2,4, or 8)
 
   
P_NXPL is the offset (in bytes) from the beginning of a plane to the
 
beginning of the next plane. In the case of a single plane pattern used
 
in a multi plane environment, this value would be zero. thus, the same
 
pattern is repeated through all planes.
 
   
  +
'''V. Bag o' tricks'''
P_MASK works with P_NXLN to specify the length of the pattern.
 
The length (in words) of the pattern must be an integral power of 2.
 
   
  +
:'''Q.''' I want to BLT from a single plane source to multi plane destination.
if P_NXLN = 2 ** n
 
 
then P_MASK = (length in words -1) << n
 
 
... i don't know why. go ask your father.
 
 
 
 
V. BAG 'O TRICKS
 
 
 
Q. I want to BLT from a single plane source to multi plane destination.
 
 
 
  +
:'''A.''' That's not in the form of a question. And besides, i can't think with that water pick spurtin in my ear. Hey, that's my cat your puttin in the Cuisinart. Wha the fuh you think your doin bustin into my word processor like this. Hey bud, stay away from that delete key. Hey moe foe, I'm serious. How'd you like an unexpected interrupt ?
A. That's not in the form of a question. And besides, i can't think
 
with that water pick spurtin in my ear. Hey, that's my cat your puttin in
 
the Cuisinart. Wha the fuh you think your doin bustin into my word processor
 
like this. Hey bud, stay away from that delete key. Hey moe foe, i'm
 
serious. How'd you like an unexpected interrupt ?
 
   
Q. This key is loaded and it's pointed at your bonus check.
+
:'''Q.''' This key is loaded and it's pointed at your bonus check.
   
A. ok,ok... i'll talk.
+
:'''A.''' ok,ok... i'll talk.
 
 
S_NXPL =0 => the same source plane is BLTted to all destination planes
+
::<tt>S_NXPL = 0</tt> => the same source plane is BLTted to all destination planes
   
Q. yea, i know that but what logic ops do i use ?
+
:'''Q.''' Yea, I know that but what logic ops do I use ?
   
A. to map 1's to foreground color and 0's to background color
+
:'''A.''' To map 1's to foreground color and 0's to background color set OP_TAB to:
set OP_TAB to:
 
   
 
offset logic op
 
offset logic op
  +
-------- ----------
 
 
+00 00 all zeros
 
+00 00 all zeros
 
+01 04 D' <- [not S] and D
 
+01 04 D' <- [not S] and D
Line 464: Line 383:
 
+03 15 all ones
 
+03 15 all ones
 
 
load foreground color into FG_COL and background color into BG_COL
+
::load foreground color into <tt>FG_COL</tt> and background color into <tt>BG_COL</tt>
   
  +
:'''Q.''' You wanna buy some lake bottom property?
   
  +
:'''A.''' To map 1's to foreground color and make 0's transparent set <tt>OP_TAB</tt> to:
Q. you wanna buy some lake bottom property?
 
 
A. to map 1's to foreground color and make 0's transparent
 
set OP_TAB to:
 
   
 
offset logic op
 
offset logic op
  +
-------- ----------
 
 
+00 04 D' <- [not S] and D
 
+00 04 D' <- [not S] and D
 
+01 04 D' <- [not S] and D
 
+01 04 D' <- [not S] and D
 
+02 07 D' <- S or D
 
+02 07 D' <- S or D
 
+03 07 D' <- S or D
 
+03 07 D' <- S or D
 
 
 
  +
::load foreground color into <tt>FG_COL</tt>, it doesn't matter what you put into <tt>BG_COL</tt>. Don't forget to set <tt>S_NXPL</tt> to 0.
load foreground color into FG_COL
 
  +
it doesn't matter what you put into BG_COL
 
  +
:Enough smalltalk, let's get down to the core of the issue. Here are some of my Aunt Marge's flavorful BIT BLT recipes:
   
don't forget to set S_NXPL to 0
 
   
  +
:1. BLT a pattern without Source to the Destination.
   
  +
::For this number, we'll need a word of ones. Label it "ones:" next, point <tt>S_FORM</tt> at "ones". Set <tt>S_NXLN</tt>, <tt>S_NXPL, S_NXWD, S_XMIN</tt>, and <tt>S_YMIN</tt> to 0. Set up the pattern as you usually would and before you know it, you'll have a wonderful steaming pattern filled rectangle.
   
 
 
  +
:2. this is a nice way to make a sprite like device.
enough smalltalk, let's get down to the core of the issue.
 
Here are some of my Aunt Marge's flavorful BIT BLT recipes:
 
   
  +
::You will need to bake a monoplane mask. everywhere there is a 1 in the mask, the background will be removed. wherever a 0 falls, the background is left intact.
   
  +
::Set <tt>OP_TAB</tt> to:
1. BLT a pattern without Source to the Destination.
 
 
For this number, we'll need a word of ones. Label it "ones:"
 
next, point S_FORM at "ones". Set S_NXLN, S_NXPL, S_NXWD,
 
S_XMIN, and S_YMIN to 0. Set up the pattern as you usually would
 
and before you know it, you'll have a wonderful steaming pattern
 
filled rectangle.
 
 
 
2. this is a nice way to make a sprite like device.
 
 
o you will need to bake a monoplane mask. everywhere there is a
 
1 in the mask, the background will be removed. wherever a 0 falls,
 
the background is left intact.
 
 
set OP_TAB to:
 
   
 
offset logic op
 
offset logic op
  +
-------- ----------
 
 
+00 04 D' <- [not S] and D
 
+00 04 D' <- [not S] and D
 
+01 04 D' <- [not S] and D
 
+01 04 D' <- [not S] and D
Line 517: Line 420:
   
 
 
  +
::Load foreground color into <tt>FG_COL</tt>. It doesn't matter what you put into <tt>BG_COL</tt>
load foreground color into FG_COL
 
it doesn't matter what you put into BG_COL
 
 
 
o next, take a monoplane form (or multiplane form) and "or" it (OP 07)
 
into the area that you just scooped out with the mask
 
 
feeds a family of four.
 
 
 
(8) TextBlt
 
 
... ...
 
dc.w $A008 ; Perform a TEXT BLock Transfer of 1 character.
 
... ...
 
 
input:
 
WMODE = writing mode.(0-3 => VDI modes
 
4-19 => BitBlt modes)
 
TEXTFG = text foreground color.
 
TEXTBG = text background color. (used for modes 4-19)
 
FBASE = ptr to start of font data. (font form)
 
FWIDTH = width of font form.
 
SOURCEX = x coord of character in font form.
 
SOURCEY = y coord of character in font form.
 
DESTX = x coord of character on screen.
 
DESTY = y coord of character on screen.
 
DELX = width of character.
 
DELY = height of character.
 
STYLE = vector of TextBlt special effects flags.
 
LITEMASK = the mask to use in lightening text.
 
SKEWMASK = the mask to use in skewing text.
 
WEIGHT = the width by which to thicken text.
 
ROFF = offset above character baseline when skewing.
 
LOFF = offset below character baseline when skewing.
 
SCALE = scaling flag. (0 => no scaling.)
 
XDDA = accumulator for x dda.
 
DDAINC = fractional amount to scale up or down.
 
SCALDIR = scale direction flag. (0 => down)
 
CHUP = character rotation vector.
 
MONO = monospaced font flag.
 
SCRTCHP = ptr to start of text special effects buffer.
 
SCRPT2 = offset of scaling buffer in above buffer.
 
 
output: none.
 
 
 
(9) Show mouse
 
 
... ...
 
dc.w $A009 ; Show the mouse.
 
... ...
 
 
input: see GEM VDI manual.
 
 
 
output: none.
 
 
 
(10) Hide mouse
 
 
... ...
 
dc.w $A00A ; Hide the mouse.
 
... ...
 
 
input: see GEM VDI manual.
 
 
 
output: none.
 
 
 
(11) Transform mouse
 
 
... ...
 
dc.w $A00B ; Transform the mouse's form.
 
... ...
 
 
input: see GEM VDI manual.
 
 
 
output: none.
 
 
 
(12) Undraw sprite
 
   
  +
::Next, take a monoplane form (or multiplane form) and "or" it (OP 07) into the area that you just scooped out with the mask
... ...
 
dc.w $A00C ; Undraw the previously drawn sprite.
 
... ...
 
   
  +
::Feeds a family of four.
input: a2 = ptr to sprite save block.
 
   
  +
|}
note: The sprite save block is used to save the screen
 
  +
|}
underneath the sprite. Its size is 10 bytes + 64 bytes
 
  +
</div>
per plane, i.e. (10 + VPLANES * 64) bytes.
 
   
  +
<span id="textblt"></span>
output: clobbers a6. ("C" programmers beware.)
 
  +
<div style="border:1px solid #fff; padding:5px !important;overflow;hidden;width:90%;float:center;text-align:left;margin-left:1.5em;border-width:.5em 0 .8em 1.4em;">
  +
{| class="wikitable" style="text-align:left;font-size:95%;background:#F0F8FF;border:1px solid #666;width:100%;cellpadding:4;cellspacing:5"
  +
! colspan="2" style="background:#00BFFF;font-size:12pt;height:40px" |'''TextBlt (8)'''
  +
|-valign="top"
  +
| '''Code:''' || <tt>dc.w $A008 ; Perform a TEXT BLock Transfer of 1 character.</tt>
  +
|-valign="top"
  +
|width="10%"|'''Input:'''
  +
|width="90%"|<tt>WMODE</tt> = writing mode.(0-3 => VDI modes, 4-19 => BitBlt modes) <br>
  +
<tt>TEXTFG</tt> = text foreground color <br>
  +
<tt>TEXTBG</tt> = text background color. (used for modes 4-19) <br>
  +
<tt>FBASE</tt> = ptr to start of font data. (font form) <br>
  +
<tt>FWIDTH</tt> = width of font form <br>
  +
<tt>SOURCEX</tt> = x coord of character in font form <br>
  +
<tt>SOURCEY</tt> = y coord of character in font form <br>
  +
<tt>DESTX</tt> = x coord of character on screen <br>
  +
<tt>DESTY</tt> = y coord of character on screen <br>
  +
<tt>DELX</tt> = width of character <br>
  +
<tt>DELY</tt> = height of character <br>
  +
<tt>STYLE</tt> = vector of TextBlt special effects flags <br>
  +
<tt>LITEMASK</tt> = the mask to use in lightening text <br>
  +
<tt>SKEWMASK</tt> = the mask to use in skewing text <br>
  +
<tt>WEIGHT</tt> = the width by which to thicken text <br>
  +
<tt>ROFF</tt> = offset above character baseline when skewing <br>
  +
<tt>LOFF</tt> = offset below character baseline when skewing <br>
  +
<tt>SCALE</tt> = scaling flag (0 => no scaling) <br>
  +
<tt>XDDA</tt> = accumulator for x dda <br>
  +
<tt>DDAINC</tt> = fractional amount to scale up or down <br>
  +
<tt>SCALDIR</tt> = scale direction flag (0 => down) <br>
  +
<tt>CHUP</tt> = character rotation vector <br>
  +
<tt>MONO</tt> = monospaced font flag <br>
  +
<tt>SCRTCHP</tt> = ptr to start of text special effects buffer <br>
  +
<tt>SCRPT2</tt> = offset of scaling buffer in above buffer
  +
|-
  +
| '''Output:''' || None
  +
|}
  +
</div>
   
  +
<span id="show_mouse"></span>
  +
<div style="border:1px solid #fff; padding:5px !important;overflow;hidden;width:90%;float:center;text-align:left;margin-left:1.5em;border-width:.5em 0 .8em 1.4em;">
  +
{| class="wikitable" style="text-align:left;font-size:95%;background:#F0F8FF;border:1px solid #666;width:100%;cellpadding:4;cellspacing:5"
  +
! colspan="2" style="background:#00BFFF;font-size:12pt;height:40px" |'''Show mouse (9)'''
  +
|-valign="top"
  +
| '''Code:''' || <tt>dc.w $A009 ; Show the mouse.</tt>
  +
|-valign="top"
  +
|width="10%"|'''Input:'''
  +
|width="90%"| See GEM VDI manual
  +
|-
  +
| '''Output:''' || None
  +
|}
  +
</div>
   
  +
<span id="hide_mouse"></span>
(13) Draw sprite
 
  +
<div style="border:1px solid #fff; padding:5px !important;overflow;hidden;width:90%;float:center;text-align:left;margin-left:1.5em;border-width:.5em 0 .8em 1.4em;">
  +
{| class="wikitable" style="text-align:left;font-size:95%;background:#F0F8FF;border:1px solid #666;width:100%;cellpadding:4;cellspacing:5"
  +
! colspan="2" style="background:#00BFFF;font-size:12pt;height:40px" |'''Hide mouse (10)'''
  +
|-valign="top"
  +
| '''Code:''' || <tt>dc.w $A00A ; Hide the mouse.</tt>
  +
|-valign="top"
  +
|width="10%"|'''Input:'''
  +
|width="90%"| See GEM VDI manual
  +
|-
  +
| '''Output:''' || None
  +
|}
  +
</div>
   
  +
<span id="transform_mouse"></span>
... ...
 
  +
<div style="border:1px solid #fff; padding:5px !important;overflow;hidden;width:90%;float:center;text-align:left;margin-left:1.5em;border-width:.5em 0 .8em 1.4em;">
dc.w $A00D ; Draw a sprite.
 
  +
{| class="wikitable" style="text-align:left;font-size:95%;background:#F0F8FF;border:1px solid #666;width:100%;cellpadding:4;cellspacing:5"
... ...
 
  +
! colspan="2" style="background:#00BFFF;font-size:12pt;height:40px" |'''Transform mouse (11)'''
  +
|-valign="top"
  +
| '''Code:''' || <tt>dc.w $A00B ; Transform the mouse's form.</tt>
  +
|-valign="top"
  +
|width="10%"|'''Input:'''
  +
|width="90%"| See GEM VDI manual
  +
|-
  +
| '''Output:''' || None
  +
|}
  +
</div>
   
  +
<span id="undraw_sprite"></span>
input: d0 = x hot-spot.
 
  +
<div style="border:1px solid #fff; padding:5px !important;overflow;hidden;width:90%;float:center;text-align:left;margin-left:1.5em;border-width:.5em 0 .8em 1.4em;">
d1 = y hot_spot.
 
  +
{| class="wikitable" style="text-align:left;font-size:95%;background:#F0F8FF;border:1px solid #666;width:100%;cellpadding:4;cellspacing:5"
a0 = ptr to sprite definition block.
 
  +
! colspan="2" style="background:#00BFFF;font-size:12pt;height:40px" |'''Undraw sprite (12)'''
a2 = ptr to sprite save block.
 
  +
|-valign="top"
  +
| '''Code:''' || <tt>dc.w $A00C ; Undraw the previously drawn sprite.</tt>
  +
|-valign="top"
  +
|width="10%"|'''Input:'''
  +
|width="90%"| <tt>a2</tt> = ptr to sprite save block <br> <br>
  +
Note: The sprite save block is used to save the screen underneath the sprite. Its size is 10 bytes + 64 bytes per plane, i.e. (10 + VPLANES * 64) bytes.
  +
|-
  +
| '''Output:''' || Clobbers <tt>a6</tt>. ([[C]] programmers beware)
  +
|}
  +
</div>
   
  +
<span id="draw_sprite"></span>
SPRITE DEFINTION BLOCK LAYOUT
 
  +
<div style="border:1px solid #fff; padding:5px !important;overflow;hidden;width:90%;float:center;text-align:left;margin-left:1.5em;border-width:.5em 0 .8em 1.4em;">
  +
{| class="wikitable" style="text-align:left;font-size:95%;background:#F0F8FF;border:1px solid #666;width:100%;cellpadding:4;cellspacing:5"
  +
! colspan="2" style="background:#00BFFF;font-size:12pt;height:40px" |'''Draw sprite (13)'''
  +
|-valign="top"
  +
| '''Code:''' || <tt>dc.w $A00D ; Draw a sprite.</tt>
  +
|-valign="top"
  +
|width="10%"|'''Input:'''
  +
|width="90%"| <tt>d0</tt> = x hot-spot <br>
  +
<tt>d1</tt> = y hot-spot <br>
  +
<tt>a0</tt> = ptr to sprite definition block <br>
  +
<tt>a2</tt> = ptr to sprite save block <br>
  +
<pre><nowiki>
  +
Sprite definiton block layout
   
 
ds.w 1 x offset of hot-spot.
 
ds.w 1 x offset of hot-spot.
Line 658: Line 570:
 
word 3 = foreground line 1.
 
word 3 = foreground line 1.
 
etc.)
 
etc.)
  +
</nowiki></pre>
  +
|-
  +
| '''Output:''' || Clobbers <tt>a6</tt>. ([[C]] programmers beware)
  +
|-
  +
| '''Bugs:''' || This function is not usable as a Line A call in the first release of TOS. See example program #2 below for the technique one must adopt to use this function.
  +
|}
  +
</div>
   
  +
<span id="copy_raster_form"></span>
output: clobbers a6. ("C" programmers beware.)
 
  +
<div style="border:1px solid #fff; padding:5px !important;overflow;hidden;width:90%;float:center;text-align:left;margin-left:1.5em;border-width:.5em 0 .8em 1.4em;">
  +
{| class="wikitable" style="text-align:left;font-size:95%;background:#F0F8FF;border:1px solid #666;width:100%;cellpadding:4;cellspacing:5"
  +
! colspan="2" style="background:#00BFFF;font-size:12pt;height:40px" |'''Copy raster form (14)'''
  +
|-valign="top"
  +
| '''Code:''' || <tt>dc.w $A00E ; Copy a raster form from source to destination.</tt>
  +
|-valign="top"
  +
|width="10%"|'''Input:'''
  +
|width="90%"|See the [[VDI]] discussion of copy raster. Opaque and Transparent, EXCEPT, CONTRL(0), CONTRL(1), CONTRL(3), and CONTRL(6) are ignored. COPYTRAN = Opaque/Transparent mode flag. (0 => Opaque)
  +
|-
  +
| '''Output:''' || None
  +
|-
  +
| '''Note:''' || See the [[#bitblt|BitBlt]] discussion above.
  +
|}
  +
</div>
  +
<br>
   
bugs: This function is not usable as a Line-A call in the 1st
 
release of TOS. See Example Program #2 below for the
 
technique one must adopt to use this function.
 
   
  +
==Using the Line A interface==
   
  +
The inputs to the Line-A routines are contained in a structure pointed to by the value returned in a0 after an initialization call ($A000) has been made. This initialization only needs to be done once and any returned values can be saved and used as needed.
(14) Copy raster form
 
   
  +
The Line A interface can be used in cooperation with the VDI and AES, however, one cannot expect the variables below to be unchanged after the VDI or AES has been used. Therefore, if an application wants to mix calls to Line-A and VDI/AES, it must reload any variables that it uses as input to the Line-A routines.
... ...
 
dc.w $A00E ; Copy a raster form from source to destination.
 
... ...
 
   
  +
The caller should assume that registers d0-d2 and a0-a2 are clobbered upon return. The rest are preserved.
input: See the VDI discussion of Copy Raster, Opaque & Transparent,
 
EXCEPT, CONTRL(0), CONTRL(1), CONTRL(3), and CONTRL(6) are
 
ignored.
 
COPYTRAN = Opaque/Transparent mode flag. (0 => Opaque)
 
   
output: none.
 
   
  +
==The Line A input variables structure==
note: See the BitBlt discussion above.
 
 
 
 
 
USING THE Line-A INTERFACE
 
 
 
The inputs to the Line-A routines are contained in a structure pointed
 
to by the value returned in a0 after an initialization call ($A000) has
 
been made. This initialization only needs to be done once and any returned
 
values can be saved and used as needed.
 
 
The Line-A interface can be used in cooperation with the VDI and AES,
 
however, one cannot expect the variables below to be unchanged after the
 
VDI or AES has been used. Therefore, if an application wants to mix calls
 
to Line-A and VDI/AES, it must reload any variables that it uses as input
 
to the Line-A routines.
 
 
The caller should assume that registers d0-d2 and a0-a2 are clobbered
 
upon return. The rest are preserved.
 
 
 
 
The LINE"A" input variables structure:
 
   
  +
<pre>
 
offset name type description
 
offset name type description
   
Line 873: Line 776:
 
Program #2 for the technique to use to identify the 1st TOS
 
Program #2 for the technique to use to identify the 1st TOS
 
release.
 
release.
  +
</pre>
   
   
  +
==Example Line A equates==
   
  +
<pre>
 
EXAMPLE Line-A EQUATES
 
 
 
*
 
*
 
*
 
*
Line 953: Line 856:
 
COPYRSTR equ INIT+14
 
COPYRSTR equ INIT+14
 
SEEDFILL equ INIT+15
 
SEEDFILL equ INIT+15
  +
</pre>
   
   
  +
==Example program #1==
   
  +
<pre>
EXAMPLE PROGRAM #1
 
 
 
text
 
text
   
Line 979: Line 883:
 
trap #1 ; exit.
 
trap #1 ; exit.
 
end
 
end
  +
</pre>
   
   
  +
==Example program #2==
   
  +
<pre>
EXAMPLE PROGRAM #2
 
 
 
text
 
text
 
*
 
*
Line 1,102: Line 1,007:
 
</pre>
 
</pre>
   
  +
Back to [[Programming]]
 
  +
[[Category:Programming]]

Revision as of 01:19, 15 October 2006

Introduction

In order to provide quick-and-dirty access to the assembler-level graphics routines, Atari engineers have set up the MC68000's Line A exception as an interface to several useful routines. The Line A interface is faster than going through GEM's VDI and has some extra features. Also, Line A calls require less application code than their VDI counterparts. Of course, Line A does not replace the VDI completely, but if an application only needs a few primitive graphics functions (and wants maximum performance), then Line A is sufficient and optimal.

The Line-A interface is provided for the hacker-at-heart and no claims are made about its ease of use. The interface may seem unusually inconsistent, but it was not designed; it simply fell out as a freebie from the low-level VDI primitives interface. That is, these routines are the heart of the VDI.

The Line-A interface consists of 15 opcodes. The calls to Line-A are assembled as 1-word instructions, the highest 4 bits of which are 1010 ($A, hence Line A) and the lower 12 bits of which are used as the opcode field. Following is a description of the 15 opcodes:

Line A opcodes
Opcode Description
0 Initialization
1 Put pixel
2 Get pixel
3 Line
4 Horizontal line
5 Filled rectangle
6 Line-by-line filled polygon
7 BitBlt
8 TextBlt
9 Show mouse
10 Hide mouse
11 Transform mouse
12 Undraw sprite
13 Draw sprite
14 Copy raster form
15 Seedfill (exists only in versions of TOS after the first release)


The Line A routines have some features that the VDI does not support. BitBlt supports half-tone patterns on the source and TextBlt supports all 16 BitBlt logic operations, not just the four GEM VDI writing modes. In addition to these straight-forward extensions, Line A also allows the adventurous programmer to experiment with special effects. The BitBlt is especially generous in this area.

Description of graphics routines

Initialization (0)
Code: dc.w $A000  ; Init Line A.
Input: None
Output: d0 = pointer to the base address of Line A interface variables

a0 = pointer to the base address of Line A interface variables
a1 = pointer to the array of pointers to the three system font headers
a2 = pointer to array of pointers to the fifteen Line A routines

Note: The value returned in a0 is the sine qua non of the Line A interface. Inputs to all the other Line-A operations are made relative to this value, i.e., the Line A interface variables are contained in a structure pointed to by a0. The offsets of these variables in the structure are given below.
Bugs: In the first TOS release, a2 is not returned as described above. Instead, it is preserved across the Line A call. See example program #2 at the end of this document for the technique that makes a2 point to the proper place.

Put pixel (1)
Code: dc.w $A001  ; Plot a pixel at x,y.
Input: INTIN[0] = pixel value

PTSIN[0] = x coordinate
PTSIN[1] = y coordinate

Output: None
Note: For a discussion of the CONTRL, INTIN, PTSIN, INTOUT, and PTSOUT arrays, see the GEM VDI manual.

Get pixel (2)
Code: dc.w $A002  ; Get the pixel at x,y.
Input: PTSIN[0] = x coordinate

PTSIN[1] = y coordinate

Output: d0 = pixel value.

Line (3)
Code: dc.w $A003  ; Draw a line between (x1,y1) and (x2,y2).
Input: X1 = x1 coordinate

Y1 = y1 coordinate
X2 = x2 coordinate
Y2 = y2 coordinate
COLBIT0 = bit value for plane 0
COLBIT1 = bit value for plane 1
COLBIT2 = bit value for plane 2
COLBIT3 = bit value for plane 3
LNMASK = line style mask
WMODE = writing mode
LSTLIN = always set this to -1, if using xor mode else ignore it

Output: LNMASK is rotated to align with right-most endpoint.
Quirks:
  • If the line is horizontal, LNMASK is a word-aligned pattern, not a line style. That is, a bit other thanbit 15 of LNMASK may be used at the left-most endpoint.
  • As the foregoing references imply, the line is always drawn from left to right, not from (X1,Y1) to (X2,Y2). Thus, LNMASK is always applied from left to right.
Note: Because of the quirks, an application cannot depend upon the phase of the LNMASK being properly updated between calls to line-drawing primitives. If the phase is critical, the application must compute and init LNMASK before each line is drawn.

LNMASK is applied to the line-drawing DDA algorithm along the direction of greater delta. If delta Y is greater than delta X, then LNMASK is applied in the Y direction.

These line-drawing quirks and notes apply to the GEM VDI, too.

Horizontal line (4)
Code: dc.w $A004  ; Draw a line from (x1,y1) to (x2,y1).
Input: X1 = x1 coordinate

Y1 = y1 coordinate
X2 = x2 coordinate
COLBIT0 = bit value for plane 0
COLBIT1 = bit value for plane 1
COLBIT2 = bit value for plane 2
COLBIT3 = bit value for plane 3
WMODE = writing mode
PATPTR = ptr to the fill pattern
PATMSK = pattern index
MFILL = multi-plane pattern flag

Output: None

Filled rectangle (5)
Code: dc.w $A005  ; Draw a filled rectangle with upper left corner at (x1,y1) and lower right corner at (x2,y2).
Input: X1 = x1 coordinate

Y1 = y1 coordinate
X2 = x2 coordinate
Y2 = y2 coordinate
COLBIT0 = bit value for plane 0
COLBIT1 = bit value for plane 1
COLBIT2 = bit value for plane 2
COLBIT3 = bit value for plane 3
WMODE = writing mode
PATPTR = ptr to the fill pattern
PATMSK = fill pattern index
MFILL = multi-plane fill pattern flag
CLIP = clipping flag
XMINCL = x minimum for clipping
XMAXCL = x maximum for clipping
YMINCL = y minimum for clipping
YMAXCL = y maximum for clipping

Output: None

Line-by-line filled polygon (6)
Code: dc.w $A006  ; Draw 1 scan-line of a filled polygon.
Input: PTSIN[] = array of polygon vertices

CONTRL[1] = n = number of vertices
Y1 = y coordinate of scan-line to fill
COLBIT0 = bit value for plane 0
COLBIT1 = bit value for plane 1
COLBIT2 = bit value for plane 2
COLBIT3 = bit value for plane 3
WMODE = writing mode
PATPTR = ptr to the fill pattern
PATMSK = fill pattern index
MFILL = multi-plane fill pattern flag
CLIP = clipping flag
XMINCL = x minimum for clipping
XMAXCL = x maximum for clipping
YMINCL = y minimum for clipping
YMAXCL = y maximum for clipping

Output: X1 and X2 are clobbered.
Note: The first end point must be repeated at the end of the list of n end points.

BitBlt (7)
Code: dc.w $A007  ; Perform a BIT BLock Transfer.
Input: a6 = ptr to a structure of input parameters
Output: None
.
BitBlt parameter block offsets
B_WD            equ     +00     ; width of block in pixels                          
B_HT            equ     +02     ; height of block in pixels                         

PLANE_CT        equ     +04     ; number of consecutive planes to blt       {*}     

FG_COL          equ     +06     ; foreground color (logic op index:hi bit)  {*}     
BG_COL          equ     +08     ; background color (logic op index:lo bit)  {*}     
OP_TAB          equ     +10     ; logic ops for all fore and background combos (see below) 
                                ; contents of OP_TAB
                                ; +00   byte    logic operation employed when foreground and background color
                                ; bits for current plane are both clear (0)

                                ; +01   byte    logic operation employed when current plane's foreground color
                                ; bit is clear (0) and background color bit is set (1)

                                ; +02   byte    logic operation employed when current plane's foreground color
                                ; bit is set (1) and background color bit is clear (0)
 
S_XMIN          equ     +14     ; minimum X: source                                 
S_YMIN          equ     +16     ; minimum Y: source                                 
S_FORM          equ     +18     ; source form base address                          
S_NXWD          equ     +22     ; offset to next word in line  (in bytes)           
S_NXLN          equ     +24     ; offset to next line in plane (in bytes)           
S_NXPL          equ     +26     ; offset to next plane from start of current plane  

D_XMIN          equ     +28     ; minimum X: destination                            
D_YMIN          equ     +30     ; minimum Y: destination                            
D_FORM          equ     +32     ; destination form base address                     
D_NXWD          equ     +36     ; offset to next word in line  (in bytes)           
D_NXLN          equ     +38     ; offset to next line in plane (in bytes)           
D_NXPL          equ     +40     ; offset to next plane from start of current plane  

P_ADDR          equ     +42     ; address of pattern buffer   (0:no pattern) {*}
P_NXLN          equ     +46     ; offset to next line in pattern  (in bytes)    
P_NXPL          equ     +48     ; offset to next plane in pattern (in bytes)    
P_MASK          equ     +50     ; pattern index mask                            

P_BLOCK_LEN     equ      76     ; the parameter block must be 76 bytes long

***Note*** Parameters marked with {*} may be altered during the course of the BIT BLT execution
Description

0. Preface
Before one floggles one's tormented mind with this tangled nest of arcane knowledge, one ought to be intimately familiar with chapter 6 of the GEM VDI manual. the author assumes that one's knowledge of Raster matters is quite wide and that the rudiments of BIT BLTting are below discussion. If the author is mistaken then he's sorry (and you're about to become lost in the sea of woe, oh ho!).


I. Parameter block

The BIT BLT is accessed via a 76 byte parameter block. Register A6 points to the head of this block upon Line A entry. Only the first 52 bytes of the block need be attended to by the abuser. The remaining space is maintained internally by the BLT. Note that in the following explanations, parameters will be refered to by their symbolic offsets into the parameter block.


II. Memory forms

Memory forms are something like a cabbage patch. (A cabbage patch is a place for mentally retarded programmers). Let's face it, forms are nothing like a cabbage patch. If you think they are, go back and read chapter 6 in the GEM VDI manual. If you know anything at all about memory forms, you know they are almost entirely but not totally unlike a garbage can. One difference is that memory forms are of two sexes, source and destination. each sex is defined by the same four parameters: Form block address, form block width, offset to next contiguous word, and offset to next plane.
S_FORM and D_FORM point to the first words of the source memory form and destination memory forms, respectively. these addresses must fall on word boundaries or severe hardships will fall (as will address exceptions) like plagues upon the ancient Egyptians.
S_NXWD and D_NXWD are offsets to the next word in a plane of the memory form. For example, in the monochrome mode the value is 2 while a value of 4 is used in medium resolution and 8 is applicable to low resolution.
S_NXLN and D_NXLN are form widths for source and destination. (I can't remember which one belongs to the source form and which one belongs to the destination form). These widths must be even byte values, as you know, for they represent the offset from one row of the form to the next and forms must be word aligned and an integral number of words wide. (Hint: the hi rez screen value is 90 while lo and medium rez values are 160)
S_NXPL and D_NXPL are offsets from the start of one plane to the start of the next plane. because of the ST screen's interleaved plane structure, this value is always two (2). Alternative universes allow for a series of contiguous planes where NXPL values are the number of bytes in each plane. Yhus , it is possible to BLT from the contiguous universe into the interleaved ST universe and vice versa.
The actual bit alligned blocks of memory are defined within the form by an upper left anchor point, a pixel width, and a pixel height: (S_XMIN, S_YMIN, B_WD, and B_HT). the location in the destination form is defined by an anchor point(D_XMIN, D_YMIN). no harm will come if these two areas overlap. Note that no clipping is performed andthere is no checking to determine whether the bit blocks fall within the confines of the encompasing memory forms. finally, the number of planes to be transfered (the number of itterations of the BLT algorithm) is contained in the PLANE_CT word.


III. Raster operations

OP_TAB is a table of four RASTER OP codes. Each of the byte wide entries in OP_TAB contain a code for one of the sixteen logical operations between consenting source and destination blocks. For each plane, the logical operation is chosen by indexing into the OP_TAB with a value derived from FG_COL and BG_COL words. For a given plane "n", bit "n" of FG_COL is the hi bit of the two bit index value and bit "n" of BG_COL is the lo bit of the index value.
For those with a furniture fetish, here is a table:
                FG(n)   BG(n)   OP_TAB entry
                -----   -----   ------------

                  0       0     first entry
                  0       1     second entry
                  1       0     third entry
                  1       1     fourth entry


IV. Patterns

Patterns are word wide, word aligned images that are logically anded with the source prior to the logical combination of source with destination.
Patterns are packed in an imaginary grid anchored at the upper left corner (0,0) of the destination memory form.
Patterns are 16 bits wide and repeated every 16 pixels horizontally.
Patterns are an integral power of 2 in height and repeat vertically at that frequency.
The source is shifted into alignment with the destination rectangle prior to the combination of source with pattern. Thus, the relationship between source and pattern is dependent upon the X,Y positioning of the destination rectangle.
P_ADDR points to the first word of the pattern. If this pointer is 0, a pattern is not combined with the source rectangle.
P_NXLN is the offset (in bytes) between consecutive words in the pattern. For reasons too inane to go into here, this number should be an integral power of 2 (such as 2,4, or 8)
P_NXPL is the offset (in bytes) from the beginning of a plane to the beginning of the next plane. In the case of a single plane pattern used in a multi plane environment, this value would be zero. thus, the same pattern is repeated through all planes.
P_MASK works with P_NXLN to specify the length of the pattern. The length (in words) of the pattern must be an integral power of 2.
If P_NXLN = 2 ** n then P_MASK = (length in words -1) << n ... I don't know why. go ask your father.


V. Bag o' tricks

Q. I want to BLT from a single plane source to multi plane destination.
A. That's not in the form of a question. And besides, i can't think with that water pick spurtin in my ear. Hey, that's my cat your puttin in the Cuisinart. Wha the fuh you think your doin bustin into my word processor like this. Hey bud, stay away from that delete key. Hey moe foe, I'm serious. How'd you like an unexpected interrupt ?
Q. This key is loaded and it's pointed at your bonus check.
A. ok,ok... i'll talk.
S_NXPL = 0 => the same source plane is BLTted to all destination planes
Q. Yea, I know that but what logic ops do I use ?
A. To map 1's to foreground color and 0's to background color set OP_TAB to:
                      offset   logic op
                     -------- ----------
                       +00       00       all zeros
                       +01       04       D' <- [not S] and D
                       +02       07       D' <- S or D
                       +03       15       all ones
          
load foreground color into FG_COL and background color into BG_COL
Q. You wanna buy some lake bottom property?
A. To map 1's to foreground color and make 0's transparent set OP_TAB to:
                      offset   logic op
                     -------- ----------
                       +00       04       D' <- [not S] and D
                       +01       04       D' <- [not S] and D
                       +02       07       D' <- S or D
                       +03       07       D' <- S or D
          
load foreground color into FG_COL, it doesn't matter what you put into BG_COL. Don't forget to set S_NXPL to 0.
Enough smalltalk, let's get down to the core of the issue. Here are some of my Aunt Marge's flavorful BIT BLT recipes:


1. BLT a pattern without Source to the Destination.
For this number, we'll need a word of ones. Label it "ones:" next, point S_FORM at "ones". Set S_NXLN, S_NXPL, S_NXWD, S_XMIN, and S_YMIN to 0. Set up the pattern as you usually would and before you know it, you'll have a wonderful steaming pattern filled rectangle.


2. this is a nice way to make a sprite like device.
You will need to bake a monoplane mask. everywhere there is a 1 in the mask, the background will be removed. wherever a 0 falls, the background is left intact.
Set OP_TAB to:
                      offset   logic op
                     -------- ----------
                       +00       04       D' <- [not S] and D
                       +01       04       D' <- [not S] and D
                       +02       07       D' <- S or D
                       +03       07       D' <- S or D


Load foreground color into FG_COL. It doesn't matter what you put into BG_COL
Next, take a monoplane form (or multiplane form) and "or" it (OP 07) into the area that you just scooped out with the mask
Feeds a family of four.

TextBlt (8)
Code: dc.w $A008  ; Perform a TEXT BLock Transfer of 1 character.
Input: WMODE = writing mode.(0-3 => VDI modes, 4-19 => BitBlt modes)

TEXTFG = text foreground color
TEXTBG = text background color. (used for modes 4-19)
FBASE = ptr to start of font data. (font form)
FWIDTH = width of font form
SOURCEX = x coord of character in font form
SOURCEY = y coord of character in font form
DESTX = x coord of character on screen
DESTY = y coord of character on screen
DELX = width of character
DELY = height of character
STYLE = vector of TextBlt special effects flags
LITEMASK = the mask to use in lightening text
SKEWMASK = the mask to use in skewing text
WEIGHT = the width by which to thicken text
ROFF = offset above character baseline when skewing
LOFF = offset below character baseline when skewing
SCALE = scaling flag (0 => no scaling)
XDDA = accumulator for x dda
DDAINC = fractional amount to scale up or down
SCALDIR = scale direction flag (0 => down)
CHUP = character rotation vector
MONO = monospaced font flag
SCRTCHP = ptr to start of text special effects buffer
SCRPT2 = offset of scaling buffer in above buffer

Output: None

Show mouse (9)
Code: dc.w $A009  ; Show the mouse.
Input: See GEM VDI manual
Output: None

Hide mouse (10)
Code: dc.w $A00A  ; Hide the mouse.
Input: See GEM VDI manual
Output: None

Transform mouse (11)
Code: dc.w $A00B  ; Transform the mouse's form.
Input: See GEM VDI manual
Output: None

Undraw sprite (12)
Code: dc.w $A00C  ; Undraw the previously drawn sprite.
Input: a2 = ptr to sprite save block

Note: The sprite save block is used to save the screen underneath the sprite. Its size is 10 bytes + 64 bytes per plane, i.e. (10 + VPLANES * 64) bytes.

Output: Clobbers a6. (C programmers beware)

Draw sprite (13)
Code: dc.w $A00D  ; Draw a sprite.
Input: d0 = x hot-spot

d1 = y hot-spot
a0 = ptr to sprite definition block
a2 = ptr to sprite save block

               Sprite definiton block layout

                  ds.w  1       x offset of hot-spot.
                  ds.w  1       y offset of hot-spot.
                  ds.w  1       format flag. (1 => VDI Format,
                                             -1 => XOR Format)

                                        VDI Format

                                fg bit  bg bit  action
                                  0       0       transparent to screen
                                  0       1       background color plotted
                                  1       0       foreground color plotted
                                  1       1       foreground color plotted
                                        

                                        XOR Format

                                fg bit  bg bit  action
                                  0       0       transparent to screen
                                  0       1       background color plotted
                                  1       0       xor screen
                                  1       1       foreground color plotted
                                        
                  ds.w  1       background color (color table index)
                  ds.w  1       foreground color (color table index)
                  ds.w  32      interleaved background/foreground image.
                                (word 0 = background line 0.
                                 word 1 = foreground line 0.
                                 word 2 = background line 1.
                                 word 3 = foreground line 1.
                                 etc.)
Output: Clobbers a6. (C programmers beware)
Bugs: This function is not usable as a Line A call in the first release of TOS. See example program #2 below for the technique one must adopt to use this function.

Copy raster form (14)
Code: dc.w $A00E  ; Copy a raster form from source to destination.
Input: See the VDI discussion of copy raster. Opaque and Transparent, EXCEPT, CONTRL(0), CONTRL(1), CONTRL(3), and CONTRL(6) are ignored. COPYTRAN = Opaque/Transparent mode flag. (0 => Opaque)
Output: None
Note: See the BitBlt discussion above.



Using the Line A interface

The inputs to the Line-A routines are contained in a structure pointed to by the value returned in a0 after an initialization call ($A000) has been made. This initialization only needs to be done once and any returned values can be saved and used as needed.

The Line A interface can be used in cooperation with the VDI and AES, however, one cannot expect the variables below to be unchanged after the VDI or AES has been used. Therefore, if an application wants to mix calls to Line-A and VDI/AES, it must reload any variables that it uses as input to the Line-A routines.

The caller should assume that registers d0-d2 and a0-a2 are clobbered upon return. The rest are preserved.


The Line A input variables structure

offset  name            type    description

  0     VPLANES         word    number of video planes.
  2     VWRAP           word    number of bytes/video line.

        note:   These variables can be changed to implement special effects,
                e.g.,doubling VWRAP will cause the routines to skip 1 scan-
                line between every scanline that is output to the screen.
                Of course, any modifications made to these variables must be
                undone when normal operation of the Line-A (or VDI) is
                desired.

  4     CONTRL          long    ptr to the CONTRL array.
  8     INTIN           long    ptr to the INTIN array.
 12     PTSIN           long    ptr to the PTSIN array.
 16     INTOUT          long    ptr to the INTOUT array.
 20     PTSOUT          long    ptr to the PTSOUT array.

        note:   See the GEM VDI manual for a discussion of the above arrays.

 24     COLBIT0         word    current color bit-plane 0 value.
 26     COLBIT1         word    current color bit-plane 1 value.
 28     COLBIT2         word    current color bit-plane 2 value.
 30     COLBIT3         word    current color bit-plane 3 value.
                
        note: current foreground writing color = 1*COLBIT0 +
                                                 2*COLBIT1 +
                                                 4*COLBIT2 +
                                                 8*COLBIT3.

 32     LSTLIN          word    set this to -1 and forget it.
 34     LNMASK          word    equivalent to VDI's line style.
 36     WMODE           word    writing mode.  (0 => replace mode,
                                                1 => transparent mode,
                                                2 => xor mode,
                                                3 => inverse trans mode.)

        note: see VDI manual for discussion of writing modes.

 38     X1              word    x1 coordinate.
 40     Y1              word    y1 coordinate.
 42     X2              word    x2 coordinate.
 44     Y2              word    y2 coordinate.
 46     PATPTR          long    ptr to the current fill pattern.
 50     PATMSK          word    fill pattern "mask".
 52     MFILL           word    multi-plane fill flag.
                                (0 => current fill pattern is single plane)
                                (1 => current fill pattern is multi-plane)

 54     CLIP            word    clipping flag (0 => no clipping)
 56     XMINCL          word    minimum x clipping value.
 58     YMINCL          word    minimum y clipping value.
 60     XMAXCL          word    maximum x clipping value.
 62     YMAXCL          word    maximum y clipping value.

 64     XDDA            word    accumulator for textblt x dda.

        note:   Should be inited to 8000H (.5) before each invocation
                of TextBlt.  

 66     DDAINC          word    fractional amount to scale up or down.

        note:   If scaling up, set DDAINC to
                256*(Intended size-Actual size)/Actual size.

                If scaling down, set DDAINC to
                256*Intended size/Actual size.

 68     SCALDIR         word    scale direction flag. (0 => down)
 70     MONO            word    0 => current font is not monospaced OR
                                     its OK for thickening to increase the
                                     width of the current font.
                                1 => current font is monospaced AND thickening
                                     may not increase the width of the font.

 72     SOURCEX         word    x coord of character in font form.
 74     SOURCEY         word    y coord of character in font form.

        note:   SOURCEX can be computed from the information held in the
                font header. (see Appendix G of VDI manual for header def)
                e.g.    temp = character value;
                        temp -= fnt_ptr->first_ade;
                        SOURCEX = fnt_ptr->off_table(temp);

                SOURCEY is typically set to 0. (top line of font form)

 76     DESTX           word    x coord of character on screen.
 78     DESTY           word    y coord of character on screen.
 80     DELX            word    width of character.
 82     DELY            word    height of character.

        note:   DELX & DELY can be computed from the font header.
                e.g.    temp = character value;
                        temp -= fnt_ptr->first_ade;
                        SOURCEX = fnt_ptr->off_table(temp);
                        DELX = fnt_ptr->offtable(temp+1)-SOURCEX;
                        DELY = fnt_ptr->form_height;

 84     FBASE           long    ptr to start of font data. (font form)
 88     FWIDTH          word    width of font form.

        note:   FBASE & FWIDTH can be computed from the font header.
                e.g.    FBASE = fnt_ptr->dat_table;
                        FWIDTH = fnt_ptr->form_width;

 90     STYLE           word    vector of TextBlt special effects flags.
                                        Bit 0 = Thicken flag.
                                        Bit 1 = Lighten flag.
                                        Bit 2 = Skewing flag.
                                        Bit 3 = Underline flag. (ignored)
                                        Bit 4 = Outline flag.

        note:   Set the bits to select the desired effects.
                Underlining must be done by the application.

 92     LITEMASK        word    the mask to use in lightening text.
 94     SKEWMASK        word    the mask to use in skewing text.
 96     WEIGHT          word    the width by which to thicken text.
 98     ROFF            word    offset above character baseline when skewing.
100     LOFF            word    offset below character baseline when skewing.

        note:   The above 5 input variables can be computed from the font
                header.
                e.g.    LITEMASK = fnt_ptr->lighten;
                        SKEWMASK = fnt_ptr->skew;
                        WEIGHT = fnt_ptr->thicken;
                        if (skewing) {
                          ROFF = fnt_ptr->right_offset;
                          LOFF = fnt_ptr->left_offset;
                        }
                        else {
                          ROFF = 0;
                          LOFF = 0;
                        }

102     SCALE           word    scaling flag. (0 => no scaling.)
104     CHUP            word    character rotation vector.
                                0 => normal horizontal orientation.
                                900 => rotated 90 degrees clockwise.
                                1800 => rotated 180 degrees clockwise.
                                2700 => rotated 270 degrees clockwise.

106     TEXTFG  word    text foreground color.

108     SCRTCHP         long    ptr to start of text special effects buffer.
112     SCRPT2          word    offset of scaling buffer in above buffer.  

        note:   These special effects buffer pointers must be initialized
                before TextBlt effects can be used.

114     TEXTBG  word    text background color. (4/20/85) RAMVDI only.
116     COPYTRAN        word    copy raster form type flag. (4/26/85) RAMVDI.
                                 0 => Opaque type
                                        n-plane source -> n-plane dest
                                        BitBlt writing modes
                                ~0 => Transparent type
                                        1-plane source -> n-plane dest
                                        VDI writing modes

118     SEEDABORT       long    ptr to routine which is called within the
                                    seedfill logic to allow the fill to be
                                    aborted.  Initialized to point to a 
                                    dummy routine which returns FALSE.
                                    Returning TRUE aborts the seedfill.

        note:   This ptr doesn't exist in 1st release of TOS.  See Example
                Program #2 for the technique to use to identify the 1st TOS
                release.


Example Line A equates

*
*
*
VPLANES         equ             0
VWRAP           equ             2
CONTRL          equ             4
INTIN           equ             8
PTSIN           equ             12
INTOUT          equ             16
PTSOUT          equ             20
COLBIT0         equ             24
COLBIT1         equ             26
COLBIT2         equ             28
COLBIT3         equ             30
LSTLIN          equ             32
LNMASK          equ             34
WMODE           equ             36
X1              equ             38
Y1              equ             40
X2              equ             42
Y2              equ             44
PATPTR          equ             46
PATMSK          equ             50
MFILL           equ             52
CLIP            equ             54
XMINCL          equ             56
YMINCL          equ             58
XMAXCL          equ             60
YMAXCL          equ             62
XDDA            equ             64
DDAINC          equ             66
SCALDIR         equ             68
MONO            equ             70
SRCX            equ             72
SRCY            equ             74
DSTX            equ             76
DSTY            equ             78
DELX            equ             80
DELY            equ             82
FBASE           equ             84
FWIDTH          equ             88
STYLE           equ             90
LITEMSK         equ             92
SKEWMSK         equ             94
WEIGHT          equ             96
ROFF            equ             98
LOFF            equ             100
SCALE           equ             102
CHUP            equ             104
TEXTFG          equ             106
SCRTCHP         equ             108
SCRPT2          equ             112
TEXTBG          equ             114
COPYTRAN        equ             116
SEEDABORT       equ             118
*
*
*
INIT            equ             $A000
PUTPIX          equ             INIT+1
GETPIX          equ             INIT+2
ABLINE          equ             INIT+3
HABLINE         equ             INIT+4
RECTFILL        equ             INIT+5
POLYFILL        equ             INIT+6
BITBLT          equ             INIT+7
TEXTBLT         equ             INIT+8
SHOWCUR         equ             INIT+9
HIDECUR         equ             INIT+10
CHGCUR          equ             INIT+11
DRSPRITE        equ             INIT+12
UNSPRITE        equ             INIT+13
COPYRSTR        equ             INIT+14
SEEDFILL        equ             INIT+15


Example program #1

                text

start:          dc.w    INIT                    ; initialize.
                move.w  #-1,LSTLIN(a0)          ; once and for all.
                move.w  #$5555,LNMASK(a0)       ; dithered line.
                move.w  #0,WMODE(a0)            ; replace mode.
                move.w  #1,COLBIT0(a0)
                move.w  #1,COLBIT1(a0)
                move.w  #1,COLBIT2(a0)
                move.w  #0,COLBIT3(a0)          ; drawing color = 7.
                move.w  #0,X1(a0)               ; X1 = 0.
                move.w  #0,Y1(a0)               ; Y1 = 0.
                move.w  #99,X2(a0)              ; X2 = 99.
                move.w  #99,Y2(a0)              ; Y2 = 99.
                dc.w    ABLINE                  ; draw line.
                .
                .
                .
                move.w  #0,-(sp)
                trap    #1                      ; exit.
                end


Example program #2

                text
*
*
*
start:          clr.l   -(sp)
                move.w  #$20,-(sp)
                trap    #1              ; supervisor mode required to use
*                                       ;    Line-A routines via jsr.
                addq    #6,sp
                move.l  d0,stksave      ; save old stack ptr.
*
*       Find out which version of Line-A handler exists.
*
                move.l  #0,a2           ; convenient value for testing.
                dc.w    INIT            ; Line-A initialization.
                move.l  a2,d2           ; old version?
                bne     a2ok            ; no, a2 points to array of Line-A
*                                       ;     routine addresses.
                lea     -4*15(a1),a2    ; yes, a2 is untouched, so use a1 plus
*                                       ;     displacement (15 addresses).
*
*       a2 now points to array of Line-A routine addresses.
*
a2ok:           move.l  4*$D(a2),drawaddr ; fetch draw routine address.
*
*       Bug-workaround/Initialization complete.
*
                move.w  #0,d0           ; init x.
                move.w  #0,d1           ; init y.
                lea     sprite,a0       ; point to sprite.
                lea     save,a2         ; point to save area.

loop:           movem.w d0-d1,-(sp)     ; save x,y.
                movem.l a0/a2,-(sp)     ; save ptrs.
                move.l  a6,-(sp)        ; draw clobbers a6.
                tst.w   old_linea       ; old or new Line-A handler?
                beq     new             ; new, branch.
                move.l  drawaddr,a3     ; fetch draw routine address.
                jsr     (a3)            ; draw the old way.
                bra     merge
*
new:            dc.w    DRSPRITE        ; draw the new way.
*
merge:          move.l  (sp)+,a6
                movem.l (sp)+,a0/a2     ; restore ptrs.
*
                move.w  #2000,d2
wait:           dbra    d2,wait         ; wait a bit.
*
                movem.l a0/a2,-(sp)     ; save ptrs.
                move.l  a6,-(sp)        ; undraw clobbers a6.
                dc.w    UNSPRITE
                move.l  (sp)+,a6
                movem.l (sp)+,a0/a2     ; restore ptrs.
                movem.w (sp)+,d0-d1     ; restore x,y.
                addq.w  #1,d0           ; inc x.
                cmp.w   #640,d0
                ble     loop
*
                move.l  stksave,-(sp)
                move.w  #$20,-(sp)
                trap    #1              ; user mode.
                addq    #6,sp
*
                move.w  #0,-(sp)
                trap    #1              ; exit.

                data
*
*
*
sprite:         dc.w            0,0     ; x,y offsets of hotspot.
                dc.w            1,0,1   ; format, background, foreground.
bob:            dc.w            $FFFF   ; background line 0.
                dc.w            $07F0   ; foreground line 0.
                dc.w            $FFFF
                dc.w            $0ff8
                dc.w            $FFFF
                dc.w            $1fec
                dc.w            $FFFF
                dc.w            $1804
                dc.w            $FFFF
                dc.w            $1804
                dc.w            $FFFF
                dc.w            $1004
                dc.w            $FFFF
                dc.w            $1e3c
                dc.w            $FFFF
                dc.w            $1754
                dc.w            $FFFF
                dc.w            $1104
                dc.w            $FFFF
                dc.w            $0b28
                dc.w            $FFFF
                dc.w            $0dd8
                dc.w            $FFFF
                dc.w            $0628
                dc.w            $FFFF
                dc.w            $07d0
                dc.w            $FFFF
                dc.w            $2e10
                dc.w            $FFFF
                dc.w            $39e0
                dc.w            $FFFF
                dc.w            $3800


                bss
*
*
*
stksave:        ds.l            1
save:           ds.b            10+64
old_linea:      ds.w            1
drawaddr:       ds.l            1
                end