Commits

ChrisLowe committed df1a0bc

Added pseudo random seeder

Comments (0)

Files changed (1)

+;;
+;    by @lowey2002
+;
+;  Generates a fresh pseudo random
+;  seed by asking the user to press enter
+;  and calculating fibonacci while it waits.
+;
+;  Each time you run this it *should*
+;  generate three different random numbers.
+;
+;  It's not perfect because you can occasionally
+;  press enter the exact same number of cycles as
+;  you did before but it is better than nothing.
+
+
+SET A, press_enter_string
+SET B, 1
+JSR print_message
+JSR generate_seed
+
+;generate 5 random numbers between 1 and 100
+
+
+; random number 1
+SET A, 1
+SET B, 100
+JSR pseudorandom
+SET B, last_random
+JSR itoa
+SET A, last_random
+SET B, 3
+JSR print_message
+
+; random number 2
+SET A, 1
+SET B, 100
+JSR pseudorandom
+SET B, last_random
+JSR itoa
+SET A, last_random
+SET B, 4
+JSR print_message
+
+; random number 3
+SET A, 1
+SET B, 100
+JSR pseudorandom
+SET B, last_random
+JSR itoa
+SET A, last_random
+SET B, 5
+JSR print_message
+
+SET PC, end
+
+
+
+
+
+
+JSR end
+
+
+
+
+
+
+:generate_seed
+SET [0x9000], 0
+;preserve X, Y & Z
+SET PUSH, X
+SET PUSH, Y
+SET PUSH, Z
+SET X, 1
+SET Y, 1
+SET Z, 1
+
+
+:generate_seed_loop
+IFE [0x9000], 0         ;; no input
+    SET PC, generate_seed_waiting
+
+IFE [0x9000], 0xD       ;; enter pressed
+    SET PC, generate_seed_end
+IFE [0x9000], 0xA
+    SET PC, generate_seed_end
+
+:generate_seed_waiting
+ADD Z, Y
+SET Y, X
+SET X, Z
+SET PC, generate_seed_loop
+
+
+:generate_seed_end
+SET [seed], Z
+SET Z, POP
+SET Y, POP
+SET X, POP
+SET PC, POP
+
+
+
+; Parameters
+;   A - min
+;   B - max
+;   [seed]
+; Returns
+;   A - random number
+:pseudorandom
+SET PUSH, X
+SET PUSH, I
+SET X, [seed]
+MUL X, 0xE3D1
+ADD X, 0x2B69
+SHR X, 3
+SET I, B
+SUB I, A
+MOD X, I
+ADD X, A
+SET [seed], X    ;; new seed
+SET A, X
+SET I, POP
+SET X, POP
+SET PC, POP
+
+
+;;
+;;        Print_Message
+;;
+;; Parameters:
+;;    A - pointer to string
+;;    B - line number
+;;
+:print_message
+MUL B, 0x0020
+ADD B, 0x8000
+
+:print_message_loop
+IFE [A], 0
+SET PC, POP
+SET [B], [A]
+BOR [B], 0x7000
+ADD A, 1
+ADD B, 1
+SET PC, print_message_loop
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;           Convert integer to string
+;;                    (itoa)
+;;
+;;
+;;  Paramters
+;;     A - the integer
+;;     B - the address of the destination string
+;;
+;;  Notes
+;;     - address string must be a DAT with 0x5 reserved
+;;       to prevent overflow
+;;     - no support for radix or sign
+;;     - 0 will evaluate '0' or 0x30
+;;
+
+:itoa
+IFE A, 0
+SET PC, itoa_zero_string
+SET J, 0        ; stack count
+
+:itoa_loop1
+IFE A, 0
+SET PC, itoa_loop1_end
+SET I, A
+MOD I, 0xa      ; 10
+DIV A, 0xa      ; 10
+SET PUSH, i     ; the integer at this magnitude
+ADD J, 1        ; next magnitude
+SET PC, itoa_loop1
+
+:itoa_loop1_end
+SET Z, 0        ; character count
+
+:itoa_loop2
+IFE J, 0        ; stack cleared, all values accumulated
+SET PC, itoa_loop2_end
+SET I, POP
+SET A, 0x30     ; add '0' to get the ASCII value
+ADD A, I
+SET C, B
+ADD C, Z
+SET [C], A
+ADD Z, 1        ; next character
+SUB J, 1        ; decrement stack count
+SET PC, itoa_loop2
+
+:itoa_loop2_end SET C, B
+ADD C, Z
+SET [C], 0x0 ; null terminate
+:itoaret SET A, Z
+SET PC, POP
+
+:itoa_zero_string
+SET [B], 0x30
+ADD B, 1
+SET [B], 0
+SET PC, POP
+
+
+
+
+:end
+SET PC, end
+
+:seed
+DAT 0
+
+:last_random
+DAT 0,0,0,0,0
+
+:press_enter_string
+DAT "Press [ENTER] to start", 0
+