News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu
avatar_AMSDOS

Testing those Assembly 8bit Random Number Generators

Started by AMSDOS, 12:36, 07 November 15

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

AMSDOS

I have put together a series of Assembly programs along with their outputs. The results are stunning, though my original BASIC program is still able to produce a more random pattern compared to the results you will see.




   org &4000


.mode      equ &bc0e
.border      equ &bc38
.inks      equ &bc32
.plot      equ &bbea
.grapen      equ &bbde
.keywait   equ &bb18


   call setup
.loop
   call rnd
   call sht4
   ld a,(rslt)
   call grapen


   ld hl,(xp)
   ex hl,de
   ld hl,(yp)
   call plot
   
   ld hl,(xp)
   inc hl
   inc hl
   inc hl
   inc hl
   ld (xp),hl


   ld hl,(checkx)
   ex hl,de
   ld hl,(xp)
   and a
   sbc hl,de   
   jr nz,loop


   ld hl,0
   ld (xp),hl


   ld hl,(yp)
   dec hl
   dec hl
   ld (yp),hl


   ld hl,(checky)
   ex hl,de
   ld hl,(yp)
   and a
   sbc hl,de
   jr nz,loop
   
   call keywait


   ret
   


.rnd
   ld a,(seed)
   ld b,a
   add a,a
   add a,a
   add a,b
   inc a
   ld (seed),a
   ret


.sht4
   srl a
   srl a
   srl a
   srl a
   inc a
   ld (rslt),a
   ret


.setup   xor a
   call mode
   ld a,14
   ld c,9
   ld b,c
   call inks
   ld a,15
   ld c,11
   ld b,c
   call inks
   ld c,26
   ld b,c
   call border
   ret


.xp   defw 0
.yp   defw 398
.seed   defb 0
.rslt   defb 0
.xcount   defw 0
.checkx   defw 640
.checky   defw 0



Output:
[attachimg=1]




   org &4000


.mode      equ &bc0e
.border      equ &bc38
.inks      equ &bc32
.plot      equ &bbea
.grapen      equ &bbde
.keywait   equ &bb18


   call setup
.loop
   call rnd
   call sht4
   ld a,(rslt)
   call grapen


   ld hl,(xp)
   ex hl,de
   ld hl,(yp)
   call plot
   
   ld hl,(xp)
   inc hl
   inc hl
   inc hl
   inc hl
   ld (xp),hl


   ld hl,(checkx)
   ex hl,de
   ld hl,(xp)
   and a
   sbc hl,de   
   jr nz,loop


   ld hl,0
   ld (xp),hl


   ld hl,(yp)
   dec hl
   dec hl
   ld (yp),hl


   ld hl,(checky)
   ex hl,de
   ld hl,(yp)
   and a
   sbc hl,de
   jr nz,loop
   
   call keywait


   ret
   
.rnd
    push    hl
        ld      a,(RandomPtr)
        inc     a
        ld      (RandomPtr),a
        ld      hl,RandTable
        add     a,l
        ld      l,a
        jr      nc,skip
        inc     h
.skip     ld      a,(hl)
        pop     hl
        ret


.sht4
   srl a
   srl a
   srl a
   srl a
   inc a
   ld (rslt),a
   ret


.setup   xor a
   call mode
   ld a,14
   ld c,9
   ld b,c
   call inks
   ld a,15
   ld c,11
   ld b,c
   call inks
   ld c,26
   ld b,c
   call border
   ret


