I needed this function for a DLL I have just written for one of my editors so I can routinely randomise lines of text in the editor. This version is fully self contained and has a parallel prototype for GetTickCount() so it does not conflict with the original include files.
This is the actualy randomise algo.
' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
DECLARE FUNCTION Tick_Count LIB "KERNEL32.DLL" ALIAS "GetTickCount" () AS DWORD
SUB arr_rand(arr() as STRING)
#REGISTER NONE
LOCAL parr as DWORD ' array pointer
LOCAL acnt as DWORD ' array member count
LOCAL lbnd as DWORD ' lower bound of array
LOCAL lcnt as DWORD
LOCAL seed as LONG
seed = val(left$(strreverse$(str$(Tick_Count)),6))
cout sstr(seed)
lbnd = Lbound(arr()) ' get lowest array index
parr = VarPtr(arr(lbnd)) ' get address of 1st array member
acnt = ArrayAttr(arr(),4) ' get the array member count
! mov edi, acnt
! mov esi, parr
! xor ebx, ebx
! mov lcnt, edi
#align 4
stlp:
! mov eax, seed
! test eax, &H80000000
! jz nxt
! add eax, &H7FFFFFFF
nxt:
! xor edx, edx
! mov ecx, 127773
! div ecx
! mov ecx, eax
! mov eax, 16807
! mul edx
! mov edx, ecx
! mov ecx, eax
! mov eax, 2836
! mul edx
! sub ecx, eax
! xor edx, edx
! mov eax, ecx
! mov seed, ecx
! div lcnt
! mov eax, edx
! mov ecx, [esi+ebx*4] ' get the incremental pointer
! mov edx, [esi+eax*4] ' get the random pointer
! mov [esi+ebx*4], edx ' write random pointer back to incremental location
! mov [esi+eax*4], ecx ' write incremental pointer back to random location
! add ebx, 1 ' increment the original pointer
! sub edi, 1 ' decrement the loop counter
! jnz stlp
END SUB
' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
hello steve,
it's possible to get an powerbasic example for testing your algo ?
and something isn't still defined for me in your example, so eg cout, sstr... , it's possible ?
Quotecout sstr(seed)
best thanks frank
Frank,
Sorry about the messup, that line should not be in the final algorithm. I took it out of the test piece instead of the final algo.
Here is the test bed that I have been using for developing these algos, it has all of the functions in it.
#IF 0 ' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
Build with PBCC50
FUNCTION LIST
1. cout console display with C escape support
2. pause wait for a key press to continue
3. sstr convert a SIGNED integer to a basic string
4. ustr convert an UNSIGNED integer to a basic string
5. atoi convert a string to an UNSIGNED integer
6. atol convert a string to a SIGNED integer
#ENDIF ' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
FUNCTION PBmain as LONG
#REGISTER NONE
LOCAL svar as LONG
LOCAL uvar as DWORD
cout "\n\tTestbed for Assembler Programming in\n\tthe PowerBASIC Console Compiler PBCC50\n\n"
' ---------------------------------------------
' conversion tests string to integer to string
' NOTE
' you only use these functions on 32 bit values
' ---------------------------------------------
svar = atol("-12345678") ' ascii to LONG conversion
longint$ = sstr(svar) ' LONG to ascii conversion
cout longint$
uvar = atoi("4000000000") ' ascii to DWORD conversion
uint$ = ustr(uvar) ' DWORD to ascii conversion
cout uint$
pause
FUNCTION = 0
End FUNCTION
' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
DECLARE FUNCTION cc_out CDECL LIB "MSVCRT.DLL" ALIAS "puts" (BYVAL ptxt AS DWORD) AS DWORD
SUB cout(a$)
' ***** Supported escapes *****
' \0 = ascii zero 0
' \t = tab 9
' \n = newline 10
' \r = carriage return 13
' \q = double quote 34
' \\ = backslash 92
' *****************************
#REGISTER NONE
LOCAL src as DWORD
LOCAL dst as DWORD
LOCAL sln as DWORD
src = StrPtr(a$)
! mov esi, src
! mov edi, src
stlp:
! mov al, [esi]
! add esi, 1
! cmp al, "\"
! jne nxt
' ¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤
! cmp BYTE PTR [esi], "n"
! jne lb1
! add esi, 1
! mov BYTE PTR [edi], 10
! add edi, 1
! jmp stlp
lb1:
! cmp BYTE PTR [esi], "r"
! jne lb2
! add esi, 1
! mov BYTE PTR [edi], 13
! add edi, 1
! jmp stlp
lb2:
! cmp BYTE PTR [esi], "t"
! jne lb3
! add esi, 1
! mov BYTE PTR [edi], 9
! add edi, 1
! jmp stlp
lb3:
! cmp BYTE PTR [esi], "0"
! jne lb4
! add esi, 1
! mov BYTE PTR [edi], 0
! add edi, 1
! jmp stlp
lb4:
! cmp BYTE PTR [esi], "\"
! jne lb5
! add esi, 1
! mov BYTE PTR [edi], 92
! add edi, 1
! jmp stlp
lb5:
! cmp BYTE PTR [esi], "q"
! jne lb6
! add esi, 1
! mov BYTE PTR [edi], 34
! add edi, 1
! jmp stlp
lb6:
' ¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤
nxt:
! mov [edi], al
! add edi, 1
! test al, al
! jnz stlp
! sub edi, src
! mov sln, edi
cesc$ = left$(a$,sln)
cc_out StrPtr(cesc$)
END SUB
' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
MACRO INPUT_HANDLE = -10&
DECLARE FUNCTION kbflush LIB "KERNEL32.DLL" ALIAS "FlushConsoleInputBuffer" ( _
BYVAL hConsoleInput AS DWORD) AS LONG
DECLARE FUNCTION hStdIn LIB "KERNEL32.DLL" ALIAS "GetStdHandle" ( _
BYVAL nStdHandle AS DWORD) AS DWORD
DECLARE FUNCTION SysYield LIB "KERNEL32.DLL" ALIAS "Sleep" ( _
BYVAL msWait AS DWORD) AS LONG
DECLARE FUNCTION keypress CDECL LIB "MSVCRT.DLL" ALIAS "_kbhit" () as DWORD
DECLARE FUNCTION putz CDECL LIB "MSVCRT.DLL" ALIAS "puts" (BYVAL ptxt AS DWORD) AS DWORD
' -------------------------------------------
SUB pause()
txt$ = "Press any key to continue ...."
putz StrPtr(txt$)
kbflush hStdIn(INPUT_HANDLE)
lbl0:
SysYield 20
keypress
! test eax, eax
! jz lbl0
END SUB
' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
DECLARE FUNCTION ltoa CDECL LIB "MSVCRT.DLL" ALIAS "_ltoa" ( _
ByVal lval as LONG,ByVal pstr as DWORD,ByVal radix as DWORD) as DWORD
' -------------------------------------------
FUNCTION sstr(ByVal lval as LONG) as STRING
LOCAL astring as ASCIIZ * 32
ltoa(lval,VarPtr(astring),10)
FUNCTION = astring
End FUNCTION
' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
DECLARE FUNCTION c_ultoa CDECL LIB "MSVCRT.DLL" ALIAS "_ultoa" ( _
ByVal uint as DWORD,ByVal pstr as DWORD,ByVal radix as DWORD) as DWORD
' -------------------------------------------
FUNCTION ustr(ByVal uint as DWORD) as STRING
LOCAL astring as ASCIIZ * 32
c_ultoa(uint,VarPtr(astring),10)
FUNCTION = astring
End FUNCTION
' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
DECLARE FUNCTION c_atoi CDECL LIB "MSVCRT.DLL" ALIAS "atoi" (ByVal ptxt as DWORD) as DWORD
FUNCTION atoi(number$) as DWORD
FUNCTION = c_atoi(StrPtr(number$))
End FUNCTION
' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
DECLARE FUNCTION c_atol CDECL LIB "MSVCRT.DLL" ALIAS "atol" (ByVal ptxt as DWORD) as LONG
FUNCTION atol(number$) as LONG
FUNCTION = c_atol(StrPtr(number$))
End FUNCTION
' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