home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 5 / DATAFILE_PDCD5.iso / demos / baah / CakeHead2 / Cake2_Src / Library < prev    next >
Encoding:
Text File  |  1995-12-16  |  15.3 KB  |  364 lines

  1. ;                                     \|/
  2. ;                                     O O
  3. ; --------------------------------oOO--U--OOo--------------------------------
  4. ; |                                                                         |
  5. ; |                          Library for CakeHead 2.                        |
  6. ; |                       By Alain BROBECKER. (as Baah)                     |
  7. ; |                                                          September 1995 |
  8. ; ---------------------------------------------------------------------------
  9. ;   This library contains a lot of usefull routines, most of them won' t
  10. ; be called often in a sourcecode. (The worst case I think is once per
  11. ; VBl, for wait_and_swap, clear_mode9...)
  12. ;   You must note that some of these routs need to be together, because I
  13. ; considered that some variables (fixed_time, videoram_adress, ...) will
  14. ; be accessed through PC. So, better not to change the order of this
  15. ; library if you are not familiar with this.
  16. ;   Also, when I indicate ??? on the KILL line, this means that a swi
  17. ; is used, and since I have no decent docs, there may be extra registers
  18. ; modified, so beware!
  19.  
  20.  
  21. ;****************************************************************************
  22. ;                                MAKE INVERSES
  23. ;****************************************************************************
  24. ; This routine calculates and store all the numbers between (r1/1) and
  25. ; (r1/r2). You guessed it, I use this to make an inverses table, where
  26. ; r1 is the premultiplication factor.
  27. ;      IN ----  r0=adress where to create the inverses table.
  28. ;               r1=dividend.
  29. ;               r2=last divisor.
  30. ;      OUT ---  nothing.
  31. ;      KILL --  r0 to r8.
  32.  
  33. .make_inverses
  34.   mov       r3,#1                   ; Used by the division routine.
  35.   mov       r4,#1                   ; r4 is the current divisor.
  36. ._make_one_inverse
  37.   mov       r5,r4                   ; r5=divisor.
  38.   mov       r6,r1                   ; r6=premul factor=dividend.
  39.   mov       r7,#0                   ; r7 will contain the quotient of r1/r4.
  40.   mov       r8,#15                  ; Shift for the division.
  41. ._divide_one_step
  42.   cmp       r6,r5,lsl r8            ; dividend bigger than divisor<<r8?
  43.   subGE     r6,r6,r5,lsl r8         ; Yes, then dividend-=divisor<<r8,
  44.   addGE     r7,r7,r3,lsl r8         ;   and add 1<<r8 to the quotient.
  45.   subS      r8,r8,#1                ; Next shift.
  46.   bPL       _divide_one_step
  47.   cmp       r5,r6,lsl #1            ; Flags=divisor-2*rest.
  48.   addLE     r7,r7,#1                ; Round to nearest integer.
  49.   str       r7,[r0],#4              ; Save r1/r4.
  50.   add       r4,r4,#1                ; r4 is the next divisor.
  51.   cmp       r4,r2                   ; It was the last one?
  52.   bLE       _make_one_inverse
  53.   mov       pc,r14                  ; Finished.
  54.  
  55.  
  56. ;****************************************************************************
  57. ;                                MAKE SIN COS
  58. ;****************************************************************************
  59. ; This routine calculates the sinus table, for angles between 0 and 5*pi/2.
  60. ; (So the cos table is between pi/2 and 5*pi/2) I take in account the fact
  61. ; that all sinus and cosinus values between 0 and pi/4 are positive.
  62. ; When I write sinN, it is in fact sin(N*A).
  63. ;      IN ----  r0=adress where to create the table.
  64. ;      OUT ---  nothing.
  65. ;      KILL --  r0 to r12.
  66.  
  67. #set sin_shift=16                   ; Shift for saved values. Must be =<28.
  68. #set sin_nb=64                      ; Nb of angles between [0;pi/4[.
  69.  
  70. .sinA       dcd 3294116             ; sin((pi/4)/sin_nb)*2^28.
  71. .cosA       dcd 268415243           ; cos((pi/4)/sin_nb)*2^28.
  72.  
  73. .make_sinus
  74.   ldr       r1,sinA                 ; r1=sinA*2^28.
  75.   ldr       r2,cosA                 ; r2=cosA*2^28.
  76.   mov       r3,#0                   ; r3=sin0*2^28.
  77.   mov       r4,#1<<28               ; r4=cos0*2^28.
  78.   mov       r5,#sin_nb+1
  79. .make_one_sinus
  80.   mov       r6,r4,lsr #28-sin_shift ; r6=cosN*2^shift.
  81.   str       r6,[r0,#sin_nb*2*4]     ; Save sin(N+pi/2)=cosN.
  82.   mov       r6,r3,lsr #28-sin_shift ; r6=sinN*2^shift.
  83.   str       r6,[r0],#4              ; Save sinN.
  84.   umul64 r6,r7,r1,r3,r8,r9,r10      ; [r6|r7]=sinN*sinA.
  85.   umul64 r8,r9,r2,r4,r10,r11,r12    ; [r8|r9]=cosN*cosA.
  86.   sub64 r6,r7,r8,r9,r6,r7           ; [r6|r7]=cos(N+1)=cosN*sin1-sinN*sin1.
  87.   umul64 r3,r8,r3,r2,r9,r10,r11     ; [r3|r8]=sinN*cosA.
  88.   umul64 r4,r9,r4,r1,r10,r11,r12    ; [r4|r9]=cosN*sinA.
  89.   add64 r3,r8,r3,r8,r4,r9           ; [r3|r8]=sin(N+1)=sinN*cos1+cosN*sin1.
  90.   adjust64 r3,r3,r8,28              ; r1=sin(N+1)=sinN*cos1+cosN*sin1.
  91.   adjust64 r4,r6,r7,28              ; r2=cos(N+1)=cosN*sin1-sinN*sin1.
  92.   subS      r5,r5,#1                ; One sinus processed.
  93.   bNE       make_one_sinus
  94.  
  95.   sub       r0,r0,#4                ; Complete the table by stupid copy.
  96.   mov       r1,r0                   ; Point on the position which are like
  97.   add       r2,r0,#sin_nb*8         ;  (pi/4+k*(pi/2))   0<=k<=4
  98.   mov       r3,r2
  99.   add       r4,r2,#sin_nb*8
  100.   mov       r5,r4
  101.   add       r6,r4,#sin_nb*8
  102.   mov       r7,r6
  103.   add       r8,r6,#sin_nb*8
  104.   mov       r9,r8
  105.   mov       r10,#sin_nb+1           ; Copy sin_nb+1 values.
  106. ._make_sinus_copy
  107.   ldr       r11,[r0],#-4
  108.   str       r11,[r3],#4             ; sin(pi-X)=sinX.
  109.   str       r11,[r8],#-4            ; sin(2*pi+X)=sinX.
  110.   rsb       r11,r11,#0
  111.   str       r11,[r4],#-4            ; sin(pi+X)=-sinX.
  112.   str       r11,[r7],#4             ; sin(2*pi-X)=-sinX.
  113.   ldr       r11,[r2],#-4
  114.   str       r11,[r1],#4             ; cos(-X)=cosX.
  115.   subS      r10,r10,#1              ; One value copied.
  116.   strNE     r11,[r9],#4             ; cos(2*pi+X)=cosX. No copy if r10=0.
  117.   rsb       r11,r11,#0
  118.   str       r11,[r5],#4             ; cos(pi-X)=-cosX.
  119.   str       r11,[r6],#-4            ; cos(pi+X)=-cosX.
  120.   bNE       _make_sinus_copy
  121.   mov       pc,r14
  122.  
  123.  
  124. ;****************************************************************************
  125. ;                                  FIX TIME
  126. ;****************************************************************************
  127. ; This function sets the current time as new time base.
  128. ;      IN ----  nothing.
  129. ;      OUT ---  r0=nb of cent-seconds since last hard reset.
  130. ;      KILL --  r0 and ???.
  131. .fix_time
  132.   swi       OS_ReadMonotonicTime
  133.   str       r0,fixed_time
  134.   mov       pc,r14
  135. .fixed_time
  136.   dcd       0
  137.  
  138.  
  139. ;****************************************************************************
  140. ;                                 READ TIME
  141. ;****************************************************************************
  142. ; This function sets the current time as new time base.
  143. ;      IN ----  nothing.
  144. ;      OUT ---  r0=nb of cent-seconds since last time fix.
  145. ;      KILL --  r0,r1 and ???.
  146. .read_time
  147.   swi       OS_ReadMonotonicTime
  148.   ldr       r1,fixed_time
  149.   sub       r0,r0,r1
  150.   mov       pc,r14
  151.  
  152.  
  153. ; ###########################################################################
  154. ; ###########################################################################
  155. ; ###########################################################################
  156. ; ###########################################################################
  157. ; ###########################################################################
  158. ; |                                                                         |
  159. ; |                              SCREEN ROUTS                               |
  160. ; |                                                                         |
  161. ; ###########################################################################
  162.  
  163.  
  164. .videoram_adress
  165.   dcd       148,-1
  166. .screen_offset
  167.   dcd       &02000000,0
  168.  
  169. ;****************************************************************************
  170. ;                                SCREEN INIT
  171. ;****************************************************************************
  172. ; This function sets the screen to mode9, remove cursors, and read the
  173. ; physical screen base of screen.
  174. ;      IN ----  nothing.
  175. ;      OUT ---  nothing.
  176. ;      KILL --  r0,r1,???
  177. .screen_init
  178.   swi       256+22                  ; Vdu 22, set screenmode.
  179.   swi       256+9                   ; Mode 9.
  180.   swi       OS_RemoveCursors        ; Fuck the cursor.
  181.   adr       r0,videoram_adress
  182.   mov       r1,r0
  183.   swi       OS_ReadVduVariables     ; Get videoram adress.
  184.   mov       pc,r14
  185.  
  186.  
  187. ;****************************************************************************
  188. ;                               GET SHOWSCREEN
  189. ;****************************************************************************
  190. ; This function will return the adress of the showscreen.
  191. ;      IN ----  nothing.
  192. ;      OUT ---  r0=showscreen adress.
  193. ;      KILL --  r0,r1.
  194. .get_showscreen
  195.   ldr       r0,videoram_adress
  196.   ldr       r1,screen_offset+4
  197.   add       r0,r0,r1                ; r0=adress of showscreen.
  198.   mov       pc,r14
  199.  
  200.  
  201. ;****************************************************************************
  202. ;                               GET WORKSCREEN
  203. ;****************************************************************************
  204. ; This function will return the adress of the workscreen.
  205. ;      IN ----  nothing.
  206. ;      OUT ---  r0=workscreen adress.
  207. ;      KILL --  r0,r1.
  208. .get_workscreen
  209.   ldr       r0,videoram_adress
  210.   ldr       r1,screen_offset+4
  211.   eor       r1,r1,#160*256
  212.   add       r0,r0,r1                ; r0=adress of workscreen.
  213.   mov       pc,r14
  214.  
  215. ;****************************************************************************
  216. ;                               WAIT AND SWAP
  217. ;****************************************************************************
  218. ; This routine waits for vertical sync, and then it swaps between workscreen
  219. ; and showscreen, and returns adress of workscreen.
  220. ;      IN ----  nothing.
  221. ;      OUT ---  r0=adress of workscreen.
  222. ;      KILL --  r0,r1 and ???.
  223.  
  224. .wait_and_swap
  225.   mov       r0,#&13                 ; Wait for Vsync.
  226.   swi       OS_Byte
  227.   ldr       r1,screen_offset+4      ; Swap show and work screen.
  228.   eor       r1,r1,#160*256
  229.   str       r1,screen_offset+4
  230.   adr       r1,screen_offset+3
  231.   mov       r0,#22
  232.   swi       OS_Word
  233.   ldr       r0,videoram_adress      ; Calculate adress of workscreen.
  234.   ldr       r1,screen_offset+4
  235.   eor       r1,r1,#160*256
  236.   add       r0,r0,r1
  237.   mov       pc,r14
  238.  
  239.  
  240. ;****************************************************************************
  241. ;                                 DISAPPEAR
  242. ;****************************************************************************
  243. ; This routine will make the current showed screen scroll up or down to
  244. ; let another, uniformly colored, screen appear. After this rout, the
  245. ; whole videoram is filled with the color given as a parameter.
  246. ;      IN ----  r1=color to fill with. (0-255)
  247. ;      OUT ---  r0=adress of workscreen.
  248. ;      KILL --  r0 and nothing else, but uses r13.
  249.  
  250. .disappear
  251.   stmfd     r13!,{r1-r12,r14}
  252.   str       r1,_fill_pattern
  253.   mov       r11,#160                ; r11=inc1.
  254.   ldr       r10,screen_offset+4     ; r10=screen_offset.
  255.   cmp       r10,#0                  ; First screen? (r10=0)
  256.   rsbNE     r11,r11,#0              ; If r10<>0, inc1=-160.
  257.   mov       r12,r11                 ; r12=inc2=inc1.
  258.   eor       r2,r10,#160*256         ; r2=offset to workscreen.
  259.   ldr       r0,videoram_adress
  260.   add       r0,r0,r2                ; r0 points on workscreen.
  261.   bl        clear_mode9             ; Clear workscreen.
  262. ._one_frame
  263.   mov       r0,#&13                 ; Wait for Vsync.
  264.   swi       OS_Byte
  265.   addS      r10,r10,r11             ; Screen offset+=inc1.
  266.   add       r11,r11,r12             ; inc1+=inc2.
  267.   movLE     r10,#0                  ; offset=<0, then offset=0 and we
  268.   movLE     r12,#0                  ; indicate we have reached the end.
  269.   cmp       r10,#160*256
  270.   movGE     r10,#160*256            ; offset>=160*256, then offset=160*256
  271.   movGE     r12,#0                  ; and indicate it' s the end.
  272.   str       r10,screen_offset+4     ; Set screen adress.
  273.   adr       r1,screen_offset+3
  274.   mov       r0,#22
  275.   swi       OS_Word
  276.   cmp       r12,#0                  ; We have reached the end?
  277.   bNE       _one_frame
  278.   ldr       r1,_fill_pattern        ; Clear the new workscreen.
  279.   eor       r2,r10,#160*256
  280.   ldr       r0,videoram_adress
  281.   add       r0,r0,r2                ; r0 points on workscreen.
  282.   bl        clear_mode9
  283.   ldmfd     r13!,{r1-r12,pc}
  284. ._fill_pattern
  285.   dcd       0
  286.  
  287.  
  288. ;****************************************************************************
  289. ;                                 SET PALETTE
  290. ;****************************************************************************
  291. ; Not much to say, so....
  292. ;      IN ----  r2 points on the 16*3 bytes color palette.
  293. ;      OUT ---  nothing.
  294. ;      KILL --  r0 to r4 and ???.
  295. .set_palette
  296.   adr       r0,_setpal_string
  297.   mov       r3,#0                   ; Counter for the colors.
  298. ._setpal_loop
  299.   strB      r3,[r0,#1]              ; Put color number into string.
  300.   ldrB      r4,[r2],#1              ; Copy red compound into the string.
  301.   strB      r4,[r0,#3]
  302.   ldrB      r4,[r2],#1              ; Same for green...
  303.   strB      r4,[r0,#4]
  304.   ldrB      r4,[r2],#1              ; ..and blue...
  305.   strB      r4,[r0,#5]
  306.   mov       r1,#6                   ; Use a 'write 6 bytes' to change color.
  307.   swi       OS_WriteN
  308.   addS      r3,r3,#1
  309.   cmp       r3,#16                  ; 16 colors changed?
  310.   bNE       _setpal_loop
  311.   mov       pc,r14                  ; Finished.
  312. ._setpal_string
  313.   dcb       19,0,16,0,0,0
  314.  
  315. ALIGN
  316.  
  317.  
  318. ;****************************************************************************
  319. ;                                 CLEAR MODE9
  320. ;****************************************************************************
  321. ; Again a stupid routine, no comment... (22*32*14+27*14+6)=40*256
  322. ;      IN ----  r0 points on the Mode9 screen.
  323. ;               r1=pattern to fill with. (In the lower byte)
  324. ;      OUT ---  nothing.
  325. ;      KILL --  nothing, but uses r13 as a stack.
  326.  
  327. .clear_mode9
  328.   stmfd     r13!,{r2-r12,r14}
  329.   str       r13,_old_stack
  330.   add       r1,r1,r1,lsl #8
  331.   add       r1,r1,r1,lsl #16
  332.   mov r2,r1:mov r3,r2:mov r4,r3:mov r5,r4:mov r6,r5:mov r7,r6:mov r8,r7
  333.   mov r9,r8:mov r10,r9:mov r11,r10:mov r12,r11:mov r13,r12
  334.   mov       r14,#22
  335. ._clear_many
  336.   str       r14,_counter
  337.   mov       r14,r13                 ; Here, r1-r14=fill pattern.
  338.   stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
  339.   stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
  340.   stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
  341.   stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
  342.   stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
  343.   stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
  344.   stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
  345.   stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
  346.   ldr       r14,_counter
  347.   subS      r14,r14,#1
  348.   bNE       _clear_many
  349.   mov       r14,r13
  350.   stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
  351.   stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
  352.   stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
  353.   stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
  354.   stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
  355.   stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
  356.   stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r6}
  357.   sub       r0,r0,#160*256          ; Restore r0.
  358.   ldr       r13,_old_stack
  359.   ldmfd     r13!,{r2-r12,pc}
  360. ._old_stack
  361.   dcd       0
  362. ._counter
  363.   dcd       0
  364.