Triangle filling routine using doublemask HLINE machine code Written for the Acorn Atom 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 0000 0011 0000 0111 0000 1111 0001 1111 0011 1111 0111 1111 1111 1111 rem E 1111 1110 1111 1100 1111 1000 1111 0000 1110 0000 1100 0000 1000 0000 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 Handle midbyte 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!