verz

LowRes Graph C64 - integer math

Jun 6th, 2021
935
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ; 10 SYS2061
  2.  
  3. *=$0801
  4.  
  5.         BYTE    $0B, $08, $0A, $00, $9E, $32, $30, $36, $31, $00, $00, $00
  6.  
  7.  
  8.         jsr CLRSCR      ; {clrscr}
  9.  
  10.         ; reset I (I=0)
  11.         lda #0
  12.         sta varI
  13.         sta varI+1
  14.  
  15. ForLoop
  16.         ; compute P=cos(I/2)
  17.         lda varI+1
  18.         lsr
  19.         sta angle+1
  20.         lda varI
  21.         ror
  22.         sta angle
  23.         ldy #1          ; cos
  24.         jsr SinCos      ; get Cos(I/2) (value by 65535)
  25.  
  26.         sty varP
  27.         sta varP+1
  28.         lda #0
  29.         rol
  30.         sta sgntrig1    ; save sign of the trig result
  31.  
  32.         ; compute Y=24*P*Sin(I)+25
  33.         lda varI
  34.         sta angle
  35.         lda varI+1
  36.         sta angle+1
  37.         ldy #0
  38.         jsr SinCos      ; get Sin(I) (value by 65535)
  39.  
  40.         sty M
  41.         sta M+1
  42.         lda #0
  43.         rol
  44.         eor sgntrig1
  45.         sta sgntrig2    ; flag with the combined signs of the trig results
  46.  
  47.         lda varP
  48.         ldy varP+1
  49.         sta N
  50.         sty N+1
  51.         jsr mult16
  52.  
  53.         ldy #3
  54. _lp24   lda div24,y
  55.         sta divisor,y
  56.         dey
  57.         bpl _lp24
  58.         jsr div32       ; division by 65535*65535/24
  59.  
  60.         lda sgntrig2    ; check if the result has to be subtracted
  61.         beq _sum25
  62.         clc
  63.         lda dividend
  64.         eor #$ff
  65.         ;adc #1
  66.         sta dividend
  67.  
  68. _sum25  lda #0
  69.         sta varL+1
  70.         clc
  71.         lda #25
  72.         adc dividend
  73.         lsr
  74.         sta varL
  75.  
  76.         ; compute B=(Y&1)    and    40*int(Y/2)
  77.         rol
  78.         and #1
  79.         sta varB
  80.  
  81.         lda varL        ; (<= 25)
  82.         asl             ; int(Y/2) * 2  (<= 50)
  83.         asl             ; int(Y/2) * 4  (<= 100)
  84.         adc varL        ; int(Y/2) * 5  (<= 125)
  85.         asl
  86.         ;rol varL+1     ; int(Y/2) * 10 (<= 250)
  87.         asl
  88.         rol varL+1      ; int(Y/2) * 20
  89.         asl
  90.         sta varL
  91.         rol varL+1      ; varL = int(Y/2) * 40
  92.  
  93.  
  94.         ; compute X=39*P*Cos(I)+40
  95.         lda varI
  96.         ldy varI+1
  97.         sta angle
  98.         sty angle+1
  99.         ldy #1
  100.         jsr SinCos      ; get Cos(I) (value by 65535)
  101.  
  102.         sty M
  103.         sta M+1
  104.         lda #0
  105.         rol
  106.         eor sgntrig1
  107.         sta sgntrig2    ; flag with the combined signs of the trig results
  108.  
  109.         lda varP
  110.         ldy varP+1
  111.         sta N
  112.         sty N+1
  113.         jsr mult16
  114.  
  115.         ldy #3
  116. _lp39   lda div39,y
  117.         sta divisor,y
  118.         dey
  119.         bpl _lp39
  120.         jsr div32       ; division by 65535*65535/39
  121.  
  122.         lda sgntrig2    ; check if the result has to be subtracted
  123.         beq _sum40
  124.         clc
  125.         lda dividend
  126.         eor #$ff
  127.         ;adc #1
  128.         sta dividend
  129.  
  130. _sum40  clc
  131.         lda #40
  132.         adc dividend
  133.         sta dividend
  134.  
  135.         ; compute 2^((X & 1) + 2*(Y & 1))   and    Scr + int(X/2) + 40*int(Y/2)
  136.         lsr
  137.         clc
  138.         adc varL
  139.         sta varL
  140.         lda #4
  141.         adc varL+1
  142.         sta varL+1
  143.        
  144.         lsr dividend
  145.         lda varB
  146.         rol
  147.         tay
  148.         lda _pwr2,y
  149.         sta varB        ; varB = 2 ^ (X & 1 + (2 * (Y & 1)))
  150.  
  151.  
  152.         ; Draw new point on the screen
  153.         ldy #0
  154.         ldx #15
  155.         lda (varL),y    ; get the byte from screen mem
  156. _loop   cmp _plotab,x   ; seek the value in the table
  157.         beq _found
  158.         dex
  159.         bpl _loop
  160. _found  txa
  161.         ora varB        ; add the offset for the new value
  162.         tax
  163.         lda _plotab,x   ; load the new value
  164.         sta (varL),y    ; on the screen
  165.  
  166.         ; increment counter and check the loop condition
  167.         inc varI
  168.         bne _sk
  169.         inc varI+1
  170.  
  171. _sk     lda varI+1      ; loops until I=$2d0 (4*Pi rad)
  172.         cmp #2
  173.         bne _lp
  174.         lda varI
  175.         cmp #$d0
  176.         beq _end
  177.  
  178. _lp     jmp ForLoop
  179.  
  180. _end    rts
  181.  
  182.  
  183. ; memory references
  184. Scr=$400
  185. Fac1=$61
  186. Fac2=$69
  187.  
  188. ; System references
  189. CLRSCR=$e544
  190.  
  191. ; variables
  192. varB=$2                                 ; offset in the _plotab
  193. varL=$fd                                ; Screen Location to plot
  194. varI    byte 00, 00                     ; counter
  195. varP    byte 00, 00
  196.  
  197. ; constants
  198. _plotab byte  32,126,124,226,123, 97,255,236
  199.         byte 108,127,225,251, 98,252,254,160
  200. _pwr2   byte   1, 2, 4, 8
  201.  
  202. div24 byte $55, $95, $aa, $0a           ; 65535*65535/24 = 178951509
  203. div39 byte $e6, $5b, $90, $06           ; 65535*65535/39 = 110124005
  204.  
  205.  
  206. P    =fac1
  207. M    =fac1+4
  208. N    =fac1+6
  209.  
  210. mult16
  211.         lda #$00
  212.         sta P+2
  213.         sta P+3
  214.         ldx #$10
  215. Lp      lsr N+1
  216.         ror N
  217.         bcc Sk
  218.         lda P+2
  219.         clc
  220.         adc M
  221.         sta P+2
  222.         lda P+3
  223.         adc M+1
  224. Sk      ror
  225.         sta P+3
  226.         ror P+2
  227.         ror P+1
  228.         ror P
  229.         dex
  230.         bne Lp
  231.         rts
  232.  
  233. div32   lda #0          ;preset remainder to 0
  234.         sta remainder
  235.         sta remainder+1
  236.         sta remainder+2
  237.         sta remainder+3
  238.         ldx #32         ;repeat for each bit: ...
  239.  
  240. divloop asl dividend    ;dividend lb & hb*2, msb -> Carry
  241.         rol dividend+1  
  242.         rol dividend+2
  243.         rol dividend+3
  244.         rol remainder   ;remainder lb & hb * 2 + msb from carry
  245.         rol remainder+1
  246.         rol remainder+2
  247.         rol remainder+3
  248.         lda remainder
  249.         sec
  250.         sbc divisor     ;substract divisor to see if it fits in
  251.         tay             ;lb result -> Y, for we may need it later
  252.         lda remainder+1
  253.         sbc divisor+1
  254.         sta pztemp
  255.         lda remainder+2
  256.         sbc divisor+2
  257.         sta pztemp2
  258.         lda remainder+3
  259.         sbc divisor+3
  260.         bcc skip        ;if carry=0 then divisor didn't fit in yet
  261.  
  262.         sta remainder+3 ;else save substraction result as new remainder,
  263.         lda pztemp2
  264.         sta remainder+2
  265.         lda pztemp
  266.         sta remainder+1
  267.         sty remainder  
  268.         inc dividend    ;and INCrement result cause divisor fit in 1 times
  269.  
  270. skip    dex
  271.         bne divloop    
  272.         rts
  273.  
  274. sgntrig1 =fac2+5
  275. sgntrig2 =fac2+4
  276. dividend =fac1
  277. divisor  =fac1+4
  278. remainder=fac2
  279. pztemp   =$fb
  280. pztemp2  =$fc
  281. angle    =$fb
  282.  
  283. ; *** SinCos ************
  284. ; call with Y=0 for Sin
  285. ;           Y=1 for Cos
  286. ;
  287. ; Result in A/Y (hi/lo)
  288. ;           sign in C
  289. ; ***********************
  290. SinCos
  291. ; check angle≤90
  292. ChkAng lda angle+1
  293.        bne ChQuad
  294.        lda angle
  295.        cmp #91
  296.        bcc FrstQ
  297.  
  298. ; change quadrant
  299. ChQuad iny
  300.        sec
  301.        lda angle
  302.        sbc #90
  303.        sta angle
  304.        bcs ChkAng
  305.        dec angle+1
  306.        bcc ChQuad
  307. FrstQ  tax
  308.        tya
  309.        lsr
  310.        bcc SinX
  311.  
  312. ; will get 90-α
  313.        tay
  314.        txa
  315.        eor #$FF
  316.        ;sec
  317.        adc #90
  318.        tax
  319.        tya
  320.  
  321. ; res: A/Y  sign: C
  322. SinX   lsr
  323.        lda SinHi,X
  324.        ldy SinLo,X
  325.        rts
  326. SinHi   ; hibytes of Sin(angle)×65535
  327.   byte 0, 4, 8, 13, 17, 22, 26, 31, 35, 40, 44, 48, 53
  328.   byte 57, 61, 66, 70, 74, 79, 83, 87, 91, 95, 100, 104
  329.   byte 108, 112, 116, 120, 124, 127, 131, 135, 139, 143
  330.   byte 146, 150, 154, 157, 161, 164, 167, 171, 174, 177
  331.   byte 181, 184, 187, 190, 193, 196, 198, 201, 204
  332.   byte 207, 209, 212, 214, 217, 219, 221, 223, 226
  333.   byte 228, 230, 232, 233, 235, 237, 238, 240, 242
  334.   byte 243, 244, 246, 247, 248, 249, 250, 251, 252
  335.   byte 252, 253, 254, 254, 255, 255, 255, 255, 255, 255
  336. SinLo   ; lobytes of Sin(angle)×65535
  337.   byte 0, 120, 239, 102, 219, 80, 194, 51, 161, 12
  338.   byte 116, 217, 57, 150, 238, 66, 144, 217, 27, 88
  339.   byte 142, 190, 230, 7, 31, 48, 57, 56, 47, 28, 255
  340.   byte 217, 168, 109, 39, 213, 121, 16, 155, 27, 141
  341.   byte 243, 75, 151, 212, 4, 38, 57, 62, 52, 27, 242
  342.   byte 186, 115, 27, 179, 59, 178, 25, 110, 179, 230, 8
  343.   byte 24, 22, 3, 221, 165, 91, 254, 143, 13
  344.   byte 119, 207, 20, 70, 100, 111, 103, 75, 27
  345.   byte 216, 129, 23, 152, 6, 95, 165, 215, 245, 255
  346.  
  347.  
RAW Paste Data