; pink noise (1/f) generator
; (actually white noise into a one-pole low-pass filter)
; based on noise generator from Dr. Bubb but extended to 24 bits
; uses simple one-tap recursive filter
;
; written by: Quinn Jensen (jensenq@qcj.icon.com)
;

include "tdsg.a56"
;***************************************************************
;
;	sample rate computations
;
;***************************************************************

dot
	org	x:$10

NSTATE  dc      1               ;STATE OF NOISE GENERATOR (SHIFT REG)


	org	y:$0

	org	p:dot		;go back to P-space
;
; non-interrupt code
;

hf_init
        MOVE    #$FEEDEE,X0         ;INITIAL STATE OF NOISE GENERATOR
        MOVE    X0,X:<NSTATE
	rts

;
; fs = 32.552083 kHz
;

hf_comp
	jsr	<saveregs
	jsr	NOISE
	move		#.005,x1
	move		#.990,y1
	move		a,x0
	mpyr	x0,x1,a	x:<out_l,x0
	macr	x0,y1,a
	move		a,x:<out_l
	jsr	NOISE
	move		a,x0
	mpyr	x0,x1,a	x:<out_r,x0
	macr	x0,y1,a
	move		a,x:<out_r
	jsr	<restregs
	rts

;       NOISE GENERATION ROUTINE.  THIS ROUTINE USES A 15 BIT SHIFT
;       REGISTER LEFT JUSTIFIED IN THE VARIABLE "NSTATE".  AFTER THE STATE
;       IS LOADED, IT IS CHECKED TO SEE IF IT IS NORMALIZED.  IF IT IS
;       NORMALIZED (TOP TWO BITS ARE DIFFERENT), A 1 IS SET AS THE INPUT
;       TO THE SHIFT REGISTER AND THE REGISTER IS SHIFTED AND SAVED.
;
;         B23     B22                            B9      B8
;        ______________________________________________
;       | S14   | S13 |                        | S0   |
;       |       |     |      . . .             |      |<----------
;       |_______|_____|________________________|_______          |
;           |      |                                             |
;            \    /                                              |
;              XOR                                               |
;               \_________________________________________________
;
;
;       ASSUMES SCALING MODE IS OFF
;
NOISE                                   ;DO NOISE GENERATION LOOP
        CLR     B       X:<NSTATE,A     ;GET A ZERO IN B
        TST     A   #>$000001,X0        ;CHECK A, GET A 1 IN LSB POSITION
        TNR     X0,B                    ;IF NORMALIZED, THEN XOR=1
        ADD     B,A                     ;SET LSB
        ASL     A                       ;SHIFT BITS
        MOVE    A1,X:<NSTATE            ;SAVE STATE
        RTS                             ;RETURN WITH STATE

        END
