Page 1 of 1
ive got this plot routine and want to instert a random number generator into it
Posted: Tue Aug 16, 2022 12:38 pm
by 777
ive tried using this routine but the plot routine uses the d and e registers to plot on the screen. ive also tried to adapt it to no avail
random number generator
Code: Select all
add hl,hl
sbc a,a
and %00101101
xor l
ld l,a
ld a,r
add a,h
plot routine
Code: Select all
LD D,C
; D = X and E = Y
PLOT:
ld a,7
and d
ld b,a
inc b
ld a,e
rra
scf
rra
or a
rra
ld l,a
xor e
and 248
xor e
ld h,a
ld a,d
xor l
and 7
xor d
rrca
rrca
rrca
ld l,a
ld a,1 ; one
PLOTBIT:
rrca
djnz PLOTBIT
or (hl)
ld (hl),a
RET
i realise i probably will have to have 2 of the random number generator routines, to affect the d and e registers
any help would be appreciated as always
Re: ive got this plot routine and want to instert a random number generator into it
Posted: Tue Aug 16, 2022 4:09 pm
by Joefish
Take a look at the top random number generator on this page:
https://wikiti.brandonw.net/index.php?t ... ath:Random
There
randData is a label denoting a place in memory for temporarily storing the
seed value of the random number generator from one call to the next. If you're not doing that, then your random number generator won't work properly.
You can just add a line like:
randData dw 9999
After the routine and it'll save the number there each time. That defines the space for a word (a 16-bit number) and initially sets it to value 9999. This is how 'variables' work in machine code. You define some memory addresses, or set labels to point to just empty bytes in memory (e.g.
my_var_x db 0), then you store values there with
LD (my_var_x),A when you're no longer processing those numbers and don't need them held in registers, then retrieve them again with
LD A,(my_var_x) when you do.
Note also how it
PUSHes the registers it's going to use onto the stack before it does anything, then
POPs them back afterwards, to restore them to what they were. The only thing it changes is AF, and really, just the register A comes back with the random number in it.
What you need to do is CALL a routine like this then when it returns copy A into D, then call it again and copy A into E, then call the plot routine.
Re: ive got this plot routine and want to instert a random number generator into it
Posted: Tue Aug 16, 2022 6:54 pm
by RMartins
777 wrote: ↑Tue Aug 16, 2022 12:38 pm
...
plot routine
Code: Select all
LD D,C
; D = X and E = Y
PLOT:
ld a,7
and d
ld b,a
inc b
ld a,e
rra
scf
rra
or a
rra
ld l,a
xor e
and 248
xor e
ld h,a
ld a,d
xor l
and 7
xor d
rrca
rrca
rrca
ld l,a
ld a,1 ; one
PLOTBIT:
rrca
djnz PLOTBIT
or (hl)
ld (hl),a
RET
Are you sure that plot routine even works ?
Looking at it, at first glance, it doesn't seem like it will work. NOTE: Assuming X and Y are in pixels.
Have you tried to plot a pixel at a fixed value first ?
Re: ive got this plot routine and want to instert a random number generator into it
Posted: Wed Aug 17, 2022 1:34 am
by 777
yeah, it works. and yes ive tried that
its missing ld d,(x coordinate)
and ld e,(y coordinate) at the beginning of the code
* maybe i need to learn to spell insert properly... lol...
Re: ive got this plot routine and want to instert a random number generator into it
Posted: Wed Aug 17, 2022 2:08 am
by 777
Joefish wrote: ↑Tue Aug 16, 2022 4:09 pm
Take a look at the top random number generator on this page:
https://wikiti.brandonw.net/index.php?t ... ath:Random
There
randData is a label denoting a place in memory for temporarily storing the
seed value of the random number generator from one call to the next. If you're not doing that, then your random number generator won't work properly.
You can just add a line like:
randData dw 9999
After the routine and it'll save the number there each time. That defines the space for a word (a 16-bit number) and initially sets it to value 9999. This is how 'variables' work in machine code. You define some memory addresses, or set labels to point to just empty bytes in memory (e.g.
my_var_x db 0), then you store values there with
LD (my_var_x),A when you're no longer processing those numbers and don't need them held in registers, then retrieve them again with
LD A,(my_var_x) when you do.
Note also how it
PUSHes the registers it's going to use onto the stack before it does anything, then
POPs them back afterwards, to restore them to what they were. The only thing it changes is AF, and really, just the register A comes back with the random number in it.
What you need to do is CALL a routine like this then when it returns copy A into D, then call it again and copy A into E, then call the plot routine.
ok, this works, sort of. but i need a number from 0 to 191 for the y register. or it starts printing color attributes to the screen...
Code: Select all
org 40000
LD D,C
randData dw 9999
random:
push hl
push de
ld hl,(randData)
ld a,r
ld d,a
ld e,(hl)
add hl,de
add a,l
xor h
ld (randData),hl
pop de
pop hl
ld d,a
random2:
push hl
push de
ld hl,(randData)
ld a,r
ld d,a
ld e,(hl)
add hl,de
add a,l
xor h
ld (randData),hl
pop de
pop hl
ld e,a
; D = X and E = Y
PLOT:
ld a,7
and d
ld b,a
inc b
ld a,e
rra
scf
rra
or a
rra
ld l,a
xor e
and 248
xor e
ld h,a
ld a,d
xor l
and 7
xor d
rrca
rrca
rrca
ld l,a
ld a,1 ; one
PLOTBIT:
rrca
djnz PLOTBIT
or (hl)
ld (hl),a
jr random
Re: ive got this plot routine and want to instert a random number generator into it
Posted: Wed Aug 17, 2022 10:51 am
by 777
ok, so now i managed to divide the number by 2. unfortunately it only fills 128 pixels of the screen
Code: Select all
org 40000
LD D,C
randData dw 9999
random:
push hl
push de
ld hl,(randData)
ld a,r
ld d,a
ld e,(hl)
add hl,de
add a,l
xor h
ld (randData),hl
pop de
pop hl
ld d,a
random2:
push hl
push de
ld hl,(randData)
ld a,r
ld d,a
ld e,(hl)
add hl,de
add a,l
xor h
ld (randData),hl
pop de
pop hl
and %11111110
rrca
ld e,a
; D = X and E = Y
PLOT:
ld a,7
and d
ld b,a
inc b
ld a,e
rra
scf
rra
or a
rra
ld l,a
xor e
and 248
xor e
ld h,a
ld a,d
xor l
and 7
xor d
rrca
rrca
rrca
ld l,a
ld a,1 ; one
PLOTBIT:
rrca
djnz PLOTBIT
or (hl)
ld (hl),a
jr random
Re: ive got this plot routine and want to instert a random number generator into it
Posted: Wed Aug 17, 2022 11:01 am
by AndyC
The easiest way is to compare the number against 192 and just jump back to the random number generation of it exceeds it.
Re: ive got this plot routine and want to instert a random number generator into it
Posted: Wed Aug 17, 2022 11:13 am
by 777
AndyC wrote: ↑Wed Aug 17, 2022 11:01 am
The easiest way is to compare the number against 192 and just jump back to the random number generation of it exceeds it.
cool, thanks
Re: ive got this plot routine and want to instert a random number generator into it
Posted: Wed Aug 17, 2022 11:23 am
by 777
ok, ive got
cp 192
jp nc, random2
Re: ive got this plot routine and want to instert a random number generator into it
Posted: Wed Aug 17, 2022 11:45 am
by Pobulous
Another way to get a random number between 0 and 191 would be to get 2 random numbers, AND one of them with 127, AND the other one with 63 and then add them together. That will always take a predictable amount of time. In theory, depending on how random your routine is, you could end up with a long string of numbers > 191, causing a long delay.
Re: ive got this plot routine and want to instert a random number generator into it
Posted: Wed Aug 17, 2022 11:47 am
by 777
AndyC wrote: ↑Wed Aug 17, 2022 11:01 am
The easiest way is to compare the number against 192 and just jump back to the random number generation of it exceeds it.
just one more thing. how do i get it to 'over 1', instead of 'over 0' each pixel? would i use xor of something like that?
Re: ive got this plot routine and want to instert a random number generator into it
Posted: Wed Aug 17, 2022 12:02 pm
by Joefish
Yes, xor (hl) at the end instead of or.
Yep, the 4:3 screen ratio might be pleasing on the eye but that factor of 3 can be a pain in the bum sometimes for maths. As you've found, it'd be relatively easy to have a 256x128 pixel window as then it's a 2:1 ratio which is a doddle to handle with binary maths.
And you'll find an awful lot of games out there where they do exactly that, with a great big 8-character high scoreboard at the bottom of the screen.
The alternative to re-running the random number generator is a little check at the start of your plot routine that says if Y>191 then just return straight away. This sort of 'defensive' programming doesn't make a lot of difference when plotting, but if you were printing characters, for example, it's always good to check the co-ordinates are on-screen first!
Re: ive got this plot routine and want to instert a random number generator into it
Posted: Wed Aug 17, 2022 12:05 pm
by AndyC
Pobulous wrote: ↑Wed Aug 17, 2022 11:45 am
Another way to get a random number between 0 and 191 would be to get 2 random numbers, AND one of them with 127, AND the other one with 63 and then add them together. That will always take a predictable amount of time. In theory, depending on how random your routine is, you could end up with a long string of numbers > 191, causing a long delay.
The trouble with adding random numbers together like that is that it may skew the overall distribution of random numbers. That may or may not matter, but you might start to see more predictable patterns as a result. Re-picking a random number should avoid that and, if your random number generator has a good distribution in the first place, shouldn't require too many attempts. Obviously sometimes being constant time can win out over having "better" random numbers.
Re: ive got this plot routine and want to instert a random number generator into it
Posted: Wed Aug 17, 2022 12:07 pm
by AndyC
777 wrote: ↑Wed Aug 17, 2022 11:47 am
just one more thing. how do i get it to 'over 1', instead of 'over 0' each pixel? would i use xor of something like that?
Yes XOR is the way to go, may depend on how your PLOT routine works of course.
Re: ive got this plot routine and want to instert a random number generator into it
Posted: Wed Aug 17, 2022 2:41 pm
by Pobulous
AndyC wrote: ↑Wed Aug 17, 2022 12:05 pm
The trouble with adding random numbers together like that is that it may skew the overall distribution of random numbers. That may or may not matter, but you might start to see more predictable patterns as a result. Re-picking a random number should avoid that and, if your random number generator has a good distribution in the first place, shouldn't require too many attempts. Obviously sometimes being constant time can win out over having "better" random numbers.
You're right - I missed that. I was thinking that a *truly* random function could at some point generate a very long sequence of large numbers, but a pseudo-random function would actually never do that anyway.
Re: ive got this plot routine and want to instert a random number generator into it
Posted: Thu Aug 18, 2022 7:46 am
by Dr beep
loop
sub 192
jr nc,loop
add a,192
Re: ive got this plot routine and want to instert a random number generator into it
Posted: Thu Aug 18, 2022 7:59 am
by AndyC
Again, it "works" if speed is critical but it messes up the distribution of numbers so your "random" number routine will tend to generate some numbers more often than others. This may or may not matter, depending upon what you're trying to do.
Re: ive got this plot routine and want to instert a random number generator into it
Posted: Fri Aug 26, 2022 10:26 am
by Pobulous
Revisiting how to reduce the random 8 bit number to a 0-191 range.
I first looked at:
20 LET Y=INT(RND*256)
30 IF Y>256 THEN LET Y=Y-256: REM this step won't be needed in ASM
40 IF Y>191 THEN LET Y=Y-192: LET Y=Y*3
I found that there were very pronounced lines every 3rd row
Like this, though, and they disappeared
10 LET Y=0
20 LET Y=Y+INT(RND*256)
25 LET R=INT(RND*175)
30 IF Y>256 THEN LET Y=Y-256: REM this step won't be needed in ASM
40 IF Y>191 THEN LET Y=Y-192: LET Y=Y*3
50 PLOT R,Y: REM as BASIC doesn't handle 192 rows of pixels, I've rotated the output
100 GOTO 20
In ASM I have:
Code: Select all
UpdateXY:
ld bc,(Ypos)
call random ;random (0-256) in a
add a,b
ld (Xpos),a
call random ;random (0-256) in a
add a,c
cp 191
jr nc, validY
sub 192 ;random (0-63)
ld b,a
add a,b
add a,b ;random (0-189)
validY:
ld (Ypos),a
call plot
jp UpdateXY
Ypos: db 0
Xpos: db 0
RandData: dw 9999
random:
ld hl,(randData)
ld a,r
ld d,a
ld e,(hl)
add hl,de
add a,l
xor h
ld (randData),hl
ret
Re: ive got this plot routine and want to instert a random number generator into it
Posted: Fri Aug 26, 2022 4:59 pm
by Pobulous
OK, I didn't test the code as I hadn't integrated a plot routine. It had some bugs! Here it is with a plot routine.
Assemble it, create and run this BASIC program:
1 BORDER 7: CLS: BORDER 1
10 RANDOMIZE USR 32768: GOTO 10
crank your emulator speed up
I think that gets pretty even coverage despite using a weak RND function, and a very quick and dirty correction of the values over 191.
Adding LSb of R after 3*(Y-192) might be another improvement.
The plot code is simplified version of the ROM routine.
Code: Select all
org 32768
UpdateXY:
ld bc,(Xpos)
call random ;random (0-256) in a
add a,c
ld (Xpos),a
call random ;random (0-256) in a
add a,b
cp 192
jr c, validY
sub 192 ;random (0-63)
ld b,a
add a,b
add a,b ;random (0-189)
validY:
ld (Ypos),a
ld bc,(Xpos)
call plotpoint
ret
Xpos:
db 0
Ypos:
db 0
RandData:
dw 9999
random:
ld hl,(randData)
ld a,r
ld d,a
ld e,(hl)
add hl,de
add a,l
xor h
ld (randData),hl
ret
plotpoint: ;y=0 is top of screen
ld a,b
and a
rra
scf
rra
and a
rra
xor b
and 248
xor b
ld h,a
ld a,c
rlca
rlca
rlca
xor b
and 199
xor b
rlca
rlca
ld l,a
ld a,c
and 7
;HL=display address, A=pixel offset in byte
ld b,a
ld a,128 ;set pixel and shift to correct place
plotloop:
rrca
djnz plotloop
or (hl) ;write pixel to screen
ld (hl),a
ret