.xp   defw 0
.yp   defw 398
.rslt   defb 0
.xcount   defw 0
.checkx   defw 640
.checky   defw 0
.RandTable
     
   defb   &3B,&02,&B7,&6B,&08,&74,&1A,&5D,&21,&99,&95,&66,&D5,&59,&05,&42
        defb    &F8,&03,&0F,&53,&7D,&8F,&57,&FB,&48,&26,&F2,&4A,&3D,&E4,&1D,&D9
        defb    &9D,&DC,&2F,&F5,&92,&5C,&CC,&00,&73,&15,&BF,&B1,&BB,&EB,&9E,&2E
        defb    &32,&FC,&4B,&CD,&A7,&E6,&C2,&10,&11,&80,&52,&B2,&DA,&77,&4F,&EC
        defb    &13,&54,&64,&ED,&94,&8C,&C6,&9A,&19,&9F,&75,&FA,&AA,&8D,&FE,&91
        defb    &01,&23,&07,&C1,&40,&18,&51,&76,&3C,&BD,&2A,&88,&2D,&F1,&8A,&72
        defb    &F6,&98,&35,&97,&68,&93,&B3,&0C,&82,&4E,&CB,&39,&D8,&5F,&C7,&D4
        defb    &CE,&AE,&6D,&A3,&7C,&6A,&B8,&A6,&6F,&5E,&E5,&1B,&F4,&B5,&3A,&14
        defb    &78,&FD,&D0,&7A,&47,&2C,&A8,&1E,&EA,&2B,&9C,&86,&83,&E1,&7B,&71
        defb    &F0,&FF,&D1,&C3,&DB,&0E,&46,&1C,&C9,&16,&61,&55,&AD,&36,&81,&F3
        defb    &DF,&43,&C5,&B4,&AF,&79,&7F,&AC,&F9,&37,&E7,&0A,&22,&D3,&A0,&5A
        defb    &06,&17,&EF,&67,&60,&87,&20,&56,&45,&D7,&6E,&58,&A9,&B0,&62,&BA
        defb    &E3,&0D,&25,&09,&DE,&44,&49,&69,&9B,&65,&B9,&E0,&41,&A4,&6C,&CF
        defb    &A1,&31,&D6,&29,&A2,&3F,&E2,&96,&34,&EE,&DD,&C0,&CA,&63,&33,&5B
        defb    &70,&27,&F7,&1F,&BE,&12,&B6,&50,&BC,&4D,&28,&C8,&84,&30,&A5,&4C
        defb    &AB,&E9,&8E,&E8,&7E,&C4,&89,&8B,&0B,&24,&85,&3E,&38,&04,&D2,&90
.RandomPtr
   defb   0





Output:

[attachimg=2]




   org &4000


.mode      equ &bc0e
.border      equ &bc38
.inks      equ &bc32
.plot      equ &bbea
.grapen      equ &bbde
.keywait   equ &bb18


   call setup
.loop
   call rnd   
   ld l,a
   ld h,0   
   ld bc,14
.mod_loop   
   or a   
   sbc hl,bc   
   jp p,mod_loop   
   add hl,bc   
   ld bc,1
   add hl,bc   
   ld a,l
   call grapen
   ld hl,(xp)
   ex hl,de
   ld hl,(yp)
   call plot
   
   ld hl,(xp)
   inc hl
   inc hl
   inc hl
   inc hl
   ld (xp),hl


   ld hl,(checkx)
   ex hl,de
   ld hl,(xp)
   and a
   sbc hl,de   
   jr nz,loop


   ld hl,0
   ld (xp),hl


   ld hl,(yp)
   dec hl
   dec hl
   ld (yp),hl


   ld hl,(checky)
   ex hl,de
   ld hl,(yp)
   and a
   sbc hl,de
   jr nz,loop
   
   call keywait


   ret
   


.rnd
   ld a,(seed)
   ld b,a
   add a,a
   add a,a
   add a,b
   inc a
   ld (seed),a
   ret


.setup   xor a
   call mode
   ld a,14
   ld c,9
   ld b,c
   call inks
   ld a,15
   ld c,11
   ld b,c
   call inks
   ld c,26
   ld b,c
   call border
   ret


.xp   defw 0
.yp   defw 398
.seed   defb 0
.rslt   defb 0
.xcount   defw 0
.checkx   defw 640
.checky   defw 0



Output:


[attachimg=3]




   org &4000


.mode      equ &bc0e
.border      equ &bc38
.inks      equ &bc32
.plot      equ &bbea
.grapen      equ &bbde
.keywait   equ &bb18


   call setup
.loop


   call rnd
   ld l,a
   ld h,0
   ld bc,14
.mod_loop
   or a
   sbc hl,bc
   jp p,mod_loop
   add hl,bc
   ld bc,1
   add hl,bc
   ld a,l


   call grapen


   ld hl,(xp)
   ex hl,de
   ld hl,(yp)
   call plot
   
   ld hl,(xp)
   inc hl
   inc hl
   inc hl
   inc hl
   ld (xp),hl


   ld hl,(checkx)
   ex hl,de
   ld hl,(xp)
   and a
   sbc hl,de   
   jr nz,loop


   ld hl,0
   ld (xp),hl


   ld hl,(yp)
   dec hl
   dec hl
   ld (yp),hl


   ld hl,(checky)
   ex hl,de
   ld hl,(yp)
   and a
   sbc hl,de
   jr nz,loop
   
   call keywait


   ret
   
.rnd
        push    hl
        ld      a,(RandomPtr)
        inc     a
        ld      (RandomPtr),a
        ld      hl,RandTable
        add     a,l
        ld      l,a
        jr      nc,skip
        inc     h
.skip     ld      a,(hl)
        pop     hl
        ret


.setup   xor a
   call mode
   ld a,14
   ld c,9
   ld b,c
   call inks
   ld a,15
   ld c,11
   ld b,c
   call inks
   ld c,26
   ld b,c
   call border
   ret


