diff --git a/compiler/res/prog8lib/math.asm b/compiler/res/prog8lib/math.asm index c9c392591..0dd35743d 100644 --- a/compiler/res/prog8lib/math.asm +++ b/compiler/res/prog8lib/math.asm @@ -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 diff --git a/compiler/res/prog8lib/prog8_funcs.asm b/compiler/res/prog8lib/prog8_funcs.asm index 4848a069b..f69a2ccc2 100644 --- a/compiler/res/prog8lib/prog8_funcs.asm +++ b/compiler/res/prog8lib/prog8_funcs.asm @@ -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 diff --git a/compiler/src/prog8/compiler/functions/BuiltinFunctions.kt b/compiler/src/prog8/compiler/functions/BuiltinFunctions.kt index f35d80bdc..08e6571bb 100644 --- a/compiler/src/prog8/compiler/functions/BuiltinFunctions.kt +++ b/compiler/src/prog8/compiler/functions/BuiltinFunctions.kt @@ -137,6 +137,7 @@ private val functionSignatures: List = 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), diff --git a/compiler/src/prog8/compiler/target/cpu6502/codegen/BuiltinFunctionsAsmGen.kt b/compiler/src/prog8/compiler/target/cpu6502/codegen/BuiltinFunctionsAsmGen.kt index 6bd1746f0..00639817a 100644 --- a/compiler/src/prog8/compiler/target/cpu6502/codegen/BuiltinFunctionsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/cpu6502/codegen/BuiltinFunctionsAsmGen.kt @@ -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") diff --git a/docs/source/programming.rst b/docs/source/programming.rst index dd4218372..d316c580c 100644 --- a/docs/source/programming.rst +++ b/docs/source/programming.rst @@ -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, diff --git a/docs/source/todo.rst b/docs/source/todo.rst index e61b57b4b..ff32ee631 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -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) diff --git a/examples/balloonflight.p8 b/examples/balloonflight.p8 index 1b7fe3a5d..d8fd8fd0a 100644 --- a/examples/balloonflight.p8 +++ b/examples/balloonflight.p8 @@ -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) } diff --git a/examples/balls.p8 b/examples/balls.p8 index fc0cfb23a..e56e91fac 100644 --- a/examples/balls.p8 +++ b/examples/balls.p8 @@ -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 diff --git a/examples/cxlogo.p8 b/examples/cxlogo.p8 index b5a173cff..037842e38 100644 --- a/examples/cxlogo.p8 +++ b/examples/cxlogo.p8 @@ -14,4 +14,3 @@ main { } } } - diff --git a/examples/plasma.p8 b/examples/plasma.p8 index 3f719b826..9c1eaf37e 100644 --- a/examples/plasma.p8 +++ b/examples/plasma.p8 @@ -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] } } diff --git a/examples/sprites.p8 b/examples/sprites.p8 index 938204527..442835ac1 100644 --- a/examples/sprites.p8 +++ b/examples/sprites.p8 @@ -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 diff --git a/examples/test.p8 b/examples/test.p8 index 4fe9069d4..e8fb68db4 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -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") } }