Triangle filling routine using doublemask HLINE machine code ingezonden door Janny
Looyenga Note
van de redactie: dit artikel is door Janny gevonden op het Internet.
De tekst is niet in zuiver Atomformaat. Wegens tijdgebrek heb ik dit
niet om kunnen zetten. Aan een ieder de uitnodiging om deze listing
te bewerken zodat deze draait op een Atom (emulator).
Lines 10 - 70 belong to triangle filling routine
10 DIM XX(3), YY(3) co-ordinates
20 DIM DD(3), GG(3) divisors and gradients
30 S = 256
40 XX1 = 10, YY1 = 15
50 XX2 = 250, YY2 = 100
60 XX3 = 120, YY3 = 190
Common to both hline routines:
rem S 0000 0001 rem E 1111 1110
0000 0011 1111 1100
0000 0111 1111 1000
0000 1111 1111 0000
0001 1111 1110 0000
0011 1111 1100 0000
0111 1111 1000 0000
1111 1111
70 S =#87: E=#80 base addresses of two overlapping tables
80 E!4=#FFFEFCF8: E!E=#F0E0C080 end-byte mask table
90 S!4=#0103070F: S!S=#1F3F7FFF start-byte mask table contents
100 L=#91:V=#93:M=#95:T=#97
110 R=#92:W=#94:G=#96:B=#98
120 DIM LL9: P.$21
130 FOR N = 1 TO 2: DIM P(-1) or P=#2800
This is the generic HLINE, does any operation
140 [
150 :LL1 LDA L
170 LSR A: LSR A: LSR A Left X/8 = no of bytes
180 TAY: STA G from left of screen in G, and Y reg
190 LDA L Left X%7 = no of bits in X reg
200 AND @7: TAX
210 LDA S,X: STA M
220 LDA R
230 LSR A: LSR A: LSR A
240 SEC: SBC G: BEQ LL4 If == 0, then start and end pixel in same byte
250 STA G Get start_byte
260 LDA M: AND W
270 ORA (B),Y: STA T
280 LDA M: AND V
290 EOR T: STA (B),Y Ex-or mask from table T into display RAM
300 INY: DEC G: BEQ LL3 Next Y byte. If byte-count == 0 then LL3
310 :LL2 LDA (B),Y do { Fetch display Byte Y
320 ORA W: EOR V
330 STA (B),Y Store display Byte
340 INY: DEC G: BNE LL2 Y--;G-- } while ( G );
350 :LL3 Endbyte:
360 LDA R Get right-X
370 AND @7: TAX number of bits in X
380 LDA E,X and E
390 STA M: AND W
400 ORA (B),Y: STA T
410 LDA M: AND V
420 EOR T: STA (B),Y
430 RTS Return
440 :LL4 LDA R
450 AND @7: TAX: LDA E,X
460 AND M
470 STA M: AND W
480 ORA (B),Y: STA T
490 LDA M: AND V
500 EOR T: STA (B),Y
510 RTS
520 ]
530 NEXT
540 P.$6:P.$7: CLEAR 4
550 ?W =
560 ?V =
610 !B=38880 - 32 * YY1 Triangle fill
620 DD3 = YY3-YY1
630 GG3 = S*(XX3-XX1)/DD3
640 F = S * XX1: H=F
650 DD1 = YY2 - YY1
660 GG1 = S*(XX2-XX1)/DD1
Horizontal Line-drawing routine, with HLINE dedicated to XOR
This is the version dedicated to XOR
150 :LL1 Entry to HLINE_XOR (37* us)
LDA L Get Left-X
170 LSR A: LSR A: LSR A divide by 8 = no of bytes
180 TAY: STA G from left of screen in G, and Y reg
190 LDA L
200 AND @7: TAX modulo 8 = no of bits in X reg rem LDA S,X: STA M snipped out
220 LDA R
230 LSR A: LSR A: LSR A
240 SEC: SBC G If right and left in same byte
BEQ LL4 then skip to Same_byte()
250 STA G Start_byte ( 27** us) rem LDA M: AND W snipped
270 LDA (B),Y: STA T rem LDA M: AND V snipped
290 EOR T: STA (B),Y Ex-or mask from table T into display RAM
300 INY Next Y byte
DEC G: BEQ LL3 If byte-count == 0 then LL3
Handle midbyte (22** us)
310 :LL2 LDA (B),Y do { Fetch display Byte Y rem ORA W: EOR V snipped
EOR @#FF flip whole byte of pixels (new)
330 STA (B),Y Store display Byte
340 INY Y++
DEC G: BNE LL2 } while ( --G );
350 :LL3 Endbyte: (28* us)
360 LDA R Get right-X
370 AND @7: TAX number of bits in X
LDA (B),Y Fetch display_byte[Y]
EOR E,X operate mask from table E
STA (B),Y replace
430 RTS Return
440 :LL4 Single_byte case (48us)
LDA S,X: STA G Store left mask in G
LDA R right-bits
450 AND @7: TAX: LDA E,X
460 AND M A = rightbit mask AND leftbitmask
500 EOR (B),Y Operate
STA (B),Y Replace
510 RTS
520 ]
Execution time
85** us if on same byte = 10.6 us per pixel
92+22*midbytes otherwise
eg 256x192 = 49152 pixels
192*(92+22*30) = 144384 us = 2.9375 us per pixel
Hex dump from location #2800
2800
A5 91
2802
4A 4A 4A
2805
85 93
2807
A8
2808
A5 91
280A
29 07
280C
AA
280D
A5 A2
280F
4A 4A 4A
2812
38
2813
E5 93
2815
F0 24
2817
85 93
2819 B1 94
|
281B
55 87
281D
91 94
281F
C8
2820
C6 93
2822
F0 0B
2824
B1 94
2826
49 FF
2828
91 94
282A
C8
282B
C6 93
282D
D0 F5
282F
A5 92
2831
29 07
2833 AA
|
2834
B1 94
2836
55 80
2838
91 94
283A
60
283B
B5 87
283D
85 93
283F
A5 92
2841
29 07
2843
AA
2844
B5 80
2845
25 93
2848
51 94
284A
91 94
284C 60
|
4D = a minute 76 bytes!
REM triangle filling routine for acorn atom.
REM from a letter to Greg, c. 1985
REM ATOM BASIC PROGRAM TO FILL TRIANGLES REM
DIMXX(3), YY(3), DD(3), GG(3): S=256
XX1=10: YY1=15
XX2=250: YY2=100
XX3=120: YY3=190
S= #87: E=#80
E!4=#FFFEFCF8
!E=#F0E0C080
S!4=#0103070F
!S=#1F3F7FFF
L= #91, R= L+1,V=L+2, W=L+3,M=L+4, G=L+5,T=L+6,B=L+7
DIM LL9, PRINT $1
F.N=1TO 2: DIM P(-1): REM or P=#2800
:LL1 LDA L: LSR A: LSR A: LSR A: TAY: STA G
LDA L: AND @07: TAX
LDA S,X: STA M
LDA R: LSR A: LSR A: LSR A: SEC SBC G
BEQ LL4
STA G
LDA M: AND W: ORA (B),Y: STA T
LDA M: AND V: EOR T: STA (B),Y
INY: DEC G
BEQ LL3
:LL2 LDA (B),Y: ORA W: EOR V: STA (B),Y
INY: DEC G
BNE LL2
:LL3 LDA R: AND @07: TAX: LDA E,X
STA M: AND W: ORA (B),Y: STA T
LDA M: AND V: EOR T: STA(B),Y
RTS
:LL4 LDA R: AND @7: TAX: LDA E,X: AND M
STA M: AND W: ORA (B),Y: STA T
LDA M: AND V: EOR T: STA(B),Y:
RTS
]
N.PRINT $6: PRINT $7: CLEAR 4
?w= SETMASK
?V= invertmask
!B= 38880-32*YY1
DD3= YY3-YY1: GG3=S*(XX3-XX1)/DD3
F= S*XX1: H=F
bottomTriangle
DD1= YY2-YY1: GG1=S*(XX2-XX1)/DD1
?l=F/S:?R=H/S: WAIT: LINK LL1: F=F+GG3: H=H+GG1
!B=!B-32: DD1=DD1-1: IF DD1<>0 GOTO bottomTriangle
topTriangle
DD2= YY3-YY1: GG2=S*(XX3-XX1)/DD1
?l=F/S:?R=H/S: WAIT: LINK LL1: F=F+GG3: H=H+GG1
!B=!B-32: DD2=DD2-1: IF DD2<>0 GOTO topTriangle
RETURN
|