.xp   defw 0
.yp   defw 398
.rslt   defb 0
.xcount   defw 0
.checkx   defw 640
.checky   defw 0
.RandTable
        defb   &3B,&02,&B7,&6B,&08,&74,&1A,&5D,&21,&99,&95,&66,&D5,&59,&05,&42
        defb    &F8,&03,&0F,&53,&7D,&8F,&57,&FB,&48,&26,&F2,&4A,&3D,&E4,&1D,&D9
        defb    &9D,&DC,&2F,&F5,&92,&5C,&CC,&00,&73,&15,&BF,&B1,&BB,&EB,&9E,&2E
        defb    &32,&FC,&4B,&CD,&A7,&E6,&C2,&10,&11,&80,&52,&B2,&DA,&77,&4F,&EC
        defb    &13,&54,&64,&ED,&94,&8C,&C6,&9A,&19,&9F,&75,&FA,&AA,&8D,&FE,&91
        defb    &01,&23,&07,&C1,&40,&18,&51,&76,&3C,&BD,&2A,&88,&2D,&F1,&8A,&72
        defb    &F6,&98,&35,&97,&68,&93,&B3,&0C,&82,&4E,&CB,&39,&D8,&5F,&C7,&D4
        defb    &CE,&AE,&6D,&A3,&7C,&6A,&B8,&A6,&6F,&5E,&E5,&1B,&F4,&B5,&3A,&14
        defb    &78,&FD,&D0,&7A,&47,&2C,&A8,&1E,&EA,&2B,&9C,&86,&83,&E1,&7B,&71
        defb    &F0,&FF,&D1,&C3,&DB,&0E,&46,&1C,&C9,&16,&61,&55,&AD,&36,&81,&F3
        defb    &DF,&43,&C5,&B4,&AF,&79,&7F,&AC,&F9,&37,&E7,&0A,&22,&D3,&A0,&5A
        defb    &06,&17,&EF,&67,&60,&87,&20,&56,&45,&D7,&6E,&58,&A9,&B0,&62,&BA
        defb    &E3,&0D,&25,&09,&DE,&44,&49,&69,&9B,&65,&B9,&E0,&41,&A4,&6C,&CF
        defb    &A1,&31,&D6,&29,&A2,&3F,&E2,&96,&34,&EE,&DD,&C0,&CA,&63,&33,&5B
        defb    &70,&27,&F7,&1F,&BE,&12,&B6,&50,&BC,&4D,&28,&C8,&84,&30,&A5,&4C
        defb    &AB,&E9,&8E,&E8,&7E,&C4,&89,&8B,&0B,&24,&85,&3E,&38,&04,&D2,&90
.RandomPtr
   defb   0



Output:


[attachimg=5]


And this is my original BASIC Output:


[attachimg=4]


I've used variations of the Random number generators from the Wiki pages and also used some code Kev posted which lets you select a Range for the specific Random numbers, though for this kind of program, I need something a bit more unpredictable to make up something that looks totally Random. At the moment I haven't looked into Random number generators which use the R register or the Firmware to return from the clock function, I wasn't sure how they would go.
* Using the old Amstrad Languages :D * And create my own ;)
* Incorporating the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

Singaja

Can the R register be used for (pseudo)random generation purposes? I'm interested what visual pattern it would yield.

AMSDOS

Quote from: Singaja on 13:01, 07 November 15
Can the R register be used for (pseudo)random generation purposes? I'm interested what visual pattern it would yield.


It's not something I've played with, due to the nature of the Assembly book, though I've been told the R register can only be loaded into the Accumulator. @redbox posted a 16bit solution for it in this thread.


Unfortunately I totally forgot about this thread, which might have a solution for me in there.
* Using the old Amstrad Languages :D * And create my own ;)
* Incorporating the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

Singaja

I modifed your first code snippet .rnd part to this uber complicated approach

.rnd
   ld a,r
   ret

Got this:

Singaja

