view release on metacpan or search on metacpan
t/data/zx48.asm view on Meta::CPAN
; "Goe not Thou about to Square eyther circle" -
; - John Donne, Cambridge educated theologian, 1624
;
; The CIRCLE command draws a circle as a series of straight lines.
; In some ways it can be regarded as a polygon, but the first line is drawn
; as a tangent, taking the radius as its distance from the centre.
;
; Both the CIRCLE algorithm and the ARC drawing algorithm make use of the
; 'ROTATION FORMULA' (see later). It is only necessary to work out where
; the first line will be drawn and how long it is and then the rotation
; formula takes over and calculates all other rotated points.
;
; All Spectrum circles consist of two vertical lines at each side and two
; horizontal lines at the top and bottom. The number of lines is calculated
; from the radius of the circle and is always divisible by 4. For complete
; circles it will range from 4 for a square circle to 32 for a circle of
; radius 87. The Spectrum can attempt larger circles e.g. CIRCLE 0,14,255
; but these will error as they go off-screen after four lines are drawn.
; At the opposite end, CIRCLE 128,88,1.23 will draw a circle as a perfect 3x3
; square using 4 straight lines although very small circles are just drawn as
; a dot on the screen.
t/data/zx48.asm view on Meta::CPAN
DEFB $E1 ;;get-mem-1 x, y, y, f
DEFB $04 ;;multiply x, y, y*f (=yy)
; Note. 'sin' and 'cos' trash locations mem-0 to mem-2 so fetch mem-2 to the
; calculator stack for safe keeping.
DEFB $E2 ;;get-mem-2 x, y, yy, xx.
; Once we get the coordinates of the first straight line then the 'ROTATION
; FORMULA' used in the arc loop will take care of all other points, but we
; now use a variation of that formula to rotate the first arc through (A-a)/2
; radians.
;
; xRotated = y * sin(angle) + x * cos(angle)
; yRotated = y * cos(angle) - x * sin(angle)
;
DEFB $E5 ;;get-mem-5 x, y, yy, xx, A.
DEFB $E0 ;;get-mem-0 x, y, yy, xx, A, a.
DEFB $03 ;;subtract x, y, yy, xx, A-a.
DEFB $A2 ;;stk-half x, y, yy, xx, A-a, 1/2.
t/data/zx48.asm view on Meta::CPAN
;
; Xrotated = x * cos(a) - y * sin(a)
; Yrotated = x * sin(a) + y * cos(a)
;
; The values cos(a) and sin(a) are pre-calculated and held in mem-3 and mem-4
; for the duration of the routine.
; Memory location mem-1 holds the last relative x value (rx) and mem-2 holds
; the last relative y value (ry) used by DRAW.
;
; Note. that this is a very clever twist on what is after all a very clever,
; well-used formula. Normally the rotation formula is used with the x and y
; coordinates from the centre of the circle (or arc) and a supplied angle to
; produce two new x and y coordinates in an anticlockwise direction on the
; circumference of the circle.
; What is being used here, instead, is the relative X and Y parameters from
; the last point plotted that are required to get to the current point and
; the formula returns the next relative coordinates to use.
;; ARC-LOOP
L2425: RST 28H ;; FP-CALC
DEFB $E1 ;;get-mem-1 rx.
DEFB $31 ;;duplicate rx, rx.
DEFB $E3 ;;get-mem-3 cos(a)
DEFB $04 ;;multiply rx, rx*cos(a).
DEFB $E2 ;;get-mem-2 rx, rx*cos(a), ry.
DEFB $E4 ;;get-mem-4 rx, rx*cos(a), ry, sin(a).
DEFB $04 ;;multiply rx, rx*cos(a), ry*sin(a).
t/data/zx48.asm view on Meta::CPAN
; The radius/diameter is left on the calculator stack.
POP BC ; Restore the line count to the B register.
RET ; Return.
; --------------------------
; THE 'DOUBLE ANGLE FORMULA'
; --------------------------
; This formula forms cos(a) from sin(a/2) using simple arithmetic.
;
; THE GEOMETRIC PROOF OF FORMULA cos (a) = 1 - 2 * sin(a/2) * sin(a/2)
;
;
; A
;
; . /|\
; . / | \
; . / | \
; . / |a/2\
t/data/zx48.asm view on Meta::CPAN
; residue mod p.
;
; In the case when p = 65537, we can show that d is a primitive root if and
; only if it's not a quadratic residue. For let w be a primitive root, d
; congruent to w^r (mod p). If d is not primitive, then its order is a proper
; factor of 65536: hence w^{32768*r} = 1 (mod p), so 65536 divides 32768*r,
; and hence r is even and d is a square (mod p). Conversely, the squares in
; Fp* form a subgroup of (Fp*)^2 of index 2, and so cannot be generators.
;
; Hence to check whether 75 is primitive mod 65537, we want to calculate that
; (75/65537) = -1. There is a multiplicative formula (ab/p) = (a/p)(b/p) (mod
; p), so (75/65537) = (5/65537)^2 * (3/65537) = (3/65537). Now the law of
; quadratic reciprocity says that if p and q are distinct odd primes, then
;
; (p/q)(q/p) = (-1)^{(p-1)(q-1)/4}
;
; Hence (3/65537) = (65537/3) * (-1)^{65536*2/4} = (65537/3)
; = (2/3) (because 65537 = 2 mod 3)
; = -1
;
; (I referred to Pierre Samuel's "Algebraic Theory of Numbers".)
t/data/zx48.asm view on Meta::CPAN
RET ; return.
; ---------------------
; THE 'ARCSIN' FUNCTION
; ---------------------
; (Offset $22: 'asn')
; The inverse sine function with result in radians.
; Derived from arctan function above.
; Error A unless the argument is between -1 and +1 inclusive.
; Uses an adaptation of the formula asn(x) = atn(x/sqr(1-x*x))
;
;
; /|
; / |
; 1/ |x
; /a |
; /----|
; y
;
; e.g. We know the opposite side (x) and hypotenuse (1)
t/data/zx48_base.asm view on Meta::CPAN
; "Goe not Thou about to Square eyther circle" -
; - John Donne, Cambridge educated theologian, 1624
;
; The CIRCLE command draws a circle as a series of straight lines.
; In some ways it can be regarded as a polygon, but the first line is drawn
; as a tangent, taking the radius as its distance from the centre.
;
; Both the CIRCLE algorithm and the ARC drawing algorithm make use of the
; 'ROTATION FORMULA' (see later). It is only necessary to work out where
; the first line will be drawn and how long it is and then the rotation
; formula takes over and calculates all other rotated points.
;
; All Spectrum circles consist of two vertical lines at each side and two
; horizontal lines at the top and bottom. The number of lines is calculated
; from the radius of the circle and is always divisible by 4. For complete
; circles it will range from 4 for a square circle to 32 for a circle of
; radius 87. The Spectrum can attempt larger circles e.g. CIRCLE 0,14,255
; but these will error as they go off-screen after four lines are drawn.
; At the opposite end, CIRCLE 128,88,1.23 will draw a circle as a perfect 3x3
; square using 4 straight lines although very small circles are just drawn as
; a dot on the screen.
t/data/zx48_base.asm view on Meta::CPAN
defb 0xE1 ; ;get-mem-1 x, y, y, f
defb 0x04 ; ;multiply x, y, y*f (=yy)
; Note. 'sin' and 'cos' trash locations mem-0 to mem-2 so fetch mem-2 to the
; calculator stack for safe keeping.
defb 0xE2 ; ;get-mem-2 x, y, yy, xx.
; Once we get the coordinates of the first straight line then the 'ROTATION
; FORMULA' used in the arc loop will take care of all other points, but we
; now use a variation of that formula to rotate the first arc through (A-a)/2
; radians.
;
; xRotated = y * sin(angle) + x * cos(angle)
; yRotated = y * cos(angle) - x * sin(angle)
;
defb 0xE5 ; ;get-mem-5 x, y, yy, xx, A.
defb 0xE0 ; ;get-mem-0 x, y, yy, xx, A, a.
defb 0x03 ; ;subtract x, y, yy, xx, A-a.
defb 0xA2 ; ;stk-half x, y, yy, xx, A-a, 1/2.
t/data/zx48_base.asm view on Meta::CPAN
;
; Xrotated = x * cos(a) - y * sin(a)
; Yrotated = x * sin(a) + y * cos(a)
;
; The values cos(a) and sin(a) are pre-calculated and held in mem-3 and mem-4
; for the duration of the routine.
; Memory location mem-1 holds the last relative x value (rx) and mem-2 holds
; the last relative y value (ry) used by DRAW.
;
; Note. that this is a very clever twist on what is after all a very clever,
; well-used formula. Normally the rotation formula is used with the x and y
; coordinates from the centre of the circle (or arc) and a supplied angle to
; produce two new x and y coordinates in an anticlockwise direction on the
; circumference of the circle.
; What is being used here, instead, is the relative X and Y parameters from
; the last point plotted that are required to get to the current point and
; the formula returns the next relative coordinates to use.
;; ARC-LOOP
ARC_LOOP:
rst 0x28 ; ; FP-CALC
defb 0xE1 ; ;get-mem-1 rx.
defb 0x31 ; ;duplicate rx, rx.
defb 0xE3 ; ;get-mem-3 cos(a)
defb 0x04 ; ;multiply rx, rx*cos(a).
defb 0xE2 ; ;get-mem-2 rx, rx*cos(a), ry.
defb 0xE4 ; ;get-mem-4 rx, rx*cos(a), ry, sin(a).
t/data/zx48_base.asm view on Meta::CPAN
; The radius/diameter is left on the calculator stack.
pop bc ; Restore the line count to the B register.
ret ; Return.
; --------------------------
; THE 'DOUBLE ANGLE FORMULA'
; --------------------------
; This formula forms cos(a) from sin(a/2) using simple arithmetic.
;
; THE GEOMETRIC PROOF OF FORMULA cos (a) = 1 - 2 * sin(a/2) * sin(a/2)
;
;
; A
;
; . /|\
; . / | \
; . / | \
; . / |a/2\
t/data/zx48_base.asm view on Meta::CPAN
; residue mod p.
;
; In the case when p = 65537, we can show that d is a primitive root if and
; only if it's not a quadratic residue. For let w be a primitive root, d
; congruent to w^r (mod p). If d is not primitive, then its order is a proper
; factor of 65536: hence w^{32768*r} = 1 (mod p), so 65536 divides 32768*r,
; and hence r is even and d is a square (mod p). Conversely, the squares in
; Fp* form a subgroup of (Fp*)^2 of index 2, and so cannot be generators.
;
; Hence to check whether 75 is primitive mod 65537, we want to calculate that
; (75/65537) = -1. There is a multiplicative formula (ab/p) = (a/p)(b/p) (mod
; p), so (75/65537) = (5/65537)^2 * (3/65537) = (3/65537). Now the law of
; quadratic reciprocity says that if p and q are distinct odd primes, then
;
; (p/q)(q/p) = (-1)^{(p-1)(q-1)/4}
;
; Hence (3/65537) = (65537/3) * (-1)^{65536*2/4} = (65537/3)
; = (2/3) (because 65537 = 2 mod 3)
; = -1
;
; (I referred to Pierre Samuel's "Algebraic Theory of Numbers".)
t/data/zx48_base.asm view on Meta::CPAN
ret ; return.
; ---------------------
; THE 'ARCSIN' FUNCTION
; ---------------------
; (Offset $22: 'asn')
; The inverse sine function with result in radians.
; Derived from arctan function above.
; Error A unless the argument is between -1 and +1 inclusive.
; Uses an adaptation of the formula asn(x) = atn(x/sqr(1-x*x))
;
;
; /|
; / |
; 1/ |x
; /a |
; /----|
; y
;
; e.g. We know the opposite side (x) and hypotenuse (1)
t/data/zx48_benchmark.asm view on Meta::CPAN
; "Goe not Thou about to Square eyther circle" -
; - John Donne, Cambridge educated theologian, 1624
;
; The CIRCLE command draws a circle as a series of straight lines.
; In some ways it can be regarded as a polygon, but the first line is drawn
; as a tangent, taking the radius as its distance from the centre.
;
; Both the CIRCLE algorithm and the ARC drawing algorithm make use of the
; 'ROTATION FORMULA' (see later). It is only necessary to work out where
; the first line will be drawn and how long it is and then the rotation
; formula takes over and calculates all other rotated points.
;
; All Spectrum circles consist of two vertical lines at each side and two
; horizontal lines at the top and bottom. The number of lines is calculated
; from the radius of the circle and is always divisible by 4. For complete
; circles it will range from 4 for a square circle to 32 for a circle of
; radius 87. The Spectrum can attempt larger circles e.g. CIRCLE 0,14,255
; but these will error as they go off-screen after four lines are drawn.
; At the opposite end, CIRCLE 128,88,1.23 will draw a circle as a perfect 3x3
; square using 4 straight lines although very small circles are just drawn as
; a dot on the screen.
t/data/zx48_benchmark.asm view on Meta::CPAN
defb $E1 ; ;get-mem-1 x, y, y, f
defb $04 ; ;multiply x, y, y*f (=yy)
; Note. 'sin' and 'cos' trash locations mem-0 to mem-2 so fetch mem-2 to the
; calculator stack for safe keeping.
defb $E2 ; ;get-mem-2 x, y, yy, xx.
; Once we get the coordinates of the first straight line then the 'ROTATION
; FORMULA' used in the arc loop will take care of all other points, but we
; now use a variation of that formula to rotate the first arc through (A-a)/2
; radians.
;
; xRotated = y * sin(angle) + x * cos(angle)
; yRotated = y * cos(angle) - x * sin(angle)
;
defb $E5 ; ;get-mem-5 x, y, yy, xx, A.
defb $E0 ; ;get-mem-0 x, y, yy, xx, A, a.
defb $03 ; ;subtract x, y, yy, xx, A-a.
defb $A2 ; ;stk-half x, y, yy, xx, A-a, 1/2.
t/data/zx48_benchmark.asm view on Meta::CPAN
;
; Xrotated = x * cos(a) - y * sin(a)
; Yrotated = x * sin(a) + y * cos(a)
;
; The values cos(a) and sin(a) are pre-calculated and held in mem-3 and mem-4
; for the duration of the routine.
; Memory location mem-1 holds the last relative x value (rx) and mem-2 holds
; the last relative y value (ry) used by DRAW.
;
; Note. that this is a very clever twist on what is after all a very clever,
; well-used formula. Normally the rotation formula is used with the x and y
; coordinates from the centre of the circle (or arc) and a supplied angle to
; produce two new x and y coordinates in an anticlockwise direction on the
; circumference of the circle.
; What is being used here, instead, is the relative X and Y parameters from
; the last point plotted that are required to get to the current point and
; the formula returns the next relative coordinates to use.
;; ARC-LOOP
ARC_LOOP:
rst $28 ; ; FP-CALC
defb $E1 ; ;get-mem-1 rx.
defb $31 ; ;duplicate rx, rx.
defb $E3 ; ;get-mem-3 cos(a)
defb $04 ; ;multiply rx, rx*cos(a).
defb $E2 ; ;get-mem-2 rx, rx*cos(a), ry.
t/data/zx48_benchmark.asm view on Meta::CPAN
; The radius/diameter is left on the calculator stack.
pop bc ; Restore the line count to the B register.
ret ; Return.
; --------------------------
; THE 'DOUBLE ANGLE FORMULA'
; --------------------------
; This formula forms cos(a) from sin(a/2) using simple arithmetic.
;
; THE GEOMETRIC PROOF OF FORMULA cos (a) = 1 - 2 * sin(a/2) * sin(a/2)
;
;
; A
;
; . /|\
; . / | \
; . / | \
; . / |a/2\
t/data/zx48_benchmark.asm view on Meta::CPAN
; residue mod p.
;
; In the case when p = 65537, we can show that d is a primitive root if and
; only if it's not a quadratic residue. For let w be a primitive root, d
; congruent to w^r (mod p). If d is not primitive, then its order is a proper
; factor of 65536: hence w^{32768*r} = 1 (mod p), so 65536 divides 32768*r,
; and hence r is even and d is a square (mod p). Conversely, the squares in
; Fp* form a subgroup of (Fp*)^2 of index 2, and so cannot be generators.
;
; Hence to check whether 75 is primitive mod 65537, we want to calculate that
; (75/65537) = -1. There is a multiplicative formula (ab/p) = (a/p)(b/p) (mod
; p), so (75/65537) = (5/65537)^2 * (3/65537) = (3/65537). Now the law of
; quadratic reciprocity says that if p and q are distinct odd primes, then
;
; (p/q)(q/p) = (-1)^{(p-1)(q-1)/4}
;
; Hence (3/65537) = (65537/3) * (-1)^{65536*2/4} = (65537/3)
; = (2/3) (because 65537 = 2 mod 3)
; = -1
;
; (I referred to Pierre Samuel's "Algebraic Theory of Numbers".)
t/data/zx48_benchmark.asm view on Meta::CPAN
; ---------------------
; THE 'ARCSIN' FUNCTION
; ---------------------
; (Offset $22: 'asn')
; The inverse sine function with result in radians.
; Derived from arctan function above.
; Error A unless the argument is between -1 and +1 inclusive.
; Uses an adaptation of the formula asn(x) = atn(x/sqr(1-x*x))
;
;
; /|
; / |
; 1/ |x
; /a |
; /----|
; y
;
; e.g. We know the opposite side (x) and hypotenuse (1)
t/data/zx81.asm view on Meta::CPAN
;
;
; ---------------------
; THE 'ARCSIN' FUNCTION
; ---------------------
; (Offset $1F: 'asn')
; The inverse sine function with result in radians.
; Derived from arctan function above.
; Error A unless the argument is between -1 and +1 inclusive.
; Uses an adaptation of the formula asn(x) = atn(x/sqr(1-x*x))
;
;
; /|
; / |
; 1/ |x
; /a |
; /----|
; y
;
; e.g. We know the opposite side (x) and hypotenuse (1)
t/data/zx81.ctl view on Meta::CPAN
:;
1DC4:C
:#; ---------------------
:#; THE 'ARCSIN' FUNCTION
:#; ---------------------
:#; (Offset $1F: 'asn')
:#; The inverse sine function with result in radians.
:#; Derived from arctan function above.
:#; Error A unless the argument is between -1 and +1 inclusive.
:#; Uses an adaptation of the formula asn(x) = atn(x/sqr(1-x*x))
:#;
:#;
:#; /|
:#; / |
:#; 1/ |x
:#; /a |
:#; /----|
:#; y
:#;
:#; e.g. We know the opposite side (x) and hypotenuse (1)
t/data/zx81_version_2_rom_source.asm view on Meta::CPAN
RET ; return.
; ---------------------
; THE 'ARCSIN' FUNCTION
; ---------------------
; (Offset $1F: 'asn')
; The inverse sine function with result in radians.
; Derived from arctan function above.
; Error A unless the argument is between -1 and +1 inclusive.
; Uses an adaptation of the formula asn(x) = atn(x/sqr(1-x*x))
;
;
; /|
; / |
; 1/ |x
; /a |
; /----|
; y
;
; e.g. We know the opposite side (x) and hypotenuse (1)