chickendude wrote:
lirtosiast: I believe your routine should work for unsigned numbers as is as well.
You mean signed numbers?
_FillRectangle_NoClip:
Draws an unclipped rectangle with the global color index
Arguments:
arg0 : X Coord
arg1 : Y Coord
arg2 : Width
arg3 : Height
Returns:
None
ld iy,0
add iy,sp
ld a,(iy+12) ; height
or a
ret z
ld bc,(iy+9) ; width
sbc hl,hl
adc hl,bc
ret z
ld hl,(iy+3) ; hl = x coordinate
ld e,(iy+6) ; e = y coordinate
_FillRectangle_NoClip_ASM:
ld d,lcdWidth/2
mlt de
add hl,de
add hl,de
ld de,(currDrawBuffer)
add hl,de
ex de,hl
push de
ld (_RectangleWidth1_SMC),bc \.r
ld (_RectangleWidth2_SMC),bc \.r
ld hl,color1
ldi ; check if we only need to draw 1 pixel
pop hl
jp po,_Rectangle_NoClip_Skip \.r
ldir
_Rectangle_NoClip_Skip:
dec a
ret z
inc b
ld c,$40 ; = fast "ld bc,lcdWidth"
_Rectangle_Loop_NoClip:
add hl,bc
dec de
ex de,hl
_RectangleWidth1_SMC =$+1
ld bc,0
lddr
dec a
ret z
ld bc,2*lcdWidth+1
add hl,bc
inc de
ex de,hl
_RectangleWidth2_SMC =$+1
ld bc,0
ldir
ld bc,2*lcdWidth-1
dec a
jr nz,_Rectangle_Loop_NoClip
ret
;-------------------------------------------------------------------------------
;_FillRectangle_NoClip:
; Draws an unclipped rectangle with the global color index
; Arguments:
; arg0 : X Coord
; arg1 : Y Coord
; arg2 : Width
; arg3 : Height
; Returns:
; None
;
; ld iy,0
; add iy,sp
; ld bc,(iy+9) ; bc = width
; sbc hl,hl
; adc hl,bc
; ret z ; make sure width is not 0
; ld a,(iy+12) ; a = height
; or a,a
; ret z ; make sure height is not 0
; ld hl,(iy+3) ; hl = x coordinate
; ld e,(iy+6) ; e = y coordinate
;_FillRectangle_NoClip_ASM:
; ld d,lcdWidth/2
; mlt de
; add hl,de
; add hl,de
; ld iy,(currDrawBuffer)
; ex de,hl ; de -> place to begin drawing
; ld (_RectangleWidth_SMC),bc \.r
;_Rectangle_Loop_NoClip:
; add iy,de
; lea de,iy
;_RectangleWidth_SMC =$+1
; ld bc,0
; ld hl,color1 \.r
; ldi ; check if we only need to draw 1 pixel
; jp po,_Rectangle_NoClip_Skip \.r
; scf
; sbc hl,hl
; add hl,de
; ldir ; draw the current line
;_Rectangle_NoClip_Skip:
; ld de,lcdWidth ; move to next line
; dec a
; jr nz,_Rectangle_Loop_NoClip
; ret
;----------------------------------------------------------------------
atan8:
;returns H=256*arctan(E/256)
;48cc if ADL mode
;takes 164cc to call this on the TI-84+CE
ld c,201
ld b,e
mlt bc ;x*201
xor a
sub e
ld d,a
mlt de ;x(256-x)
ld l,e
ld h,70
ld e,h
mlt de ;upper bytes
mlt hl ;lower bytes
ld a,e
add a,h
ld l,a
ld h,d
jr nc,$+3
inc h
add hl,bc
ret
section .text
; Approximates the square root of a number
; floor(2^(floor((floor(log2(x))+1)/2)-1) + (x)/(2^(floor((floor(log2(x))+1)/2)+1)))
; Generally within +6.07% -2% of the real answer
; Inputs:
; sp + [3,5] : Number to take the square root of
; Outputs:
; HL: Square root
; Destroys:
; A, B, DE, F
public _approx_sqrt_a
_approx_sqrt_a:
; Set hl to 3
ld hl, 3
add hl, sp
ld de, (hl)
sbc hl, sp
sbc hl, de
ex de, hl
; If the number is greater than 3, move on
jr c, threeCont
; Else, if the number is 1 or 0, return HL
bit 1, l
ret z
; Else, return HL - 1
dec hl
ret
; Inputs:
; DE : Number to take the square root of
; Outputs:
; HL: Square root
; Destroys:
; A, B, DE, F
public approx_sqrt_a
approx_sqrt_a:
ld hl, 3
or a, a
sbc hl, de
ex de, hl
; If the number is greater than 3, move on
jr c, threeCont
; Else, if the number is 1 or 0, return HL
bit 1, l
ret z
; Else, return HL - 1
dec hl
ret
threeCont:
; Just to be safe
di
; Save the original number for later
push hl
; Count the number of bits
; ((x+1)/2)
ld b, 12
add hl, hl
jr c, count_bits_cont
dec b
add hl, hl
jr c, count_bits_cont
add hl, hl
jr c, count_bits_cont
dec b
add hl, hl
jr c, count_bits_cont
add hl, hl
jr c, count_bits_cont
dec b
add hl, hl
jr c, count_bits_cont
add hl, hl
jr c, count_bits_cont
dec b
add hl, hl
jr c, count_bits_cont
add hl, hl
jr c, count_bits_cont
dec b
add hl, hl
jr c, count_bits_cont
add hl, hl
jr c, count_bits_cont
dec b
add hl, hl
jr c, count_bits_cont
add hl, hl
jr c, count_bits_cont
dec b
add hl, hl
jr c, count_bits_cont
add hl, hl
jr c, count_bits_cont
dec b
add hl, hl
jr c, count_bits_cont
add hl, hl
jr c, count_bits_cont
dec b
add hl, hl
jr c, count_bits_cont
add hl, hl
jr c, count_bits_cont
dec b
add hl, hl
jr c, count_bits_cont
add hl, hl
jr c, count_bits_cont
dec b
count_bits_cont:
; generate our guess
ld a, b
sub a, 9
; If the log is less than 9 (true log is less than 18), continue
jr c, log_less_than_8
; Else, shift the number right by 8 and the guess left by 8
ld b, a
inc sp
pop de
dec sp
ld a, e
ld hl, 256
jr nz, shift_guess
srl d
rra
srl d
rra
ld e, a
; add the guess and the shifted original number together
add.s hl, de
ei
ret
log_less_than_8:
pop de
; Because the carry flag is always set by the time we get here, this gives -1
sbc hl, hl
add hl, sp
; Shift the guess left by 1 to start
ld a, e
srl (hl)
rr d
rra
; Start our guess at 2
ld hl, 2
dec b
; If the log is 1, return
ret z
dec b
jr z, guess_cont
; 1 << b
; (2^b)
shift_guess:
; Shift our guess left and the original number right
add hl, hl
srl d
rra
dec b
jr z, guess_cont
add hl, hl
srl d
rra
dec b
jr z, guess_cont
add hl, hl
srl d
rra
dec b
jr z, guess_cont
add hl, hl
srl d
rra
dec b
jr z, guess_cont
add hl, hl
srl d
rra
dec b
jr z, guess_cont
add hl, hl
srl d
rra
guess_cont:
; Shift the original number right 2 final times
srl d
rra
srl d
rra
ld e, a
; add the guess and the shifted original number together
add.s hl, de
ei
ret
Advertisement