[UPDATED x 2] I also found this:
//X ABC Algorithm Random Number Generator for 8-Bit Devices:
//This is a small PRNG, experimentally verified to have at least a 50 million byte period
//by generating 50 million bytes and observing that there were no overapping sequences and repeats.
//This generator passes serial correlation, entropy , Monte Carlo Pi value, arithmetic mean,
//And many other statistical tests. This generator may have a period of up to 2^32, but this has
//not been verified.
//
// By XORing 3 bytes into the a,b, and c registers, you can add in entropy from
//an external source easily.
//
//This generator is free to use, but is not suitable for cryptography due to its short period(by //cryptographic standards) and simple construction. No attempt was made to make this generator
// suitable for cryptographic use.
//
//Due to the use of a constant counter, the generator should be resistant to latching up.
//A significant performance gain is had in that the x variable is nly ever incremented.
//
//Only 4 bytes of ram are needed for the internal state, and generating a byte requires 3 XORs , //2 ADDs, one bit shift right , and one increment. Difficult or slow operations like multiply, etc
//were avoided for maximum speed on ultra low power devices.
init_rng(s1,s2,s3) //Can also be used to seed the rng with more entropy during use.
{
//XOR new entropy into key state
a ^=s1;
b ^=s2;
c ^=s3;

x++;
a = (a^c^x);
b = (b+a);
c = (c+(b>>1)^a);
}

unsigned char randomize()
{
x++;               //x is incremented every round and is not affected by any other variabl
a = (a^c^x);       //note the mix of addition and XOR
b = (b+a);         //And the use of very few instructions
c = (c+(b>>1)^a);  //the right shift is to ensure that high-order bits from b can affect 
return(c)          //low order bits of other variables
}

I actually exchanged a & c on register level in my implementation attempt.
org &4000
.mode      equ &bc0e
.border      equ &bc38
.inks      equ &bc32
.plot      equ &bbea
.grapen      equ &bbde
.keywait   equ &bb18
run start
start
   call setup
   call rndInit
   jp firstEntry
.loop
   call rnd
.firstEntry
   call sht4
   ld a,(rslt)
   call grapen




   ld hl,(xp)
   ex hl,de
   ld hl,(yp)
   call plot
   
   ld hl,(xp)
   inc hl
   inc hl
   inc hl
   inc hl
   ld (xp),hl




   ld hl,(checkx)
   ex hl,de
   ld hl,(xp)
   and a
   sbc hl,de   
   jr nz,loop




   ld hl,0
   ld (xp),hl




   ld hl,(yp)
   dec hl
   dec hl
   ld (yp),hl




   ld hl,(checky)
   ex hl,de
   ld hl,(yp)
   and a
   sbc hl,de
   jr nz,loop
   
   call keywait
   ret
.rndInit


   ld l,a


   ;b ^=s2;
   ld a,r
   ld b,a
   xor a
   xor b
   ld b,a 


   ;a ^=s3;
   ld a,r
   ld c,a
   xor a
   xor c 
   ld (aVal),a


   ;c ^=s1
   ld a,r
   ld c,a
   xor a
   xor c
   ld c,a


   ;x++
   ld a,(x)
   inc a
   ld (x),a
   ld l,a
   
   ;c = (c^a^x);
   ld a,(aVal)
   ld a,c
   xor l
   ld c,a


   ;b = (b+c);
   ld a,b
   add c
   ld b,a


   ;a = (a+(b>>1)^c);
   ld a,(aVal)
   srl b
   add b
   xor c
   ld (aVal),a

   ld (x),hl
   ret
.rnd
   push hl


   ;x++
   ld a,(x)
   inc a
   ld (x),a
   ld l,a
   
   ;c = (c^a^x);
   ld a,(aVal)
   ld a,c
   xor l
   ld c,a


   ;b = (b+c);
   ld a,b
   add c
   ld b,a


   ;a = (a+(b>>1)^c);
   ld a,(aVal)
   srl b
   add b
   xor c
   ld (aVal),a
   
   pop hl
   ret
.sht4
   srl a
   srl a
   srl a
   srl a
   inc a
   ld (rslt),a
   ret
.setup   xor a
   call mode
   ld a,14
   ld c,9
   ld b,c
   call inks
   ld a,15
   ld c,11
   ld b,c
   call inks
   ld c,26
   ld b,c
   call border
   ret
.xp   defw 0
.yp   defw 398
;.seed   defb 0
.x    db 0
.aVal   db 0
.rslt   defb 0
.xcount   defw 0
.checkx   defw 640.checky   defw 0

Not sure if there are no bugs in implementation,but I got this:



reidrac

It would be interesting to see how performs the SDCC rand function:

Small Device C Compiler suite / Code / [r9392] /trunk/sdcc/device/lib/rand.c

That would translate into something like the following:

_rand::
; next = next * 1103515245UL + 12345;
ld hl,(_next + 2)
push hl
ld hl,(_next)
push hl
ld hl,#0x41C6
push hl
ld hl,#0x4E6D
push hl
call __mullong
pop af
pop af
pop af
pop af
ld c,l
ld b,h
ld a,c
ld hl,#_next
add a, #0x39
ld (hl),a
ld a,b
adc a, #0x30
inc hl
ld (hl),a
ld a,e
adc a, #0x00
inc hl
ld (hl),a
ld a,d
adc a, #0x00
inc hl
ld (hl),a
; return (unsigned int)(next/65536) % (RAND_MAX + 1U);
push af
ld iy,#_next
ld l,0 (iy)
ld iy,#_next
ld h,1 (iy)
ld iy,#_next
ld e,2 (iy)
ld iy,#_next
ld d,3 (iy)
pop af
ld b,#0x10
00103$:
srl d
rr e
rr h
rr l
djnz 00103$
res 7, h
ret

