QB / QB64 Discussion Forum      Other Subforums, Links and Downloads
 

 Return to Index  

pure qbasic version

August 31 2011 at 3:11 AM
  (Login MCalkins)
Moderator


Response to this might be considered cheating.

 
I've glanced through disassembly of the Int 0x1a handler on my computer. It seems to be reading the time from 0040:006c. A google search confirmed that this is not unique to my computer.

Therefore, it is possible to implement my previous program entirely in QBASIC 1.1, without any usage of assembly.

I must emphasize that I have barely tested the various sub procedures of this program, other than to verify that the first 16 results from rand match MSVCRT's results using a seed of 1.

It seems that the first iteration of rand results in poor randomness when compared with similar seeds.

Note that the timer dword is read as 4 bytes individually. It is possible for the value to change while it is being read. This is okay, since it is only used to seed the pseudorandom number generator.

I intend to verify the correctness of the various sub procedures within the next few days. Even if they are already correct, I might tweak the code a little.

Regards,
Michael

P.S. I think it is elegant the way I emulate assembly instructions and syntax within QBASIC.

-------------------------------- rand1.bas

'public domain, augest 2011, michael calkins
'assumes that there is a dword timer value at 0x0040:0x006c
'minimally tested (minimally is an overstatement)
'no guarantees of correctness of any of the procedures.
'if you find any mistakes, please let me know.

DECLARE SUB srandwithtimer ()
DECLARE SUB rand ()
DECLARE SUB add (a AS LONG, b AS LONG)
DECLARE SUB mul (a AS LONG, b AS LONG)
DECLARE SUB shl (a AS LONG, b AS INTEGER)
DECLARE SUB shr (a AS LONG, b AS INTEGER)
DIM SHARED seed AS LONG
DIM SHARED result AS INTEGER
DIM p(0 TO 25) AS INTEGER
seed = 1
CLS
srandwithtimer
FOR i = 0 TO 25
 p(i) = i
NEXT
FOR i = 0 TO 25
 DO
  rand
 LOOP UNTIL result <= &H7FF7
 SWAP p(i), p(result MOD 26)
NEXT
FOR i = 0 TO 25
 PRINT CHR$(p(i) + &H61);
NEXT
PRINT
SYSTEM

SUB add (a AS LONG, b AS LONG)
 DIM x AS LONG
 DIM y AS LONG
 DIM c AS INTEGER
 x = (a AND &HFFFF&) + (b AND &HFFFF&)
 y = b
 shr a, &H10
 shr y, &H10
 a = a + y - (x > &HFFFF&)
 shl a, &H10
 a = a OR (x AND &HFFFF&)
END SUB

SUB mul (a AS LONG, b AS LONG)
 DIM t AS LONG
 DIM i AS INTEGER
 t = a
 a = 0
 FOR i = 0 TO &H1E
  IF b AND (2 ^ i) THEN add a, t
  shl t, 1
 NEXT
 IF b AND &H80000000 THEN add a, t
END SUB

SUB rand
 mul seed, 214013
 add seed, 2531011
 result = (seed AND &H7FFF0000) \ &H10000
END SUB

SUB shl (a AS LONG, b AS INTEGER)
 a = ((a AND ((2 ^ (&H1F - b)) - 1)) * (2 ^ b)) OR (&H80000000 AND ((a AND (2 ^ (&H1F - b))) <> 0))
END SUB

SUB shr (a AS LONG, b AS INTEGER)
 a = ((a AND &H7FFFFFFF) \ (2 ^ b)) OR ((2 ^ (&H1F - b)) AND ((a AND &H80000000) <> 0))
END SUB

SUB srandwithtimer
 DEF SEG = &H40
 seed = PEEK(&H6D) OR (PEEK(&H6E) * &H100&) OR (PEEK(&H6F) * &H10000)
 shl seed, 4
 seed = seed OR PEEK(&H6C)
END SUB


    
This message has been edited by MCalkins on Aug 31, 2011 3:21 AM


 
 Respond to this message   
Responses

 Copyright © 1999-2014 Network54. All rights reserved.   Terms of Use   Privacy Statement