di3227.txt ;****************************************************************************** ; ; LISTING 1 ; ; "Make noise with a PIC," EDN, August 7, 2003, pg 77 ; Copyright (c) 2003 Peter Guettler, APS Software Engineering GmbH, Koeln ; Non-commercial use granted. ; -------------------------------------------------------------------------- ; Filename : RND32E.ASM ; -------------------------------------------------------------------------- ; Scope : 31 Bit Pseudorandom generator ; -------------------------------------------------------------------------- ; Project : RND32 ; Version : 1.01 ; Date : 28-FEB-2003 ; Autor : P.Guettler ; -------------------------------------------------------------------------- ; History : ; Vers: Datum: Name: ; V1.01 28-FEB-2003 GUT(APS) Comments improved. ; V1.00 10-JUN-2001 GUT(APS) Program optimized. ; Cycle time is now constant 15Tc. Additional ; variable TEMP ("trade space for speed") ; V0.00 04-MAR-2001 GUT(APS) First release ; -------------------------------------------------------------------------- ; Info : ; ; The program generates random numbers with a 31 bit shift register. ; The 31 bit shift register requires only two feedback taps in contrast to ; a 32 bit shift register which requires 4 taps. ; Cycle time is 2^31 - 1 = 2147483647 states. At 4MHz oscillator frequency ; the program generates noise with spectral components ranging from 15.5uHz ; up to 33.3kHz. ; The random pattern repeats each 17.8 hours and is sufficient "random" for ; most audio frequency purposes. ; ; For a comprehensive table of Linear Feedback Shift Register Taps see ; XILINX app.note. XAPP 052 of July 7, 1996. ; ************************************************************************** ; Target: Microchip PIC12C508(A) / PIC12C509(A) ; Lower memory area: program ; Upper memory area: unused LIST P=12C509A ; Configuration word: ; ; MCLRE = 0 (disabled) ; CP = 0/1 (code protection on/off) ; WDTE = 0 (disabled) ; FOSC1 = 1 (internal oscillator) ; FOSC0 = 0 ; ==> 00AH (without code protection) ; 002H (with code protection) ; -------------------------------------------------------------------------- ; Constants ; -------------------------------------------------------------------------- INADR EQU 00H ; Indirect Address register TMR0 EQU 01H ; Timer 0 PCL EQU 02H ; lower 8 bits of Program Counter STATUS EQU 03H ; Status register FSR EQU 04H ; File select register OSCCAL EQU 05H ; Calibration register GPIO EQU 06H ; General Purpose I/O register F EQU 1 ; Direction of Operation = F-Register W EQU 0 ; Direction of Operation = W-Register #DEFINE Z STATUS,2 ; zero flag - bit 2 of STATUS reg #DEFINE C STATUS,0 ; carry flag - bit 0 of STATUS reg #DEFINE PA0 STATUS,5 ; page select bit (12C509 only) ; Sig. Port I/O Pin Description #DEFINE ENBL GPIO,4; I 3 High = Enable ; Generated random signal is output at GPIO,0 ; and each shifted by one bit at GPIO,1 and GPIO,2 ; -------------------------------------------------------------------------- ; Variables ; -------------------------------------------------------------------------- RND0 EQU 07H ; RND shift register byte 0 RND1 EQU 08H ; " byte 1 RND2 EQU 09H ; " byte 2 RND3 EQU 0AH ; " byte 3 TEMP EQU 0BH ; temporary storage for XOR feedback calculation ; -------------------------------------------------------------------------- ; Reset vektor ; -------------------------------------------------------------------------- ORG 0 LCOLD MOVWF OSCCAL ; calibrate internal oscillator GOTO MAIN ; -------------------------------------------------------------------------- ; Subroutines ; -------------------------------------------------------------------------- ; -------------------------------------------------------------------------- ; Main program ; -------------------------------------------------------------------------- ORG 100H MAIN ;-- Initialisation CLRWDT ; Clear WDT and prescaler MOVLW 0C7H ; init OPTION register: ; GPWU 1 (disabled) ; GPPU 1 (disabled) ; T0CS 0 (Timer0 as timer) ; T0SE 0 (positive edge) ; PSA 0 (Prescaler assigned to timer0) ; PS2 1 (Prescaler = 256) ; PS1 1 ; PS0 1 OPTION MOVLW 38H ; set TRIS register: xx111000 = GP0..GP2 as outputs TRIS GPIO BCF PA0 ; set page 0 CLRF FSR ; clear RAM pointer MOVLW 0AFH ; preset shift register with MOVWF RND0 ; 0x340550AF MOVLW 050H ; (any other value != 0 will also MOVWF RND1 ; do the job) MOVLW 005H MOVWF RND2 MOVLW 034H MOVWF RND3 LSTART BTFSS ENBL ; wait for ENBL = high GOTO LSTART ; calculate feedback value = Q27 XOR Q30 and put in carry flag: SWAPF RND3,W ; Q27 --> TEMP.7 MOVWF TEMP RLF RND3,W ; Q30 --> W.7 XORWF TEMP,F RLF TEMP,F ; CY = Q27 XOR Q30 RLF RND0,F ; shift random number, CY --> Q0 RLF RND1,F RLF RND2,F RLF RND3,F MOVF RND0,W ; output at GPIO,0..2 MOVWF GPIO GOTO LSTART ; repeat forever END