Really need to get feedback on this as I'm a bit concerned that the clock frequency between systems may effect the results.
While a stationary image may look ok, it's only by animating it that you really notice any cycles or anomalies.
The Resultant static noise should be indistinguishable to the Pseudo Random Generated noise on the right half of the window.
Code: Select all
;idle TRGN experiment based on Rescator's Idea of using the CPU time stamp Counter
;Results may vary on different systems due to clock speeds which could require the magnitude of the bit shifts to be changed
;It apears that the output from the CPU time stamp can be used effectivly to generate a Random Bit with Rescators first example but you need
;a delay between calls to the function, without a delay I found it generated patterns and didn't conform to a normal distributuon.
;The issue was how to use it without a delay to obtain a normal distribution, so while the algorithim appears to look random it still may not
;be totaly random due to the mixing and XOR which may add cyclic trends.
EnableExplicit
Global w,h,hdc
Global rVal,bset
;hacky method to set any bit in a var or buffer given it's offset in bits
Procedure SetBit(*num,bit)
Protected of.i
of = bit >> 3
PokeB(*num+of,(PeekB(*num+of) | (1 << (bit % 8))))
EndProcedure
;hacky method to get any bit from a var or buffer given its offset in bits
Procedure GetBit(*buffer,index)
Protected mf
mf = (index % 8)
ProcedureReturn (PeekB(*buffer+(index>>3)) & (1 << mf)) >> mf
EndProcedure
;get a random bit from the CPU Time Stamp Counter
Procedure.i RandomBit()
Static num
RDTSC ;Read the CPU Time Stamp Counter
SHL eax, 6 ; << 6
XOR eax, num ;xor result
SHR eax, 2 ; >> 2
MOV num,eax
AND eax, $1
ProcedureReturn
EndProcedure
;Random Buffer fill a buffer with random bits, size in bytes
Procedure RandomBuffer(*buffer,size)
Protected n.f, num, a,bit
Static bset
ZeroMemory_(*buffer,size)
If bset = 0
While a < 3
Randombit()
a+1
Wend
bset = 1
EndIf
For a = 1 To size*8
bit=RandomBit()
If bit
setbit(*buffer,a)
EndIf
Next
EndProcedure
;Internal method to get random number called from RRandom()
Procedure.i RandomNum(num,Range)
RDTSC ;Read the CPU Time Stamp Counter
SHL eax, 6 ; << 6
XOR eax, num ;xor result
SHR eax, 2 ; >> 2
MOV ebx, Range ;do test for odd or even
AND ebx,1
AND ebx,ebx
JE ED ;
MOV ebx, Range
XOR edx,edx ;do mod zero edx
DIV ebx ;num % Range
INC edx
MOV eax,edx
! ED:
MOV ebx, Range ;get val
INC ebx ;val +1
XOR edx,edx ;do mod zero edx
DIV ebx ;num % Range
MOV eax,edx ;
DEC eax ;num - 1
ProcedureReturn
EndProcedure
;Get a TRGN number
Procedure RRandom(Range)
If bset = 0
Protected a
While a < 3
rval = RandomNum(rval,Range)
a+1
Wend
bset = 1
Else
rval = RandomNum(rval,Range)
EndIf
ProcedureReturn rval
EndProcedure
Procedure draw(hdc)
Protected a,x,y,st,et,Strt.s,*px.long,offset,pitch,strb.s ,ct,cta,tb,sout.s,*rbuf,bb ,strc.s,ctb,ct1
Strt = "Random Test "
ct=1
cta=1
ctb=1
ct=1
SetFrameRate(25)
*rbuf = AllocateMemory(128/8) ;allocate a buffer want 128 bits
randombuffer(*rbuf,128/8) ;fill random buffer want 128 bits
While 1
StartDrawing(ScreenOutput())
hdc= DrawingBuffer()
Pitch = DrawingBufferPitch()
a=0
;get TRGN number draw on the left
;get PB Random number draw on the right
While a < w/2*h/2
x = rRandom(w/2)
y = rRandom(h)
offset = (x*4 + (y * pitch))
*px = hdc + offset
*px\l = rRandom(16777215)
x = Random((w)/2)+w/2
y = Random(h)
offset = (x*4 + (y * pitch))
*px = hdc + offset
*px\l = Random(16777215)
a+1
Wend
;Get a Random bit
tb = randomBit()
If tb = 1
cta + 1
EndIf
ct+1
If Len(strb)<110
;write out random bit
strb + Str(tb) + " "
;write out a bit from the random buffer, alternativly use use peekB peekW PeekL and mask if you want unsigned vals
;strc + Str(getbit(*rbuf,bb)) + " "
tb = getbit(*rbuf,bb)
If tb = 1
ctb+1
EndIf
ct1+1
strc + Str(tb) + " "
bb+1
Else
strb = Str(tb) + " "
;refill the random buffer
randombuffer(*rbuf,128)
strc = ""
bb=0
EndIf
DrawText(0,0,strb,RGB(0,255,0),RGB(0,0,0))
sout = "Percent " + StrF(((cta/ct)*100),2)
DrawText(0,20,sout,RGB(0,255,0),RGB(0,0,0))
sout = strc
DrawText(0,40,sout,RGB(0,255,0),RGB(0,0,0))
sout = "Percent " + StrF(((ctb/ct1)*100),2)
DrawText(0,60,sout,RGB(0,255,0),RGB(0,0,0))
StopDrawing()
FlipBuffers()
ClearScreen(RGB(0,0,0))
Wend
EndProcedure
w=640
h=480
InitSprite()
OpenWindow(0,0,0,w,h,"Random Test",#PB_Window_WindowCentered| #PB_Window_SystemMenu | #PB_Window_TitleBar)
OpenWindowedScreen(WindowID(0),0,0,w,h,0,0,0)
w-1
h-1
hdc = GetDC_(WindowID(0))
Delay(100)
CreateThread(@draw(),hdc)
Repeat
Until WaitWindowEvent() = 16