_srand::
; next = seed;
ld hl, #2+0
add hl, sp
ld a, (hl)
ld (#_next + 0),a
ld hl, #2+1
add hl, sp
ld a, (hl)
ld (#_next + 1),a
ld hl,#_next + 2
ld (hl), #0x00
ld hl,#_next + 3
ld (hl), #0x00
ret

_next:
.ds 4


EDIT: well, that's SDCC assembler syntax so it may not be straightforward to assemble. Also that __mullong is a quite a piece of code. So meh.
Released The Return of Traxtor, Golden Tail, Magica, The Dawn of Kernel, Kitsune`s Curse, Brick Rick, Hyperdrive and The Heart of Salamanderland for the CPC.

If you like my games and want to show some appreciation, you can always buy me a coffee.

Urusergi

Quote from: Singaja on 16:21, 07 November 15
Not sure if there are no bugs in implementation,but I got this:

xor a ; a is always 0  ;D

Singaja

Quote from: Urusergi on 20:50, 07 November 15
xor a ; a is always 0  ;D
Thanks. I made some corrections, looks better but it is still a repeatable pattern  :-[
I found a bug, but when I corrected it, it looks even worse :picard2:

AMSDOS


Thanks for your replies folks. I've gone back to my original program and made some alterations to it.


   org &4000

.mode      equ &bc0e
.border      equ &bc38
.inks      equ &bc32
.plot      equ &bbea
.grapen      equ &bbde
.keywait   equ &bb18
.timeplease equ &bd0d


   call setup


.newseed
   call timeplease
   ld a,l
   ld (seed),a
.loop
   call rnd
   call sht4
   ld a,(rslt)
   call grapen




   ld hl,(xp)
   ex hl,de
   ld hl,(yp)
   call plot
   
   ld hl,(xp)
   inc hl
   inc hl
   inc hl
   inc hl
   ld (xp),hl




   ld hl,(checkx)
   ex hl,de
   ld hl,(xp)
;;   and a <- Not sure why this was needed, but works without it.
   sbc hl,de   
   jr nz,loop

   ld hl,0
   ld (xp),hl

   ld hl,(yp)
   dec hl
   dec hl
   ld (yp),hl

   ld hl,(checky)
   ex hl,de
   ld hl,(yp)
;;   and a <- Not sure why this was needed, but works without it.
   sbc hl,de
   jr nz,newseed
   
   call keywait

   ret
   
.rnd
   ld a,(seed)
   ld b,a
   add a,a
   add a,a
   add a,b
   inc a
   ld (seed),a
   ret

.sht4
   srl a
   srl a
   srl a
   srl a
   inc a
   ld (rslt),a
   ret

.setup   xor a
   call mode
   ld a,14
   ld c,9
   ld b,c
   call inks
   ld a,15
   ld c,11
   ld b,c
   call inks
   ld c,26
   ld b,c
   call border
   ret

.xp   defw 0
.yp   defw 398
.seed   defb 0
.rslt   defb 0
.xcount   defw 0
.checkx   defw 640
.checky   defw 0



This was about as Random as I could get it, there were some defined vertical lines, but the rest looks scrambled, only thing I could come up with regarding those lines was the clock cycle ticking over. I've used "l" register from Timeplease which gives the most random due to it being the least significant bit.


I was using "and a" which I've removed because I didn't know what it was doing and seems to work without it. I originally had it there based on some code from my assembly book which looked like this:



ld hl,(first)
ld de,(second)
and a
sbc hl,de
jr nz,over
...
...
...
.over



which branches to over if first double byte number is not equal to second double byte number.


But I altered that so I'm only using HL.


So what happens in my code above is when it reaches the Y position loop, it loops back to obtain a new seed which addresses the pattern from occurring all over again.


Here's the result:
[attachimg=1]
* Using the old Amstrad Languages :D * And create my own ;)
* Incorporating the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

AMSDOS

I was also getting some other unusual patterns when playing around with the code:


[attachimg=1]




[attachimg=2]
* Using the old Amstrad Languages :D * And create my own ;)
* Incorporating the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

AMSDOS

Quote from: reidrac on 16:47, 07 November 15
It would be interesting to see how performs the SDCC rand function:

Small Device C Compiler suite / Code / [r9392] /trunk/sdcc/device/lib/rand.c

EDIT: well, that's SDCC assembler syntax so it may not be straightforward to assemble. Also that __mullong is a quite a piece of code. So meh.


I've only played around with Small-C myself. One of the libraries for that had a Random Number Generator for it, unsure how it fared in regard to how random the numbers were.


I could also possibly experiment the last Assembly routine. In a way it works similarly to how BASIC does with RANDOMIZE TIME being initiated. The assembly just needs something to set another seed when it starts looping another line to prevent a patterned effect.
* Using the old Amstrad Languages :D * And create my own ;)
* Incorporating the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

Singaja

Slightly exhausted by my attempts to fix the previous one I went for something new with more experimental approach. The result is surprisingly good.


.rnd
   ld a,r
   ld b,a
   ld a,r
   ld c,a
   ld a,r
   ld d,a
   ld a,r
   ld e,a
   ld a,(x)
   add b
   xor c
   add d
   xor e
   add c
   xor b
   add e
   ld (x),a
   ret


AMSDOS


I've produced a similar sort of outcome when I've used the Refresh Register (R) when acquiring a new seed




org &4000


.mode equ &bc0e
.border equ &bc38
.inks equ &bc32
.plot equ &bbea
.grapen equ &bbde
.keywait equ &bb18


call setup


.newseed
ld a,r
ld (seed),a




.loop
call rnd
call sht4
ld a,(rslt)
call grapen


ld hl,(xp)
ex hl,de
ld hl,(yp)
call plot

ld hl,(xp)
inc hl
inc hl
inc hl
inc hl
ld (xp),hl


ld hl,(checkx)
ex hl,de
ld hl,(xp)
sbc hl,de
jr nz,loop


ld hl,0
ld (xp),hl


ld hl,(yp)
dec hl
dec hl
ld (yp),hl


ld hl,(checky)
ex hl,de
ld hl,(yp)
sbc hl,de
jr nz,newseed

call keywait


ret



.rnd
ld a,(seed)
ld b,a
add a,a
add a,a
add a,b
inc a
ld (seed),a
ret


.sht4
srl a
srl a
srl a
srl a
inc a
ld (rslt),a
ret


.setup xor a
call mode
ld a,14
ld c,9
ld b,c
call inks
ld a,15
ld c,11
ld b,c
call inks
ld c,26
ld b,c
call border
ret


.xp defw 0
.yp defw 398
.seed defb 7
.rslt defb 0
.xcount defw 0
.checkx defw 640
.checky defw 0



[attachimg=1]

In terms of writing a routine to generate random numbers having a routine to solely handle that has more practical application.


I was still dancing around the idea of using the Refresh Register, while it produces good Random Results, my Assembly book & Thomas Scherrer's website advise caution when using it in one way or another. Thomas Scherrer's site describes the "R" register as:


Quote

The Z-80 CPU contains a memory refresh counter to enable dynamic memories to be used with the same ease as static memories. Seven bits of this 8 bit register are automatically incremented after each instruction fetch. The eight bits will remain as programmed with the LD R,A instruction. The data in the refresh counter is sent out on the lower portion of the address bus along with a refresh control signal while the CPU is decoding and executing the instruction. The programmer can load the R register for testing purposes, but this register is normally NOT used by the programmer. During refresh, the contents of the I register are placed on the upper
8 bits of the address bus.


What I don't know is what sort of Risk is there in using the Refresh Register, is it bad for the hardware to use it a lot in your code for example?
* Using the old Amstrad Languages :D * And create my own ;)
* Incorporating the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

reidrac

Quote from: AMSDOS on 09:48, 09 November 15
What I don't know is what sort of Risk is there in using the Refresh Register, is it bad for the hardware to use it a lot in your code for example?

I'm inclined to think it won't damage the hardware, but I don't know.

I'm using rand() from SDCC, but I play with R to set the seed (expects a 16-bit number):

void
setup_srand()
{
__asm
di
ld a, r
ld l, a
ld a, (_tick)
xor l
ld h, l
push hl
call _srand
pop af
ei
__endasm;
}


("tick" is a 8-bit number that gets increased every interrupt; that's how I measure time)

I only call this once per game though.
Released The Return of Traxtor, Golden Tail, Magica, The Dawn of Kernel, Kitsune`s Curse, Brick Rick, Hyperdrive and The Heart of Salamanderland for the CPC.

If you like my games and want to show some appreciation, you can always buy me a coffee.

Singaja

Quote from: AMSDOS on 09:48, 09 November 15
What I don't know is what sort of Risk is there in using the Refresh Register, is it bad for the hardware to use it a lot in your code for example?
At this point some proper mathematical tools would be helpful to evaluate the distribution that is generated. Which is good :)
Anyway my understanding is that author meant that the register shouldn't be used like "normal" general purpose register (analogously to F).
Z80 down to logic gates is reversed engineered here:
http://www.righto.com/2014/10/how-z80s-registers-are-implemented-down.html
Our hardware experts could shed some light, but it seems pretty safe to me.

gerald

The R register is a Z80 refresh dedicated register. It is used during refresh cycle (on instruction fetch) for refreshing DRAM.
This feature is not used on the CPC. The DRAM refresh is done by the screen data fetching.

On a computer that uses the Z80 refresh feature, writing to the R register may compromise the DRAM refresh and lead to memory corruption.

Quote from: Singaja on 10:41, 08 November 15

.rnd
   ld a,r
   ld b,a
   ld a,r
   ld c,a
   ld a,r
   ld d,a
   ld a,r
   ld e,a

Did you know this is equivalent to

.rnd
   ld a,r
   ld b,a
   ld c,(a+3) & 0x7F
   ld d,(a+6) & 0x7F
   ld e,(a+9) & 0x7F

Singaja

While at work I'm thinking about this distribution evaluation, proper mathematical tool is the Kolmogorov test , but that seems like an overkill.
My simpler idea is to reserve 256bytes of memory for [0..255] and than each random result would increase the relevant memory cell.
After the screen run the memory should be filled number of occurrences , which can be easily copied from WinApe to something like an Excel or some other spreadsheet tool to make a plot.
That of course will flip for more than 255 instances but for the screen size it should be ok. if not , 2bytes per result should do the trick.
Rough estimate :screen size 320 x 200 = 64000 vs ideal distribution 256*255 = 65280

pelrun

Quote from: AMSDOS on 09:48, 09 November 15
What I don't know is what sort of Risk is there in using the Refresh Register, is it bad for the hardware to use it a lot in your code for example?


If you're just reading it, there's no problem.


If you're writing it, and you're on a CPC, then there's still no problem, because as far as I know the CPC relies on the CRTC to refresh the DRAM. Other Z80 systems may suffer memory rot if you constrain R too much.

Singaja

I have made a modified version which tracks the number of occurences in memory:



With this tool evaluating results became much easier. This lead me to an approach very similar to one Amsdos is using.


   ld a,r
   ld b,a
   ld a,(myA)
   add b
   add b
   add b
   add a
   ld (myA),a

Result is quite nice:



Full code:


org &4000
.mode      equ &bc0e
.border      equ &bc38
.inks      equ &bc32
.plot      equ &bbea
.grapen      equ &bbde
.keywait   equ &bb18
run start
start
   call setup
.loop
   call rnd
   call sht4
   ld a,(rslt)
   call grapen




   ld hl,(xp)
   ex hl,de
   ld hl,(yp)
   call plot
   
   ld hl,(xp)
   inc hl
   inc hl
   inc hl
   inc hl
   ld (xp),hl




   ld hl,(checkx)
   ex hl,de
   ld hl,(xp)
   and a
   sbc hl,de   
   jr nz,loop




   ld hl,0
   ld (xp),hl




   ld hl,(yp)
   dec hl
   dec hl
   ld (yp),hl




   ld hl,(checky)
   ex hl,de
   ld hl,(yp)
   and a
   sbc hl,de
   jr nz,loop
   
   call keywait
   ret
.rnd
   ld a,r
   ld b,a
   ld a,(myA)
   add b
   add b
   add b
   add a
   ld (myA),a
   ld b,a
   ld hl,buffer256
   ld a,l
   adc b
   ld l,a
   ld a,b
   jp nc,notcarry
   inc h
.notCarry
   ld b,(hl)
   inc b
   ld (hl),b
   ;pop hl
   ret
.sht4
   srl a
   srl a
   srl a
   srl a
   inc a
   ld (rslt),a
   ret
.setup   xor a
   call mode
   ld a,14
   ld c,9
   ld b,c
   call inks
   ld a,15
   ld c,11
   ld b,c
   call inks
   ld c,26
   ld b,c
   call border
   ret
.xp   defw 0
.yp   defw 398
;.seed   defb 0
.myA    db 0
.X      db 0
.rslt   defb 0
.xcount   defw 0
.checkx   defw 640
.checky   defw 0
.padding  defs 2+8+7,#CC
.buffer256 defs 256,0



AMSDOS

Quote from: pelrun on 15:10, 09 November 15

If you're just reading it, there's no problem.


If you're writing it, and you're on a CPC, then there's still no problem, because as far as I know the CPC relies on the CRTC to refresh the DRAM. Other Z80 systems may suffer memory rot if you constrain R too much.


Yeah I don't know why I'm all cautious about this register, the z80 website made it sound like you could change the state of your system. I guess if did it would only go as far as the emulator bounds.
More likely to do some harm with an OUT command I would of thought.
* Using the old Amstrad Languages :D * And create my own ;)
* Incorporating the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

