Usually, the output is the same format than the input. What I think would be worth the try is do a specific multiplication routine that multiplies HL by cos(A), while using a third register to hold the maximum of 6 bits that will be shifted out of HL. Theory :
Code:
function multHLcosA
  A = getEntryFromCosLUT(A)
  BDE = HL*A
  HL = BDE >> 6
  return HL
end

Something like that.

If you don't want to bother doing this, use 2-bytes coordinates for all your 3D vertices, multiply them by cos values and divide them by 64 to have rotated 2-bytes values.
matrefeytontias wrote:
I use to use a 256-entries LUT, then pass the angle in A.


Code:
sin:
 sub 64
cos:
 ld l,a
 ld h,0
 ld de, cosLUT
 add hl,de
 ld a,(hl)
 ret
cosLUT:
...


To allow for an 8.8 fixed point value for each entry, would i amend this to:


Code:
sin:
 sub 64
cos:
 ld l,a
 ld h,0
add hl,hl
 ld de, cosLUT
 add hl,de
 ld a,(hl)
 ret
cosLUT:
...


also, for the cos values,

am i correct that it is:

integer part = ipart cos [ ( n / 255 ) * 360 ], base 255
decimal part = fpart cos [ ( n / 255 ) * 360 ], base 255

also, lets say the cos value turns out to be something like -.5761..

should the entry be .db 0, -value ?
because the answer is negative, but you can't sign a zero.
Rather something like :
Code:
sin:
 sub 64
cos:
 ld l, a
 ld h, 0
 ld de, cosLUT
 add hl, de
 ld a, (hl)
 ld l, a
 rla
 sbc a, a
 ld h, a
 add hl, hl
 add hl, hl
 ret

Then HL contains the 8.8 form of cos(a) or sin(a). It works this way because cos(0) = 1 would give 256 in HL. 0.5 in decimal gives 128 in 8.8.
matrefeytontias wrote:
Rather something like :
Code:
sin:
 sub 64
cos:
 ld l, a
 ld h, 0
 ld de, cosLUT
 add hl, de
 ld a, (hl)
 ld l, a
 rla
 sbc a, a
 ld h, a
 add hl, hl
 add hl, hl
 ret

Then HL contains the 8.8 form of cos(a) or sin(a). It works this way because cos(0) = 1 would give 256 in HL. 0.5 in decimal gives 128 in 8.8.


So use this? If each entry is 2 bytes long, don't we need to double hl, tho? to get the right entry?

and so I'm only computing values from -64 to 64?

edit: ACagliano the routine I posted converts the integer [-64,64] to 8.8 [-256,256]
this confused me lol. Could you perhaps, at your leisure, show me with like the first few entries of an 8.8 LUT so i can follow.
So I see you're a bit confused here Razz let me explain.

So you want cos and sin.values in 8.8 format right ? So that means cos(0) = 256 and cos(128) = -256. To speed things up, you'll be using a LUT where cos(0) = 64 and cos(128) = -64. Why those values ? Because they all stay in one byte and permit to have cos(0) = -cos(128). If we had taken cos(0) = 128, the fact we store it in one byte would have made it -128.

So we have a 256-entries LUT made out of values in the range [-64,64]. We're not going to use them directly since we want 8.8 numbers, so instead you'll use the routine I just posted ; it will convert your one-byte signed value to a 8.8 signed value. To sum up, my routine is a function that can be depicted like this :

f : [-64,64] -> [-256,256]
ok, so use that routine with what? 1-byte integer values in the LUT?
Yes, the cosLUT must be made of 256 entries, one-byte each. The first one must be 64, since cos(0) = 1 and we scale the values to 64 for the LUT.
So, 64 to -64, where cos (0) = 1, because it is lol
but, if its only a 1-byte signed value, and that one-byte signed value must be an integer, then how do you get the fpart out of that?
May I remind you that cosinus and sinus don't have integer parts ?
OOOHHHHHHHHHHHH!

*smacks self with a textbook.

So all i need to do is convert the decimal part into an integer number that's base 256? !!
It's what the LUT and my routine are for >_> the LUT is a representation of cos(x) where cos(0) = 64. When you want to retrieve a value from the LUT, my routine converts it in 8.8 format for you.
Ok here's a list of all the mathematical routines that I need. I'll try to work on these myself in the next couple days, but anyone who wants to post one, feel free. It would help.

8 bit x 8.8 fixed point
8.8 FP x 8.8 FP

and then, adding

8 8 8 8 . 8 + 8.8 (or whatever the output of the 8.8 x 8.8 above will be)

the 8 8 8 8 is a 4 byte long coordinate (2 bytes for the sector, 2 for the coords, and 1 for the coord decimal). the coord decimal needs to carry to the coords, and the coords need to carry to the sector.
Okay so here's your addition routine. It adds DE to 5 bytes at HL and stores the result to the same 5 bytes at HL. It can be greatly optimized, but that's my try.


Code:
 ld bc, 4
 add hl, bc
 ld a, e
 add a, (hl)
 ld (hl), a
 dec hl
 ld a, d
 adc a, (hl)
 ld (hl), a
 dec hl
 ld b, 3
addLoop:
 ld a, 0
 adc a, (hl)
 ld (hl), a
 dec hl
 djnz addLoop
 ret
Thanks for that.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 3 of 3
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement