Line A
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:
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
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