Pl2 LINEA.DOC
-------------------- CHAPTER NR°8: THE LINEAS -------------------- *** INTRODUCTION *** -------------------- - LineAs are graphical functions, they are very simple but have the advantage of being really very fast. (Much more than the VDI...) LineAs are commands of the 'BLITTER', i.e., it is the HARDWARE (Some PHYSICAL components of the computer and the routines that are executed by the PROCESSOR himself.) that execute these func- tions and not the SOFTWARE (The SOFTWARE part of your computer: ROM, programs...). If your ST is equipped with the BLITTER of course... (The MEGA 2ST and the MEGA 4ST are equipped.) NB: There is a SOFTWARE version of the BLITTER that is available in the public --- domain in the form of a desktop accessory... These functions are very fast since not coming from the SOFTWARE, the routines do not need to be interpreted by the PROCESSOR. - To call the LineAs functions, you will have to provide the appro- priate parameters in the VDI TABLE and also in an INTERNAL TABLE specific to LineAs. Some registers will also be used. Indeed, the LineAs use the VDI's CONTROL, PTSIN, PTSOUT, INTIN, and INTOUT arrays. Registers d0, d1, d2, a0, a1, a2 will also be used, so you will have to be careful not to lose their content... Some parameters are also provided by the LineAs in return in d0, a0 or INTOUT (here again, be careful not to lose d0!) We have seen that the LineAs use an INTERNAL TABLE: It is in this table that the functions search for the parameters that we have deposited, the only problem is that the location of this internal table varies (hence its name). To find the location of this internal table, just call the function $A000 with: DC.W $A000 What a strange syntax isn't it?? The explanation is very simple: During the ASSEMBLY step of your listing, the ASCII codes representing the instructions and their operands will be translated into BINARY because the 68000 only recognizes information coded in binary: Thus, a NOP will be translated by %100111001110001, a RTS by %0100111 001110101 etc... and so for all instructions. If we translate these codes from binary to HEXADECIMAL, we obtain instructions coded in HEX: Thus, NOP will be written: $4E71 and RTS will be written: $4E75 etc... However, -- You can REPLACE, in an ASSEMBLER program, an instruction by its HEX CODE equivalent if it is declared as such in the TEXT segment, it would suffice to write: DC.W $4E71 instead of a NOP (or DC.B $4E, $71) or DC.W $4E75 instead of an RTS ... (or DC.B $4E, $75) This remains valid for all the instructions of the 68000 (Even for labels). But, ---- No 68000 instruction will be coded in HEX by a WORD of type: $A... (or $F...) We have therefore filled this lack (we rather took advantage of it!) by coding the LineAs functions in $A... NB: There are also $F... routines but we will not use them -- because they are not compatible between the OLD ROM and NEW ROM versions of the ST. It will therefore suffice to write DC.W $A... for the 68000 to decode this instruction by the LineA instruction of code $A... There are a total of 16 commands that are installed and that can be translated this way, these are the 16 LineAs routines: To call them simply DECLARE them in the TEXT segment: The LineAs: ----------- $A000: Installs the internal table $A001: Places 1 point on the screen $A002: Sets the color of a screen point $A003: Draws an arbitrary line $A004: Draws a horizontal line $A005: Draws a filled rectangle $A006: Draws a filled polygon $A007: ? $A008: Allows text block transfer $A009: Activates the mouse cursor $A00A: Deactivates the mouse cursor $A00B: Modifies the shape of the mouse cursor $A00C: Erases a sprite $A00D: Draws a sprite $A00E: Copies a block of points $A00F: Identical to VDI's CONTOUR FILL function (opcode=103) But let's now focus on our $A000 function: We have seen earlier that it initializes the INTERNAL TABLE in which we will place parameters. This TABLE contains 50 variables, some the size of a word and some the size of a long word. To obtain the address where the table begins, we use the function $A000: DC.W $A000 The function provides us with the address where the table is located in A0: We can now access all the variables in this table using an INDIRECT addressing mode. However, since the variables do not all have the same size (word or long word), the (a0)+ and (a0) addressing modes will not be used... We will use the d(a0) addressing mode to access the different parameters of the table: So, MOVE.W 0(a0) will place the word=0 in the 1st parameter of the table, MOVE.W 2(a0) will place the word=0 in the parameter at a0+2, and so on... Therefore, we need to know the values of the relative locations of the variables in the table. Since the d(a0) syntax is not very informative, we will define (with EQU) the relative locations of all these variables: Here they are: ; Definition of EQUIVALENCES for the INTERNAL TABLE of LineAs ; Variable NAME = Relative Displacement v_planes EQU 0 ;number of planes v_lin_wr EQU 2 ;bytes per write line ticontrol EQU 4 ;address of T.I CONTROL tiintin EQU 8 ;address of T.I INTIN tiptsin EQU 12 ;address of T.I PTSIN tiintout EQU 16 ;address of T.I INTOUT tiptsout EQU 20 ;address of T.T PTSOUT _fg_bp_1 EQU 24 ;bit 0 of color _fg_bp_2 EQU 26 ;bit 1 of color _fg_bp_3 EQU 28 ;bit 2 of color _fg_bp_4 EQU 30 ;bit 3 of color _lstlin EQU 32 ;always =-1 _ln_mask EQU 34 ;line shape for $A003 _wrt_mode EQU 36 ;WRITE MODE _x1 EQU 38 ;X coordinate of the first point _y1 EQU 40 ;Y coordinate of the first point _x2 EQU 42 ;X coordinate of the second point _y2 EQU 44 ;Y coordinate of the second point _patptr EQU 46 ;fill address _patmsk EQU 50 ;fill number _multifill EQU 52 ;details later _clip EQU 54 ;clipping flag _xmn_clip EQU 56 ;leftmost X for clipping _ymn_clip EQU 58 ;highest Y for clipping _xmx_clip EQU 60 ;rightmost X for clipping _ymx_clip EQU 62 ;lowest Y for clipping _xacc_dda EQU 64 ;points to $8000 for TXTBLT _dda_inc EQU 66 ;enlargement factor=$FFFF _t_sclsts EQU 68 ;=0 _mono_status EQU 70 ;TEXT EFFECTS type _sourcex EQU 72 ;character number in SET _sourcey EQU 74 ;=0 _destx EQU 76 ;X coordinate of TEXT _desty EQU 78 ;Y coordinate of TEXT _delx EQU 80 ;character width _dely EQU 82 ;character height _fbase EQU 84 ;SET address _fwidth EQU 88 ;SET X _style EQU 90 ;FLAG for TEXT EFFECTS _litemark EQU 92 ;shading mask _skewmask EQU 94 ;TEXT inclination mask _weight EQU 96 ;number of enlargement bits _r_off EQU 98 ;offset for TEXT italic _l_off EQU 100 ;left (Left) offset _scale EQU 102 ;enlargement flag (1/0) _chup EQU 104 ;TEXT rotation angle _txt_fg EQU 106 ;Color of TEXT foreground _scrtchp EQU 108 ;Address of a buffer for effects _scrpt2 EQU 112 ;Offset for enlargement _text_bg EQU 114 ;Background color of TEXT _copytran EQU 116 ;FLAG for writing mode Here, the structure and composition of the INTERNAL TABLE are very clear: The names used here are often default names in many works. We will only use a small part of the variables in the internal table... The definitions of equivalences for the INTERNAL TABLE are found in the file: LINEQU.L, and you should include it in your listing at the beginning of the TEXT segment. The use of variables will depend on the functions, and the details will come with the explanations... In practice: To change the variable '_patptr' in the Internal Table, you just need to write: MOVE source, _patptr(a0) To change the variable '_clip' in the Internal Table, you just need to write: MOVE source, _clip(a0) and so on... This is much more readable than writing: MOVE source, 46(a0) or MOVE source, 54(a0)... Now that our internal table is set up with DC.W $A000, we still need to provide the addresses of the CONTROL, INTIN, PTSIN, INTOUT, and PTSOUT TABLES because they are also used! This is done simply by placing these addresses in the tiintin, tiptsin, tiintout, tiptsout variables of the INTERNAL TABLE: So, you can write: MOVE.L #CONTROL, ticontrol(a0) MOVE.L #INTIN, tiintin(a0) MOVE.L #PTSIN, tiptsin(a0) MOVE.L #INTOUT, tiintout(a0) MOVE.L #PTSOUT, tiptsout(a0) To transfer the addresses into the INTERNAL TABLE. With this initialization done, you can finally use the LineAs routines. All the programs you write should look like this if you are using LINEAs: TEXT INCLUDE "INIT_TOS.L" INCLUDE "LINEQU.L" ;Equivalences for the LineAs SETBLOCK ;Initialize GEM DC.W $A000 ;Initialize the T.I. (address in a0) ; Placing the addresses of VDI TABLES in the Internal Table (T.I.) MOVE.L #CONTROL, ticontrol(a0) MOVE.L #INTIN, tiintin(a0) MOVE.L #PTSIN, tiptsin(a0) MOVE.L #INTOUT, tiintout(a0) MOVE.L #PTSOUT, tptstout(a0) . ; Your program here . . DATA . ; Data here . . BSS . . INCLUDE "TABLEAU.L" ; VDI Table END *** Explanation of Terms Used Below *** ------------------------------------------ - Graphical Coordinates: These coordinates are used to define the positions of graphic elements based on their coordinates on the X and Y axes. The origin of the orthogonal coordinate system (O, x, y) is located at the top-left point of your screen with coordinates (0, 0). - The X-axis extends from the origin O to the point on the far right at the top of the screen. - The Y-axis descends from the origin O to the point on the far right at the bottom of your screen. The number of points available along the X and Y axes depends on the resolution: In LOW resolution : (OX) = 320 pixels (points) from 0 to 319 : (OY) = 200 pixels (points) from 0 to 199 In MEDIUM resolution: (OX) = 640 pixels (points) from 0 to 639 : (OY) = 200 pixels (points) from 0 to 199 In HIGH resolution : (OX) = 640 pixels (points) from 0 to 639 : (OY) = 400 pixels (points) from 0 to 399 Be sure to always respect the graphical constraints to avoid issues. - Writing Mode: defined by the _wrt_mode variable in the internal table. There are 4 writing modes available: - If _wrt_mode=0: AND Mode, Example: BACKGROUND = %111011101110110100 ------ : DRAWING = %100011011010100011 ---> RESULT = %100011011010100011 (Background is masked) We get: BACKGROUND AND DRAWING - If _wrt_mode=1: OR Mode, Example: BACKGROUND = %101100011101010011 ------ : DRAWING = %011011101110001010 ---> RESULT = %111111111111011011 We get BACKGROUND OR DRAWING - If _wrt_mode=2: (COLOR AND DRAWING) OR (BACKGROUND NOT DRAWING) Mode, (This is the TRANSPARENT graphics mode): Points are placed where there are none yet, and if the point to be placed has no color, the point is erased. - If _wrt_mode=3: XOR Mode, Example: BACKGROUND = %1101100111000101 ------ : DRAWING = %0110011101011010 ---> RESULT = %0110011101111010 Pixels in the BACKGROUND are inverted, then an OR operation is performed with DRAWING. We get BACKGROUND XOR DRAWING NB: The default graphics mode used is mode 0. - The 4 _fg_bp_B variables are a total of 4 and are used to indicate the color according to the following mode: _fg_bp_1 = 1st bit of the color _fg_bp_2 = 2nd bit of the color _fg_bp_3 = 3rd bit of the color _fg_bp_4 = 4th bit of the color Each variable can only take a value of 1 or 0. So, for example: _fg_bp_1 = 0 _fg_bp_2 = 1 _fg_bp_3 = 1 _fg_bp_4 = 0 The color used will be color number %0110 = 6. Please note that the number of available colors varies in different graphical resolutions. - In LOW RESOLUTION: ------------------- You can use all the _fg_bp_B variables. - In MEDIUM RESOLUTION: ---------------------- You can only use the _fg_bp_1 and _fg_bp_2 variables. _fg_bp_3 and _fg_bp_4 should be set to 0 because you have only 4 colors available. - In HIGH RESOLUTION: -------------------- You can only use the _fg_bp_1 variable because only 2 colors are available at a time in this resolution. - CLIPPING allows you to define the boundaries within which your graphics can be drawn on the screen. To do this, you need to modify the _xmn_clip, _ymn_clip, _xmx_clip, and _ymx_clip variables in the internal table: - _xmn_clip and _ymn_clip define the X and Y coordinates of the top-left corner of the CLIPPING FRAME. - _xmx_clip and _ymx_clip define the X and Y coordinates of the bottom-right corner of the CLIPPING FRAME. A FLAG (or semaphore) is also used, which is a variable that is tested to determine if CLIPPING is active or not. - If you DO NOT USE CLIPPING, the _clip variable must be set to 0. - Otherwise, you set the _clip(a0) word in the internal table to any non-zero value. Example: -------- _clip=1 (different from 0, so clipping is active) _xmn_clip=0, _ymn_clip=0 _xmx_clip=50, _ymx_clip=50 If you draw a rectangle with starting coordinates of 10,10 and ending coordinates of 75,75: Only the part of the rectangle with starting coordinates of 10,10 and ending coordinates of 50,50 will be drawn because the rest of the rectangle is outside the CLIPPING FRAME. CLIPPING allows you to modify the 'action radius' of the graphic functions. Note: Exceeding the CLIPPING FRAME does not result in an error, but graphics drawn outside the frame will not be displayed. - The _multifill variable in the internal table allows you to create multicolored fill patterns (for fill options). We will always set this variable to 0 (monochrome fill). This variable in the internal table is used with functions that fill surfaces. - PAT (PATTERN) is used for functions $A004, $A005, $A006 and allows you to define the type of line and fill pattern used. The pattern normally used by these functions is '%1111111111111111' (SOLID PATTERN). Modifying PAT allows you to change the type of lines and fill patterns used by functions $A004, $A005, and $A006. For example, if PAT is set to %1010101010101010 (DOTTED) and if you use function $A004, it will draw a dotted line. If PAT is set to %1111000011110000 (DOTTED), you will get wider and more spaced dots. PAT is defined by 2 variables in the internal table: - _patptr (L-M) is the address where a sample filling pattern defined by an EVEN number of WORDs is located (see below). - _patmsk (WORD) contains the number of data (WORDS) to be read - 1. This is always an ODD number (even-1). So, if _patptr points to 'TABLE', and at this address, you find the words: TABLE DC.W %1111000011110000 ; address 'TABLE': the PATTERN DC.W %0000111100001111 DC.W %1010101010101010 DC.W %0101010101010101 ; EVEN number of WORDs _patmsk will be equal to 4-1 = 3. The filling pattern that will be used will be a pattern with a width of 16 pixels (the 16 Bits of the different WORDs, 1 = active bit, 0 = off bit) and a height of 4 lines (4 WORDs). Note: The binary representation of the data is more descriptive here. Examples of use: -------- Suppose you want to define lines with wide dots. Modify the PAT as follows: DC.W $A000 ; a0 points to the T.I. move.l #TABLE,_patptr(a0) ; set the address of the PATTERN in _patptr move #0,_patmsk(a0) ; 1-1=0 in _patmsk DATA TABLE DC.W %1111000011110000 ; the PATTERN - To achieve a filling with small squares using the $A005 function (filled rectangle), modify the PAT as follows: DC.W $A000 ; a0 points to the T.I. move.l #TABLE,_patptr(a0) ; set the address of the PATTERN in _patptr move #5,_patmsk(a0) ; 8-1=7 in _patmsk DATA TABLE DC.W %1111111111111111 ; the PATTERN (8 WORDs) DC.W %1100000000000011 DC.W %1101111111111011 ; 0 = off pixel DC.W %1101111111111011 DC.W %1101111111111011 ; 1 = active pixel DC.W %1101111111111011 DC.W %1100000000000011 DC.W %1111111111111111 *** LINEAS ROUTINES *** ------------------------ I will now describe the interesting LINEAS routines, and I will provide examples in the next file. Exercises will follow. - $A000 ----- Provides the address of the internal table in a0 and d0. Also gives the address of another table pointing to the 3 sets of characters used by the $A008 routine in a1. Call it as follows: DC.W $A000 ; In the TEXT segment ; (you can also write DC.B $A0,$00) ; Values returned in a0, a1, d0 (be careful not to lose these values; save them if necessary!) Note: Before using the other functions, make sure to initialize the ticontrol, tiintin, tiptsin, tiintout, and tiptsout variables in the internal table... - $A001 (PUT PIXEL) ----- Allows you to place a point at coordinates (X, Y) on the screen. Parameters to pass: . X in ptsin . Y in ptsin+2 . Color of the point (0 to 15) in intin (WORD) Call it as follows: DC.W $A001 ; In the TEXT segment - $A002 (GET PIXEL) ----- This function allows you to obtain the color of a point at coordinates (X, Y) on the screen. Parameters to pass: . X in ptsin . Y in ptsin+2 The color (WORD from 0 to 15) is returned in intout. Call the function as follows: DC.W $A002 ; In the TEXT segment - $A003 (LINE) ----- Allows you to draw any line with starting coordinates (A, B) and ending coordinates (C, D) on the screen. You can also modify the line's color using _fg_bp_B, line type using _ln_mask, and writing mode using _wrt_mode. Parameters to pass: . A in _x1 . B in _y1 . C in _x2 . D in _y2 You can choose the line's color, which is passed in the variables: . _fg_bp_B (Bits B used depending on the resolution) You can also modify the line type used with the variable: . _ln_mask (WORD) For example, if _ln_mask is %1111111111111111, the line will be solid. If _ln_mask is %0000111100001111, you will get large dashes, and so on. You can also choose the writing mode using the variable: . _wrt_mode (WORD = 0 to 3) Then, call the function as follows: DC.W $A003 ; In the TEXT segment - $A004 (H-LINE) ----- Allows you to draw a horizontal line (only HORIZONTAL...). The starting coordinates are (A, B), and the ending coordinates are (C, D) such that B = D (horizontal line). Just like with $A003, you can modify the line's color, writing mode, and PAT (using _patptr and _patmsk). H-LINE is a basic function and is used by the functions $A003, $A005, $A006: A curved line (routine $A003) is essentially a sequence of horizontal line segments: This explains why H-LINE is faster than LINE. Parameters to pass: . A in _x1 . B in _y1 . C in _x2 . D in _y2 ; _y1 = _y2 (horizontal line) You can choose the line's color, which is passed in the variables: . _fg_bp_B (Bits B used depending on the resolution) You can also modify the line type used with the variables: . _patptr (L-M): the address of the PATTERN . _patmsk (WORD): the number of data - 1 You can also choose the writing mode using the variable: . _wrt_mode (WORD = 0 to 3) Call the function as follows: DC.W $A004 ; In the TEXT segment
Back to ASM_Tutorial