@ gba library maths routines.
@ Pete (dooby@bits.bris.ac.uk)

@ Some of these were taken from Acorn/ARM docs, some from the GBA BIOS.

	.global	gba_sin
	.global	gba_cos
	.global	gba_sinq
	.global	gba_cosq

	.section	.iwram,"ax",%progbits
	.arm
	.align
	.text

@ signed long int gba_sinq(int ang)@
@ Returns 128*sin(ang), sign extended to fill the word.
@ ang /must/ be 0..359.
gba_sinq:
	ldr	a2, =gba_sincos	@ Point at LUT.
	ldrsb	a1, [a2, a1]		@ Load value.
	@mov	pc, lr			@ Exit.
	bx	lr			@ Exit.

	.pool

@ signed long int gba_cosq(int ang)@
@ Returns 128*cos(ang), sign extended to fill the word.
@ ang /must/ be 0..359.
gba_cosq:
	ldr	a2, =gba_sincos	@ Point at LUT.
	add	a1, a1, #90		@ Shift for cos.
	cmp	a1, #360
	subge	a1, a1, #360
	ldrsb	a1, [a2, a1]		@ Load value.
	@mov	pc, lr			@ Exit.
	bx	lr			@ Exit.

	.pool

@ signed long int gba_sin(int ang)@
@ Returns 128*sin(ang), sign extended to fill the word.
gba_sin:
	ldr	a2, =gba_sincos	@ Point at LUT.
@ Check if we're < 0.
	cmp	a1, #0			@ Are we less than 0?
	bge	gba_sin_skip_lo		@ No - skip.
gba_sin_lo:
	adds	a1, a1, #360		@ Yes - increment.
	bmi	gba_sin_lo		@ Loop if still low.
gba_sin_skip_lo:
@ Check if we're > 359.
	cmp	a1, #360		@ Are we >= 360?
	blt	gba_sin_ok		@ Skip if we're ok.
gba_sin_hi:
	sub	a1, a1, #360		@ Decrement if not.
	cmp	a1, #360		@ Under 360 yet?
	bge	gba_sin_hi		@ Nope - go again.
gba_sin_ok:
	ldrsb	a1, [a2, a1]		@ Load value.
@	mov	a1, a1, lsl #24		@ Shift up.
@	mov	a1, a1, asr #24		@ Sign extend down.
	@mov	pc, lr			@ Exit.
	bx	lr			@ Exit.

	.pool

@ signed long int gba_cos(int ang)@
@ Returns 128*cos(ang), sign extended to fill the word.
gba_cos:
	ldr	a2, =gba_sincos	@ Point at LUT.
	adds	a1, a1, #90		@ Shift for cos.
	bpl	gba_cos_skip_lo		@ If we're > 0 skip.
gba_cos_lo:
	adds	a1, a1, #360		@ If we're < 0 increment.
	bmi	gba_cos_lo		@ And go again if neccessary.
gba_cos_skip_lo:
	cmp	a1, #360		@ Check if we're >= 360?
	blt	gba_cos_ok		@ Skip if ok.
gba_cos_hi:
	sub	a1, a1, #360		@ Decrement if not.
	cmp	a1, #360		@ Under yet?
	bge	gba_cos_hi		@ Go again if not.
gba_cos_ok:
	ldrsb	a1, [a2, a1]		@ Load value.
@	mov	a1, a1, lsl #24		@ Shift up.
@	mov	a1, a1, asr #24		@ Sign extend down.
	@mov	pc, lr			@ Exit.
	bx	lr			@ Exit.

	.pool

gba_sincos:
	.word	0x07040200
	.word	0x100D0B09
	.word	0x18161412
	.word	0x211F1D1B
	.word	0x2A282523
	.word	0x32302E2C
	.word	0x3A383634
	.word	0x42403E3C
	.word	0x49484644
	.word	0x514F4D4B
	.word	0x57565452
	.word	0x5E5C5B59
	.word	0x6362615F
	.word	0x69686665
	.word	0x6E6D6B6A
	.word	0x7271706F
	.word	0x76757473
	.word	0x79787777
	.word	0x7C7B7A7A
	.word	0x7E7D7D7C
	.word	0x7F7F7E7E
	.word	0x7F7F7F7F
	.word	0x7F7F7F7F
	.word	0x7F7F7F7F
	.word	0x7E7F7F7F
	.word	0x7D7D7E7E
	.word	0x7A7B7C7C
	.word	0x7778797A
	.word	0x74757677
	.word	0x70717273
	.word	0x6B6D6E6F
	.word	0x6668696A
	.word	0x61626365
	.word	0x5B5C5E5F
	.word	0x54565759
	.word	0x4D4F5152
	.word	0x4648494B
	.word	0x3E404244
	.word	0x36383A3C
	.word	0x2E303234
	.word	0x25282A2C
	.word	0x1D1F2123
	.word	0x1416181B
	.word	0x0B0D1012
	.word	0x02040709
	.word	0xFAFCFE00
	.word	0xF1F3F5F8
	.word	0xE8EAECEF
	.word	0xDFE2E4E6
	.word	0xD7D9DBDD
	.word	0xCED1D3D5
	.word	0xC6C8CACC
	.word	0xBFC1C2C4
	.word	0xB7B9BBBD
	.word	0xB0B2B3B5
	.word	0xA9ABADAE
	.word	0xA3A4A6A8
	.word	0x9D9EA0A1
	.word	0x98999A9C
	.word	0x93949596
	.word	0x8E8F9192
	.word	0x8B8C8C8D
	.word	0x8788898A
	.word	0x85858687
	.word	0x83838484
	.word	0x81828282
	.word	0x81818181
	.word	0x81808181
	.word	0x81818181
	.word	0x82828181
	.word	0x84838382
	.word	0x86858584
	.word	0x89888787
	.word	0x8C8C8B8A
	.word	0x918F8E8D
	.word	0x95949392
	.word	0x9A999896
	.word	0xA09E9D9C
	.word	0xA6A4A3A1
	.word	0xADABA9A8
	.word	0xB3B2B0AE
	.word	0xBBB9B7B5
	.word	0xC2C0BFBD
	.word	0xCAC8C6C4
	.word	0xD3D1CECC
	.word	0xDBD9D7D5
	.word	0xE4E2DFDD
	.word	0xECEAE8E6
	.word	0xF5F3F1EF
	.word	0xFEFCFAF8

	.end
