gbdk-releases/gbdk-lib/libc/gb/arand.s

121 lines
2.6 KiB
ArmAsm
Raw Permalink Normal View History

2015-01-10 16:25:06 +01:00
;/***************************************************************************
; * *
; * Module : arand.s *
; * *
; * Purpose : A random number generator using the lagged additive method *
; * *
; * Version : 1, January 11 1998 *
; * *
; * Author : Luc Van den Borre ( Homepage : NOC.BASE.ORG ) *
; * *
; **************************************************************************/
2015-01-10 16:25:08 +01:00
;; BANKED: checked
2015-01-10 16:25:06 +01:00
.include "global.s"
.globl .initrand
.globl _rand
.area _BSS
.randarr:
.ds 55
.raxj:
.ds 0x01
.raxk:
.ds 0x01
.area _CODE
;; arand() operates on an array of 55 arbitrary values (here : bytes).
;; It adds two values of the array together, replaces one of the values
;; with the result, and returns the result.
;; At start, the indices into the array refer to the 55th and 24th element.
;; After each call, each index is decreased, and looped around if necessary.
;; This kind of works, but the values produces are less good than those by
;; rand(), mainly because it operates on bytes instead of words.
;; Ref : D. E. Knuth, "The Art of Computer Programming" , Volume 2
;;
;; Exit conditions
;; DE = Random number (byte!)
;;
;; Registers used:
;; all
;;
2015-01-10 16:25:08 +01:00
_arand:: ; Banked
2015-01-10 16:25:06 +01:00
PUSH BC
2015-01-10 16:25:08 +01:00
LD D,#0
LD HL,#.randarr-1
LD A,(.raxj)
LD E,A
2015-01-10 16:25:06 +01:00
DEC A ; Decrease the pointer
2015-01-10 16:25:08 +01:00
JR NZ,1$
LD A,#55
2015-01-10 16:25:06 +01:00
1$:
2015-01-10 16:25:08 +01:00
LD (.raxj),A
ADD HL,DE
LD B,(HL)
2015-01-10 16:25:06 +01:00
2015-01-10 16:25:08 +01:00
LD HL,#.randarr-1 ; Ooh...
LD A,(.raxk)
LD E,A
2015-01-10 16:25:06 +01:00
DEC A ; Decrease the pointer
2015-01-10 16:25:08 +01:00
JR NZ,2$
LD A,#55
2015-01-10 16:25:06 +01:00
2$:
2015-01-10 16:25:08 +01:00
LD (.raxk),A
ADD HL,DE
LD A,(HL)
2015-01-10 16:25:06 +01:00
2015-01-10 16:25:08 +01:00
ADD A,B
LD (HL),A ; Store new value
2015-01-10 16:25:06 +01:00
POP BC
2015-01-10 16:25:08 +01:00
LD D,#0
LD E,A
2015-01-10 16:25:06 +01:00
RET
;; _initarand calls the _rand function to fill the array with random values
;; Note that this also sets the seed value of the _rand function first,
;; like _initrand
;;
;; Exit conditions
;; None
;;
;; Registers used:
;; all
;;
2015-01-10 16:25:08 +01:00
_initarand:: ; Banked
LDA HL,.BANKOV(SP)
2015-01-10 16:25:06 +01:00
CALL .initrand
PUSH BC
2015-01-10 16:25:08 +01:00
LD A,#55
LD HL,#.randarr
2015-01-10 16:25:06 +01:00
1$:
DEC A
2015-01-10 16:25:08 +01:00
LD (.raxj),A
LD B,H
LD C,L
2015-01-10 16:25:06 +01:00
CALL _rand
2015-01-10 16:25:08 +01:00
LD H,B
LD L,C
2015-01-10 16:25:06 +01:00
2015-01-10 16:25:08 +01:00
LD (HL),D
2015-01-10 16:25:06 +01:00
INC HL
2015-01-10 16:25:08 +01:00
LD (HL),E
2015-01-10 16:25:06 +01:00
INC HL
2015-01-10 16:25:08 +01:00
LD A,(.raxj)
2015-01-10 16:25:06 +01:00
CP #0
2015-01-10 16:25:08 +01:00
JR NZ,1$
2015-01-10 16:25:06 +01:00
2015-01-10 16:25:08 +01:00
LD A,#24 ; Now the array has been filled,set the pointers
LD (.raxj),A
LD A,#55
LD (.raxk),A
2015-01-10 16:25:06 +01:00
POP BC
RET