Exchange of experience - The procedure for generating sine.

Adventurer #09
     (C) SerzhSoft


          UC SINUS ZABABAHAT


                    Better in the hands of the chickadee,

                   than under the bed, duck!



     It is time to talk about sore, and more specifically - 
about the sinuses. The point that in many megademnyh effects

used exactly sinus tablets.
This can be unpretentious plasma any body moving in a smooth
trajectory, the flight over the mountains, tonnelchik
and a lot more of the other, which only
one can wish ...

     Traditionally, and convenient, of course,
create a sine plate with a size
multiple of 256 bytes, or even better - just
# 0100! : -) This plate must begin with the address aligned to 
a segment that is least significant byte of the address is 
equal to the toe (#? 00). 

     Create a simple sin-table can be
using ordinary BASIC. For example,
we need a plaque, located in
address 24576 (# 6000), length 256 bytes
amplitude (scope) sine -127 to
127 and the size of one period. We get:

 10 FOR i = 0 TO 255
 20 POKE 24576 + i, SIN (PI/128 * i) * 127
 1930 NEXT i


     Now generated a plate can be stored on disk and embedded 
in their assembler effects on INSERT, INCBIN and

etc.

     But you decided to tweak
amplitude, say from -63 to 63, or you
suddenly knocked in the head, that "the median
point "should not be 0 and, say, 128.
That is, a scatter plate from 128-63 to 128 63. Of course, you 
can again, "download" BASIC and gain a little

another program:

 10 FOR i = 0 TO 255
 20 POKE 24576 + i, SIN (PI/128 * i) * 63 128
 1930 NEXT i


     Then again, keep everything on the disk,
and continue to kodit asm'e. But perhaps even last lameru 
became clear that there is something wrong. Inefficient, a 
waste of time, and even space on the disk all sorts of "left" 
files occupy. Plus, to ensure same Ping compile with podgruzku 
on INCBIN'u. And keep a sinus period in memory when you can do 
and four ... No, this must have something to do! 

     And the output is, of course, there is. Not really 
something We weakly nakodit generation procedure

sinus in assembler. Yes, a piece of cake!
Clap, and is ready routine using ROM 'Shnogh calculator. A 
similar thing present in Deja Vu # 03

article "Floating attributes. Here
is slightly improved procedure:

STACK_A EQU # 2D28
FP_TO_A EQU # 2DD5
;
SINCALC

        PUSH DE

        PUSH BC

        PUSH DE

        LD A, C

        CALL STACK_A

        POP DE

        LD A, E

        CALL STACK_A

        RST # 28; calc

        DB # A3; stk_pi / 2

        DB # 34, # 40, # B0, # 00, # 40, # 40

        DB # 05; divide

        DB # 04; multiply

        DB # 1F; sin

        DB # 04; multiply

        DB # 38; endcalc

        CALL FP_TO_A

        JR Z, $ +4; ->

        NEG; |

        POP BC; <
        ADD A, B

        POP DE

        LD (DE), A

        INC E

        JR NZ, SINCALC

        RET


     At the entrance to the register C, we must specify the 
"scope" sine (amplitude:-P ... + C), the register B - central

(How to add), and the register pair
DE must contain the address of the buffer under
plate. Moreover, this address must
must be divisible by 256 (aligned to the segment). And then, 
after about 15 seconds, we get those treasured 256 bytes!


     "So up-to-olgo!" - Fair notice and you're right. But what 
you have like only 39 bytes of memory occupied by the 
procedure. But, of course, this example was given only for 
completeness paintings, and this procedure we will examine now. 
After all, why would you in the demo, write "Please, wait 15 
sec ... Decrunching ... "just for a plaque in 256 bytes! And 
rightly so! So, here high-speed analog above procedure, which 
works much faster, though he still has 55 bytes + 64 bytes 
data. Total: 119 bytes. But the speed! 

SINMAKE

        INC C

        LD HL, SIN_DAT

        PUSH BC

        LD B, E
LP_SMK1 PUSH HL

        LD H, (HL)

        LD L, B

        LD A, # 08
LP_SMK2 ADD HL, HL

        JR NC, $ +3

        ADD HL, BC

        DEC A

        JR NZ, LP_SMK2

        LD A, H

        LD (DE), A

        POP HL

        INC HL

        INC E

        BIT 6, E

        JR Z, LP_SMK1

        LD H, D

        LD L, E

        DEC L

        LD A, (HL)

        LD (DE), A

        INC E
LP_SMK3 LD A, (HL)

        LD (DE), A

        INC E

        DEC L

        JR NZ, LP_SMK3
LP_SMK4 LD A, (HL)

        NEG

        LD (DE), A

        INC L

        INC E

        JR NZ, LP_SMK4

        POP BC
LP_SMK5 LD A, (DE)

        ADD A, B

        LD (DE), A

        INC E

        JR NZ, LP_SMK5

        RET
;
SIN_DAT

  DB # 00, # 06, # 0D, # 13, # 19, # 1F, # 25, # 2C

  DB # 32, # 38, # 3E, # 44, # 4A, # 50, # 56, # 5C

  DB # 62, # 67, # 6D, # 73, # 78, # 7E, # 83, # 88

  DB # 8E, # 93, # 98, # 9D, # A2, # A7, # AB, # B0

  DB # B4, # B9, # BD, # C1, # C5, # C9, # CD, # D0

  DB # D4, # D7, # DB, # DE, # E1, # E4, # E7, # E9

  DB # EC, # EE, # F0, # F2, # F4, # F6, # F7, # F9

  DB # FA, # FB, # FC, # FD, # FE, # FE, # FF, # FF


     Now when you install any
Your FX'a enough to cause SINMAKE
required parameters, and after a second
plate is ready! Can generates a number of different plates ... 
Or one, but consisting of different periods of sinus with

different amplitudes ... And then, say,
to put on the table scroller and torn on all cylinders ...

     In the Appendix you will find the assembler
source with the two procedures. AND
remember:


         Better Playing sinus

         than megademe glitches!


     P.S. But you can do without
plate data SIN_DAT! Who would guess -
how? : -)