Heaven/TQA Posted March 19, 2009 Share Posted March 19, 2009 is there an 6502 pendant to this z80 code: ; _____ __ ; / _ \_______| | ______ ______ ; / /_\ \_ __ \ |/ / _ \/ ___/ ; / | \ | \/ < <_> )___ \ ; \____|__ /__| |__|_ \____/____ > ; \/ \/ \/ ; Generate a 1024 bytes long, 8bits, sinus-like curve. ; Grim/Arkos^Semilanceata ; Configuration ;cnf_math_singen_sizeopt_store equ &2000 ;cnf_math_singen_unsigned equ 0 ; ********************************** ; * GENERATE 1024Bytes SINUS CURVE * ; ********************************** LET def_math_singen_sizeopt_store = cnf_math_singen_sizeopt_store AND &FC00 math_singen_sizeopt: ; Where is stored the sinus curve used as reference (1024bytes) ; Address must be (and will be forced) at any &400 boundary. ; autoconfig / do not change anything below LET def_math_singen_sizeopt_lenght = 1024 LET def_math_singen_sizeopt_store_h = def_math_singen_sizeopt_store/256 LET def_math_singen_sizeopt_and_mask = &03 LET def_math_singen_sizeopt_or_mask = def_math_singen_sizeopt_store_h AND &FC LET def_math_singen_sizeopt_store_q3 = def_math_singen_sizeopt_store_h+2 LET def_math_singen_sizeopt_store_q4 = def_math_singen_sizeopt_store_h+3 ; Parabolic approximation: ; sin(a) = ( (a-1)^2 ) - 1 @a[0, pi/2] ; used here : ; sin(a) = a^2 @ a[0,pi/2] ; [0, 2pi] => [0, 1024] ; 39 bytes long / 6405 NOPs ; try to beat diz ! =) xor a ld bc, def_math_singen_sizeopt_store_q3*256 + def_math_singen_sizeopt_store_q4 ld l,a ld e,l exx ld b,a; 256 ld d,b _math_singen_sizeopt_loop ld c,b dec b ld e,b ld h,d ld l,d _math_singen_sizeopt_square add hl,de djnz _math_singen_sizeopt_square ld a,h exx rra ifndef cnf_math_singen_unsigned sub 128 endif ld d,b ld h,c dec l ld (de),a; 3rd Quad ld (hl),a; 4th Quad cpl res 1,d res 1,h ld (de),a; 1st Quad ld (hl),a; 2nd Quad inc e exx ld b,c djnz _math_singen_sizeopt_loop ifndef cnf_math_singen_inline ret endif Quote Link to comment Share on other sites More sharing options...
bogax Posted March 22, 2009 Share Posted March 22, 2009 (edited) No one else has responded so I'll take a whack. I can't read that Z80 gibberish so I'm not really sure what it's doing You can generate squares by accumulating a constantly varying difference. That is, the difference between consecutive squares goes up linearly. So to create a parabola you increment a counter and accumulate the the count as you go. This code is just off the top of my head and not really tested so take it with a grain of salt. y is used for the counter (and table pointer) x is used as a table pointer to mirror eor #$FF flips it around the horizontal axis sin0 is the first quadrant, sin1 the second etc The count is accumulated with the low byte in lo and the high byte in a and/or the table ldx #$FF lda #$00 sta lo tay clc bcc ENTER_LOOP LOOP tya adc lo sta lo lda #$00 ADC sin3-1,y ENTER_LOOP sta sin3,y sta sin2,x eor #$FF sta sin1,y sta sin0,x dex iny bne LOOP (Edited to make it look a lot more like a sine and a lot less like an inverted cosine ) Edited March 23, 2009 by bogax Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted March 23, 2009 Author Share Posted March 23, 2009 thx. so in theory I would need a 256 byte sin first quadrant? I have 256 byte singens f.e. : //calc "sine" (or more like a set of parabolas)... ldy #$ff !loop: loa: lda #$18 adc #$07 sta loa+1 bcc !+ inc hia+1 clc !: lo: adc #0 sta lo+1 pla hia: adc #0 pha sta sine128+$c0,x sta sine128-$40,y eor #$7f sta sine128+$40,x sta sine128-$c0,y inx dey cpx #$40 bne !loop- ldx #0 // copy sine... !: txa and #$40 lsr lsr adc #$e0 sta d018s,x txa and #$3f tay lda #%10101010 sta sprite0-1,y lsr sta sprite1-1,y lda #%11111111 sta sprite2-1,y ls: lda sine128+$20,y lsr adc #$60 ss: sta sine2,x inx bne !- dec ss+2 lda ls+1 adc #$40 sta ls+1 bcc !- ok...it is c64 code... Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted March 23, 2009 Author Share Posted March 23, 2009 well... and with this version is there a chance for a fixed point version? f.e. 8.8? Quote Link to comment Share on other sites More sharing options...
bogax Posted March 24, 2009 Share Posted March 24, 2009 well... and with this version is there a chance for a fixed point version? f.e. 8.8? As in 16 bits total with 8 integral and 8 fractional bits ? Not sure there's any point, a parabola is just not that close to a sine. It only gives you something like 4 bits of accuracy in the worst case I think the fractional part would be nonsense except for just a few table entries I did 256 bytes per quadrant because it looked to me like that was what the Z80 code was doing and because it fit neatly with using the y register as the counter. What exactly do you want to end up with? Four quadrants in 256 entries in 8.8 format? I might also mention that the code I posted does not result in 2's complement althought that would be easy enough to do. Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted March 24, 2009 Author Share Posted March 24, 2009 I have seen a lot of singens in 256 byte or 1k intros for c64 and speccy.... and as I realised that they all use kind of parabolic approximation which I forgot completly... but they are not using "real" sinus/cosinus for calculation but for sinus like effects.... so maybe forget my fixed point thing... another interesting way would be to use the build in basic and floating point maths... that would be cool, too... Quote Link to comment Share on other sites More sharing options...
bogax Posted March 28, 2009 Share Posted March 28, 2009 Just for the hell of it, here's a couple that do 256 byte tables. Not as neat, I couldn't think of an elegant way to use y for the counter. They're basically the same, one using selfmodifying code. ldx #$3F lda #$00 tay sta cntr_lo sta cntr_hi sta acc_lo clc bcc ENTER_LOOP LOOP lda cntr_lo adc #$10 sta cntr_lo lda cntr_hi adc #$00 sta cntr_hi lda acc_lo adc cntr_lo sta acc_lo lda sin+191,y adc cntr_hi ENTER_LOOP sta sin+192,y sta sin+128,x eor #$FF sta sin+64,y sta sin,x iny dex bpl LOOP ldx #$3F lda #$00 tay clc bcc ENTER_LOOP LOOP lda #$00 ;cntr_lo adc #$10 sta LOOP+1 ;sta cntr_lo bcc SKIP inc CNTR_HI+1 SKIP lda #$00 ;acc_lo adc LOOP+1 ;add cntr_lo sta SKIP+1 ;sta acc_lo lda sin+191,y CNTR_HI adc #$00 ;cntr_hi ENTER_LOOP sta sin+192,y sta sin+128,x eor #$FF sta sin+64,y sta sin,x iny dex bpl LOOP Quote Link to comment Share on other sites More sharing options...
thorfdbg Posted May 29, 2009 Share Posted May 29, 2009 I have seen a lot of singens in 256 byte or 1k intros for c64 and speccy.... and as I realised that they all use kind of parabolic approximation which I forgot completly... but they are not using "real" sinus/cosinus for calculation but for sinus like effects.... so maybe forget my fixed point thing... another interesting way would be to use the build in basic and floating point maths... that would be cool, too... The floating point ROM does not contain the sin() function, it's unfortunately in the BASIC rom, not in the mathpack. Anyhow, the implementation there is also pretty naive, it uses a 6th order Taylor approximation (thus, just a higher order polynomial) and is slow and not very precise. A much faster algorithm that can be implemented with a short table entirely in integer math is the CORDIC algorithm, used in the first pocket calculators. The idea is neat, and the table size is much shorter. Here's a short intro: http://en.wikipedia.org/wiki/CORDIC I've a C implementation of a cordic-based "arctan" function - requires a short table (depending on the precision you need), and only additions, subtractions and shifts. No multiplications, no division. Ideal for the 6502. Atari engineers had no big clue about mathematics when implementing the math-pack, I afraid. So long, Thomas 1 Quote Link to comment Share on other sites More sharing options...
g0blinish Posted September 28, 2014 Share Posted September 28, 2014 I used simple routine of sine generation in "Moving IT!". 56 bytes or less. Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted September 29, 2014 Author Share Posted September 29, 2014 bumping up old threads of mine let me feel old and grey Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted September 29, 2014 Author Share Posted September 29, 2014 any CORDIC implementation in 6502? Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.