; program: bitmap sphere - marcello/retro64 blog * = $801 byteaddr = $fc ;fc, fd, fe used basic byte 11,8,10,0,158,50,48,54,49,0,0,0 ;program "10 sys 2061" for autostart bmpscreen = $2000 dummy = $0 lda #>bmpscreen ;initialize self-mod code sta mod1+2 lda #cos sta mod_cos+2 lda #>sin sta skip_tc_comp+2 ;initialize self-modifying code lda #0 sta angle ;initialize angle (actually, the parameter) curve_loop ldx angle mod_cos lda cos,x ;load cos(angle) sta tc bpl skip_tc_comp ;if it's not negative, don't take the complement sec lda #<256 sbc tc sta tc ;take the complement inc nc ;set flag nc: complement for cos value has been done skip_tc_comp lda sin,x sta ts bpl skip_ts_comp sec lda #<256 sbc ts sta ts inc ns ;set flag ns: complement for sin value has been done skip_ts_comp lda r1 sta multiplicand lda tc sta multiplier ;prepares for multiplication and division (tc*r1/128) ;jsr multiply_ab ;performs multiplication jsr multiply_ab_fast lsr sum ;divide by two result of multiplication lda nc beq cos_plus_sign ;on following code, perform addition or subtraction depending ;on the sign of nc ;cos minus sign sec lda #160 ;x= 160 - (tc*r1/128) sbc sum sta xp+1 bcs continue01 ;16 bit - 8 bit numbers, bcs/dec trick to instead of sbc #00 dec xp continue01 dec nc ;reset negative cosine flag jmp skip_cos_plus_sign cos_plus_sign clc ;if nc is positive, perform addition. x = 160 - (tc*r1/128) lda #160 adc sum sta xp+1 bcc skip_cos_plus_sign inc xp skip_cos_plus_sign lda r2 ;now (r2*ts)/128, then sign-depending code as above sta multiplicand lda ts sta multiplier ;jsr multiply_ab jsr multiply_ab_fast lsr sum ;divide by two for fixed point math (256* 2 = 512) lda ns beq sin_plus_sign ;sin minus sign sec ;y = 100-(r2*ts)/128 lda #100 sbc sum sta yp dec ns ;reset negative sine flag jmp skip_sin_plus_sign sin_plus_sign clc lda #100 ;y = 100+(r2*ts)/128 adc sum sta yp skip_sin_plus_sign jsr plot ;x and y calculated, now plot the point ;mirror the other quadrants sec lda #199 sbc yp sta yp jsr plot sec lda #<319 sbc xp+1 sta xp+1 lda #>319 sbc xp sta xp jsr plot sec lda #199 sbc yp sta yp jsr plot inc angle ;increment parameter lda angle cmp #210 ;computed quadrant complete? bne curve_loop_again ;if not, continue drawing rts ;we are done curve_loop_again jmp curve_loop ;subroutine: plot a point ;part 1: compute byteaddr plot ;test code here: skip y or point computation if possible lda yp cmp yp_old bne compute_all lda xp+1 cmp xp_old+1 bne retrieve_y_comp lda xp cmp xp_old bne retrieve_y_comp rts ;if it is the same point, no need to plot it retrieve_y_comp lda byteaddr_y+1 ;retrieve old y computation sta byteaddr+1 lda byteaddr_y sta byteaddr jmp x_compute compute_all lda #bmpscreen sta byteaddr lda yp and #248 beq yp_and_7 ;if (yp and 248) = 0 don't multiply sta temp ;(yp and 248) on temp ;temp is 8 bit only sta temp2+1 ;low byte first lda #$00 ;hi byte of temp is 0 sta temp2 ;temp on temp2 asl temp2+1 rol temp2 ;temp x 2 asl temp2+1 rol temp2 ;now temp x 4 clc lda temp2+1 adc temp sta temp2+1 bcc continue inc temp2 ;now temp x 5 continue asl temp2+1 rol temp2 ;now temp x 10 asl temp2+1 rol temp2 ;now temp x 20 asl temp2+1 rol temp2 ;now temp x 40 ;temp2 now olds (yp and 248) * 40 clc lda byteaddr+1 adc temp2+1 sta byteaddr+1 lda byteaddr adc temp2 sta byteaddr ;byteaddr = byteaddr+40*(yp and 248) yp_and_7 lda yp and #7 sta temp ;(yp and 7) on temp clc lda byteaddr+1 adc temp sta byteaddr+1 sta byteaddr_y+1 ;added bcc x_compute inc byteaddr ;byteaddr = byteaddr+(yp and 7) x_compute lda byteaddr sta byteaddr_y ;added lda xp+1 and #<504 sta temp2+1 lda xp and #>504 sta temp2 ;(xp and 504) on temp2 clc lda byteaddr+1 adc temp2+1 sta byteaddr+1 lda byteaddr adc temp2 sta byteaddr ;byteaddr = byteaddr+(xp and 504) ;part2: turn on bit lda xp+1 and #7 tax ;(xp and 7) on x lda byteaddr ; sta byteaddr+2 ;swap hi-low bytes for indirect indexed lda xp+1 and #7 tay ldx #$00 ;turn on bit lda (byteaddr+1),x ora bit_table,y sta (byteaddr+1),x lda yp sta yp_old ;store yp to check if it has changed before ;plotting next point lda xp sta xp_old lda xp+1 sta xp_old+1 rts ; fast multiply (max 127 * max 90) multiply_ab_fast clc lda multiplicand adc multiplier tax sec lda multiplicand sbc multiplier bpl no_comp_dif eor #$ff clc adc #1 no_comp_dif tay sec lda square,x sbc square,y sta sum rts ;storage locations for main program radius_index byte 0 ;storage locations for plot routine xp byte 0,0 yp byte 0 bit_table byte 128,64,32,16,8,4,2,1 temp byte 0 temp2 byte 0,0 byteaddr_y byte 0,0 yp_old byte 0 xp_old byte 0,0 ;storage locations for circle/ellipse subroutine and divide angle byte 0 tc byte 0 ts byte 0 nc byte 0 ns byte 0 r1 byte 0 r2 byte 0 ;storage locations for fast multiply routine multiplicand byte 0 multiplier byte 0 sum byte 0 ;this name is retained from previous version ;it is actually a product ; ellipses radii table radius_table byte 17,34,50,63,74,83,88,90 ; sin and cosine tables sin byte 0 , 1 , 2 , 3 , 4 byte 5 , 6 , 7 , 8 , 9 byte 10 , 11 , 12 , 13 , 14 byte 14 , 15 , 16 , 17 , 18 byte 19 , 20 , 21 , 22 , 23 byte 24 , 25 , 26 , 27 , 28 byte 29 , 30 , 30 , 31 , 32 byte 33 , 34 , 35 , 36 , 37 byte 38 , 39 , 40 , 41 , 41 byte 42 , 43 , 44 , 45 , 46 byte 47 , 48 , 49 , 49 , 50 byte 51 , 52 , 53 , 54 , 55 byte 56 , 56 , 57 , 58 , 59 byte 60 , 61 , 62 , 62 , 63 byte 64 , 65 , 66 , 66 , 67 byte 68 , 69 , 70 , 71 , 71 byte 72 , 73 , 74 , 74 , 75 byte 76 , 77 , 78 , 78 , 79 byte 80 , 81 , 81 , 82 , 83 byte 83 , 84 , 85 , 86 , 86 byte 87 , 88 , 88 , 89 , 90 byte 90 , 91 , 92 , 92 , 93 byte 94 , 94 , 95 , 96 , 96 byte 97 , 98 , 98 , 99 , 99 byte 100 , 101 , 101 , 102 , 102 byte 103 , 103 , 104 , 104 , 105 byte 106 , 106 , 107 , 107 , 108 byte 108 , 109 , 109 , 110 , 110 byte 111 , 111 , 112 , 112 , 112 byte 113 , 113 , 114 , 114 , 115 byte 115 , 115 , 116 , 116 , 117 byte 117 , 117 , 118 , 118 , 119 byte 119 , 119 , 120 , 120 , 120 byte 121 , 121 , 121 , 121 , 122 byte 122 , 122 , 123 , 123 , 123 byte 123 , 124 , 124 , 124 , 124 byte 124 , 125 , 125 , 125 , 125 byte 125 , 126 , 126 , 126 , 126 byte 126 , 126 , 126 , 127 , 127 byte 127 , 127 , 127 , 127 , 127 byte 127 , 127 , 127 , 127 , 127 byte 127 , 127 , 127 , 127 , 127 cos byte 127 , 127 , 127 , 127 , 127 byte 127 , 127 , 127 , 127 , 127 byte 127 , 127 , 127 , 127 , 127 byte 127 , 127 , 126 , 126 , 126 byte 126 , 126 , 126 , 126 , 125 byte 125 , 125 , 125 , 125 , 124 byte 124 , 124 , 124 , 123 , 123 byte 123 , 123 , 122 , 122 , 122 byte 122 , 121 , 121 , 121 , 120 byte 120 , 120 , 119 , 119 , 119 byte 118 , 118 , 118 , 117 , 117 byte 117 , 116 , 116 , 115 , 115 byte 115 , 114 , 114 , 113 , 113 byte 112 , 112 , 111 , 111 , 111 byte 110 , 110 , 109 , 109 , 108 byte 108 , 107 , 107 , 106 , 105 byte 105 , 104 , 104 , 103 , 103 byte 102 , 102 , 101 , 100 , 100 byte 99 , 99 , 98 , 97 , 97 byte 96 , 96 , 95 , 94 , 94 byte 93 , 92 , 92 , 91 , 90 byte 90 , 89 , 88 , 88 , 87 byte 86 , 85 , 85 , 84 , 83 byte 83 , 82 , 81 , 80 , 80 byte 79 , 78 , 77 , 77 , 76 byte 75 , 74 , 73 , 73 , 72 byte 71 , 70 , 70 , 69 , 68 byte 67 , 66 , 65 , 65 , 64 byte 63 , 62 , 61 , 60 , 60 byte 59 , 58 , 57 , 56 , 55 byte 55 , 54 , 53 , 52 , 51 byte 50 , 49 , 48 , 48 , 47 byte 46 , 45 , 44 , 43 , 42 byte 41 , 40 , 39 , 39 , 38 byte 37 , 36 , 35 , 34 , 33 byte 32 , 31 , 30 , 29 , 28 byte 27 , 27 , 26 , 25 , 24 byte 23 , 22 , 21 , 20 , 19 byte 18 , 17 , 16 , 15 , 14 byte 13 , 12 , 11 , 10 , 9 byte 9 , 8 , 7 , 6 , 5 byte 4 , 3 , 2 , 1 , 0 ;squares for fast multiply ;((S^2)/256 ; S is a + b; a-b can be looked up in this table as well. ;Should have been /512 = 4*128, 128 is the offset for trig tables values. ;Reduced to 256 for best accuracy. Remaining division by two performed on the code. square byte 0 , 0 , 0 , 0 , 0 byte 0 , 0 , 0 , 0 , 0 byte 0 , 0 , 0 , 0 , 0 byte 0 , 1 , 1 , 1 , 1 byte 1 , 1 , 1 , 2 , 2 byte 2 , 2 , 2 , 3 , 3 byte 3 , 3 , 4 , 4 , 4 byte 4 , 5 , 5 , 5 , 5 byte 6 , 6 , 6 , 7 , 7 byte 7 , 8 , 8 , 9 , 9 byte 9 , 10 , 10 , 10 , 11 byte 11 , 12 , 12 , 13 , 13 byte 14 , 14 , 15 , 15 , 16 byte 16 , 17 , 17 , 18 , 18 byte 19 , 19 , 20 , 20 , 21 byte 21 , 22 , 23 , 23 , 24 byte 25 , 25 , 26 , 26 , 27 byte 28 , 28 , 29 , 30 , 30 byte 31 , 32 , 33 , 33 , 34 byte 35 , 36 , 36 , 37 , 38 ;*************** byte 39 , 39 , 40 , 41 , 42 byte 43 , 43 , 44 , 45 , 46 byte 47 , 48 , 49 , 49 , 50 byte 51 , 52 , 53 , 54 , 55 byte 56 , 57 , 58 , 59 , 60 byte 61 , 62 , 63 , 64 , 65 byte 66 , 67 , 68 , 69 , 70 byte 71 , 72 , 73 , 74 , 75 byte 76 , 77 , 78 , 79 , 81 byte 82 , 83 , 84 , 85 , 86 byte 87 , 89 , 90 , 91 , 92 byte 93 , 95 , 96 , 97 , 98 byte 100 , 101 , 102 , 103 , 105 byte 106 , 107 , 108 , 110 , 111 byte 112 , 114 , 115 , 116 , 118 byte 119 , 121 , 122 , 123 , 125 byte 126 , 127 , 129 , 130 , 132 byte 133 , 135 , 136 , 138 , 139 byte 141 , 142 , 144 , 145 , 147 byte 148 , 150 , 151 , 153 , 154 ;*************** byte 156 , 157 , 159 , 160 , 162 byte 164 , 165 , 167 , 169 , 170 byte 172 , 173 , 175 , 177 , 178 byte 180 , 182 , 183