added fastrnd8() with the old rnd() generator code in it, new code for rnd() uses the much better rndw() generator now.

This commit is contained in:
Irmen de Jong 2021-03-05 22:49:14 +01:00
parent 6c66f86103
commit dffd0a2706
12 changed files with 44 additions and 142 deletions

View File

@ -244,8 +244,8 @@ randseed .proc
.pend
randbyte .proc
; -- 8-bit pseudo random number generator into A
fast_randbyte .proc
; -- fast but bad 8-bit pseudo random number generator into A
lda _seed
beq _eor
asl a
@ -263,6 +263,10 @@ _seed .byte $3a
.pend
randbyte .proc
; -- 8 bit pseudo random number generator into A (by just reusing randword)
jmp randword
.pend
randword .proc
; -- 16 bit pseudo random number generator into AY

View File

@ -387,6 +387,14 @@ func_sqrt16_into_A .proc
rts
.pend
func_fastrnd8_stack .proc
; -- put a random ubyte on the estack (using fast but bad RNG)
jsr math.fast_randbyte
sta P8ESTACK_LO,x
dex
rts
.pend
func_rnd_stack .proc
; -- put a random ubyte on the estack
jsr math.randbyte

View File

@ -137,6 +137,7 @@ private val functionSignatures: List<FSignature> = listOf(
FSignature("peekw" , true, listOf(FParam("address", setOf(DataType.UWORD))), DataType.UWORD),
FSignature("poke" , false, listOf(FParam("address", setOf(DataType.UWORD)), FParam("value", setOf(DataType.UBYTE))), null),
FSignature("pokew" , false, listOf(FParam("address", setOf(DataType.UWORD)), FParam("value", setOf(DataType.UWORD))), null),
FSignature("fastrnd8" , false, emptyList(), DataType.UBYTE),
FSignature("rnd" , false, emptyList(), DataType.UBYTE),
FSignature("rndw" , false, emptyList(), DataType.UWORD),
FSignature("rndf" , false, emptyList(), DataType.FLOAT),

View File

@ -56,7 +56,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
"ln", "log2", "sqrt", "rad",
"deg", "round", "floor", "ceil",
"rndf" -> funcVariousFloatFuncs(fcall, func, resultToStack, resultRegister, sscope)
"rnd", "rndw" -> funcRnd(func, resultToStack, resultRegister, sscope)
"fastrnd8", "rnd", "rndw" -> funcRnd(func, resultToStack, resultRegister, sscope)
"sqrt16" -> funcSqrt16(fcall, func, resultToStack, resultRegister, sscope)
"rol" -> funcRol(fcall)
"rol2" -> funcRol2(fcall)
@ -946,6 +946,14 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
private fun funcRnd(func: FSignature, resultToStack: Boolean, resultRegister: RegisterOrPair?, scope: Subroutine?) {
when(func.name) {
"fastrnd8" -> {
if(resultToStack)
asmgen.out(" jsr prog8_lib.func_fastrnd8_stack")
else {
asmgen.out(" jsr math.fast_randbyte")
assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, scope, program, asmgen), CpuRegister.A)
}
}
"rnd" -> {
if(resultToStack)
asmgen.out(" jsr prog8_lib.func_rnd_stack")

View File

@ -824,6 +824,9 @@ rndw()
rndf()
returns a pseudo-random float between 0.0 and 1.0
fastrnd8()
returns a pseudo-random byte from 0..255 (using a fast but not very good rng)
rol(x)
Rotate the bits in x (byte or word) one position to the left.
This uses the CPU's rotate semantics: bit 0 will be set to the current value of the Carry flag,

View File

@ -2,8 +2,6 @@
TODO
====
- optimize word multiplication if the constant multiplier is a multiple of 256
- move current rnd() to fastrnd() and add new rnd() based on the 16-bits rndw() for better results
- add more convenient number-to-string conversion routines to conv (and clean up the number printing routine in the blobs example?)
- optimize assigning array and struct variables (multi-element assings -> memcopy)

View File

@ -42,7 +42,7 @@ main {
active_height--
upwards = false
} else {
target_height = 8 + rnd() % 16
target_height = 8 + fastrnd8() % 16
if upwards
mountain = 233
else
@ -57,7 +57,7 @@ main {
txt.scroll_left(true)
; float the balloon
if rnd() & %10000
if fastrnd8() & %10000
c64.SPXY[1] ++
else
c64.SPXY[1] --
@ -71,10 +71,10 @@ main {
txt.setcc(39, yy, 160, 8) ; draw mountain
}
yy = rnd()
yy = fastrnd8()
if yy > 100 {
; draw a star
txt.setcc(39, yy % (active_height-1), '.', rnd())
txt.setcc(39, yy % (active_height-1), '.', fastrnd8())
}
if yy > 200 {
@ -85,7 +85,7 @@ main {
tree = 88
else if yy & %00100000 != 0
tree = 65
if rnd() > 130
if fastrnd8() > 130
treecolor = 13
txt.setcc(39, active_height, tree, treecolor)
}

View File

@ -24,12 +24,12 @@ main {
; Setup Starting Ball Positions
ubyte lp
for lp in 0 to ballCount-1 {
BX[lp] = rnd() % txt.DEFAULT_WIDTH
BY[lp] = rnd() % txt.DEFAULT_HEIGHT
BC[lp] = rnd() & 15
DX[lp] = rnd() & 1
DY[lp] = rnd() & 1
void rnd()
BX[lp] = fastrnd8() % txt.DEFAULT_WIDTH
BY[lp] = fastrnd8() % txt.DEFAULT_HEIGHT
BC[lp] = fastrnd8() & 15
DX[lp] = fastrnd8() & 1
DY[lp] = fastrnd8() & 1
void fastrnd8()
}
; start clock

View File

@ -14,4 +14,3 @@ main {
}
}
}

View File

@ -106,7 +106,7 @@ main {
ubyte @zp ii
for ii in 0 to 7 {
; use 16 bit rng for a bit more randomness instead of the 8-bit rng
if lsb(rndw()) > s {
if rnd() > s {
b |= bittab[ii]
}
}

View File

@ -42,7 +42,7 @@ main {
for i in 0 to 7 {
c64.SPRPTR[i] = $0a00 / 64
c64.SPXY[i*2] = 50+25*i
c64.SPXY[i*2+1] = rnd()
c64.SPXY[i*2+1] = fastrnd8()
}
c64.SPENA = 255 ; enable all sprites
@ -60,7 +60,7 @@ irq {
ubyte @zp i
for i in 0 to 14 step 2 {
c64.SPXY[i+1]--
ubyte @zp r = rnd()
ubyte @zp r = fastrnd8()
if r>200
c64.SPXY[i]++
else if r<40

View File

@ -1,128 +1,9 @@
%import textio
%zeropage basicsafe
main {
sub start() {
bench()
txt.nl()
uword total
ubyte bb
uword ww
for bb in 0 to 255 {
total = 0
repeat bb
total++
txt.print_uw(total)
txt.spc()
txt.spc()
}
txt.nl()
txt.nl()
for ww in 0 to 600 {
total = 0
repeat ww
total++
txt.print_uw(total)
txt.spc()
txt.spc()
}
}
sub iter(uword iterations) -> uword {
uword total = 0
repeat iterations {
repeat iterations {
total++
}
}
return total
}
sub iterb(ubyte iterations) -> uword {
uword total = 0
repeat iterations {
repeat iterations {
total++
}
}
return total
}
sub bench() {
uword xx1
uword xx2
uword xx3
uword iterations
xx1=0
repeat 99 {
xx1++
}
txt.print_uw(xx1) ;99
txt.nl()
xx1 = iterb(10) ; 100
txt.print_uw(xx1)
txt.nl()
xx1 = iterb(1) ; 1
txt.print_uw(xx1)
txt.nl()
xx1 = iterb(0) ; 0
txt.print_uw(xx1)
txt.nl()
txt.nl()
xx1 = iter(0)
txt.print_uw(xx1) ; 0
txt.nl()
xx1 = iter(10)
txt.print_uw(xx1) ; 100
txt.nl()
xx1 = iter(16)
txt.print_uw(xx1) ; 256
txt.nl()
xx1 = iter(20)
txt.print_uw(xx1) ; 400
txt.nl()
xx1 = iter(200)
txt.print_uw(xx1) ; 4000
txt.nl()
xx1 = iter(600)
txt.print_uw(xx1) ; 32320
txt.nl()
txt.nl()
c64.SETTIM(0,0,0)
xx1=0
xx2=0
xx3=0
iterations = 600
repeat 600 {
repeat iterations {
xx1++
xx2++
xx3++
}
}
uword time = c64.RDTIM16()
txt.print("time: ")
txt.print_uw(time)
txt.print("\n$7e40? :\n")
txt.print_uwhex(xx1,true)
txt.nl()
txt.print_uwhex(xx2,true)
txt.nl()
txt.print_uwhex(xx3,true)
txt.print("hello")
}
}