AMSDOS

Quote from: Singaja on 00:01, 10 November 15
I have made a modified version which tracks the number of occurences in memory:



With this tool evaluating results became much easier. This lead me to an approach very similar to one Amsdos is using.


   ld a,r
   ld b,a
   ld a,(myA)
   add b
   add b
   add b
   add a
   ld (myA),a

Result is quite nice:



Full code:


org &4000
.mode      equ &bc0e
.border      equ &bc38
.inks      equ &bc32
.plot      equ &bbea
.grapen      equ &bbde
.keywait   equ &bb18
run start
start
   call setup
.loop
   call rnd
   call sht4
   ld a,(rslt)
   call grapen




   ld hl,(xp)
   ex hl,de
   ld hl,(yp)
   call plot
   
   ld hl,(xp)
   inc hl
   inc hl
   inc hl
   inc hl
   ld (xp),hl




   ld hl,(checkx)
   ex hl,de
   ld hl,(xp)
   and a
   sbc hl,de   
   jr nz,loop




   ld hl,0
   ld (xp),hl




   ld hl,(yp)
   dec hl
   dec hl
   ld (yp),hl




   ld hl,(checky)
   ex hl,de
   ld hl,(yp)
   and a
   sbc hl,de
   jr nz,loop
   
   call keywait
   ret
