Atom Nieuws 2000 nr 2
../../../images/back.gif ../../../images/exit.gif ../../../images/forward.gif
pagina 6
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

../../../images/back.gif ../../../images/exit.gif ../../../images/forward.gif