.rnd
   ld a,r
   ld b,a
   ld a,(myA)
   add b
   add b
   add b
   add a
   ld (myA),a
   ld b,a
   ld hl,buffer256
   ld a,l
   adc b
   ld l,a
   ld a,b
   jp nc,notcarry
   inc h
.notCarry
   ld b,(hl)
   inc b
   ld (hl),b
   ;pop hl
   ret
.sht4
   srl a
   srl a
   srl a
   srl a
   inc a
   ld (rslt),a
   ret
.setup   xor a
   call mode
   ld a,14
   ld c,9
   ld b,c
   call inks
   ld a,15
   ld c,11
   ld b,c
   call inks
   ld c,26
   ld b,c
   call border
   ret
.xp   defw 0
.yp   defw 398
;.seed   defb 0
.myA    db 0
.X      db 0
.rslt   defb 0
.xcount   defw 0
.checkx   defw 640
.checky   defw 0
.padding  defs 2+8+7,#CC
.buffer256 defs 256,0



This looks great, but I don't understand what the data is about, I presume this is an alternative to the earlier 8bit Random Number Generator which had a Buffer, so the Bytes Highlighted from &40B0 to &41AF is the Information you used to create that Random Effect?
* Using the old Amstrad Languages :D * And create my own ;)
* Incorporating the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

Singaja

Quote from: AMSDOS on 08:38, 10 November 15

This looks great, but I don't understand what the data is about, I presume this is an alternative to the earlier 8bit Random Number Generator which had a Buffer, so the Bytes Highlighted from &40B0 to &41AF is the Information you used to create that Random Effect?
Highlighted bytes are used for debugging only. Each byte cell at given index is increased when a number is generated with the same value.  The smaller differences between the cells the more uniform the distribution is. 

AMSDOS

I made a little BASIC program to count through the INK colours individually, in case anyone was interested, though the colourful results speak for themselves. I just wanted to see if the results gave a good spread.




10 CALL &4000
20 FOR p%=0 TO 15
30  INK p%,0
40 NEXT p%
50 col%=26
60 FOR p%=1 TO 15
70  INK p%,col%
80  INK p%-1,0
90  CALL &BB18
100 NEXT p%
110 PEN 1:CALL &BC02:MODE 2
* Using the old Amstrad Languages :D * And create my own ;)
* Incorporating the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

Singaja

I made a xor variant with one less instruction and more uniform distribution.

.rnd
   ld a,r
   ld b,a
   ld a,(myA)
   xor b
   add a
   xor b
   ld (myA),a



AMSDOS

Quote from: Singaja on 13:35, 15 November 15
I made a xor variant with one less instruction and more uniform distribution.

.rnd

   ld a,r
   ld b,a
   ld a,(myA)
   xor b
   add a
   xor b
   ld (myA),a



This example of code would make a nice alternative for producing 8bit numbers if you don't mind having it posted on the Wiki, I could probably just alter myA to Seed I guess?
* Using the old Amstrad Languages :D * And create my own ;)
* Incorporating the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

Powered by SMFPacks Menu Editor Mod