
#include <p16f876a.inc>
#DEFINE BANK0 BCF STATUS,5
#DEFINE BANK1 BSF STATUS,5


			__CONFIG        _BODEN_OFF & _CP_OFF & _CPD_OFF &_WRT_OFF & _PWRTE_OFF & _WDT_OFF & _LVP_OFF & _HS_OSC & _DEBUG_OFF
			
			LIST	P=16F876A

			  
			

;VARIABLES-----------------------------------------------------------------


		CBLOCK	H'20'

LC			
LOC1						
CHRLOOP			
SCROFFLO			
POSLOOP
FSRL
FSRADRL
POSCNT
TIMER1
TIMER2
EECNT
SHUFCNT
EPFSR
CSLW
CSUP
FALOOP
EPADR
EPDATA
PGMUP
PGMLW
PGMDATA
BUFCNT
MESUP
MESLW
MESEND
SPD1
SPD2

		ENDC

	ORG	H'1B00'				;	START ADR OF CHAR.SET 256 BYTES

		DE	0,0,0,0,0		;	ASCII DEC 00
		DE	0,0,0,0,0
		DE	0,0,0,0,0
		DE	0,0,0,0,0
		DE	0,0,0,0,0
		DE	0,0,0,0,0
		DE	0,0,0,0,0
		DE	0,0,0,0,0
		DE	0,0,0,0,0
		DE	0,0,0,0,0
		DE	0,0,0,0,0
		DE	0,0,0,0,0
		DE	0,0,0,0,0
		DE	0,0,0,0,0
		DE	0,0,0,0,0
		DE	0,0,0,0,0
		DE	0,0,0,0,0
		DE	0,0,0,0,0
		DE	0,0,0,0,0
		DE	0,0,0,0,0
		DE	0,0,0,0,0
		DE	0,0,0,0,0
		DE	0,0,0,0,0
		DE	0,0,0,0,0
		DE	0,0,0,0,0
		DE	0,0,0,0,0
		DE	0,0,0,0,0
		DE	0,0,0,0,0
		DE	0,0,0,0,0
		DE	0,0,0,0,0
		DE	0,0,0,0,0
		DE	0,0,0,0,0		;	ACSII DEC 31		
		DE	0,0,0,0,0		;SPC	ASCII DEC 32
		DE	0,0,95,0,0		;!
		DE	0,7,0,7,0		;"
		DE  20,127,20,127,20	;#
		DE	36,42,127,42,18		;$
		DE	35,19,8,100,98		;%
		DE	54,73,85,34,80		;&
		DE	0,0,3,0,0		;'
		DE	0,28,34,65,0		;(
		DE	0,65,34,28,0		;)
		DE	34,20,127,20,34		;*
		DE	8,8,62,8,8		;+
		DE	0,80,48,0,0		;,
		DE	8,8,8,8,8		;-
		DE	0,96,96,0,0		;.
		DE	32,16,8,4,2		;/
		DE	62,81,73,69,62		;0
		DE	68,66,127,64,64		;1
		DE	66,97,81,73,70		;2
		DE	34,65,73,73,54		;3
		DE	24,20,18,127,16		;4
		DE	47,73,73,73,49		;5
		DE	60,74,73,73,48		;6
		DE	1,113,9,5,3		;7
		DE	54,73,73,73,54		;8
		DE	6,73,73,41,30		;9				
		DE	0,54,54,0,0		;:
		DE	0,86,54,0,0		;;
		DE	8,20,34,65,0		;<
		DE	20,20,20,20,20		;=
		DE	0,65,34,20,8		;>
		DE	2,1,81,9,6		;?
		DE	50,73,121,65,62		;@
		DE	126,9,9,9,126		;1C45 IS WERE A STARTS
		DE	127,73,73,73,54		;B
		DE	62,65,65,65,34		;C
		DE	127,65,65,65,62		;D
		DE	127,73,73,73,65		;E
		DE	127,9,9,9,1		;F
		DE	62,65,65,81,114		;G
		DE	127,8,8,8,127		;H
		DE	65,65,127,65,65		;I
		DE	32,64,64,64,63		;J
		DE	127,8,20,34,65		;K
		DE	127,64,64,64,64		;L
		DE	127,2,12,2,127		;M
		DE	127,4,8,16,127		;N
		DE	62,65,65,65,62		;O
		DE	127,9,9,9,6		;P
		DE	62,65,81,33,94		;Q
		DE	127,9,25,41,70		;R
		DE	38,73,73,73,50		;S
		DE	1,1,127,1,1		;T
		DE	63,64,64,64,63		;U
		DE	7,24,96,24,7		;V
		DE	63,64,56,64,63		;W
		DE	99,20,8,20,99		;X
		DE	3,4,120,4,3		;Y
		DE	97,81,73,69,67		;Z
		DE	127,65,65,0,0		;[
		DE	21,22,124,22,21		;splat
		DE	65,65,127,0,0		;]
		DE	4,2,1,2,4		;^
		DE	64,64,64,64,64		;_
		DE	0,1,2,4,0		;`
		DE	32,84,84,84,120		;a
		DE	127,72,68,68,56		;b
		DE	56,68,68,68,32		;c
		DE	56,68,68,72,127		;d
		DE	56,84,84,84,24		;e
		DE	8,126,9,1,2		;f
		DE	12,82,82,82,62		;g
		DE	127,8,4,4,120		;h
		DE	0,68,125,64,0		;i
		DE	32,64,68,61,0		;j
		DE	127,16,40,68,0		;k
		DE	0,65,127,64,0		;l
		DE	124,4,24,4,120		;m
		DE	124,8,4,4,120		;n
		DE	56,68,68,68,56		;o
		DE	124,20,20,20,8		;p
		DE	8,20,20,24,124		;q
		DE	124,8,4,4,8		;r
		DE	72,84,84,84,32		;s
		DE	4,63,68,64,32		;t
		DE	60,64,64,32,124		;u
		DE	28,32,64,32,28		;v
		DE	60,64,48,64,60		;w
		DE	68,40,16,40,68		;x
		DE	12,80,80,80,60		;y
		DE	68,100,84,76,68		;z
		DE	0,0,8,54,65		;{
		DE	0,0,127,0,0		;|
		DE	0,65,54,8,0		;}	ASCII 125
		DE	0,0,0,0,0		;	ASCII 126
		DE	0,0,0,0,0		;	ASCII 127
		DE	0,0,0,0,0		;	ASCII 128
		DE	65,65,65,65,65		;	ASCII 129
		DE	34,34,34,34,34		;	ASCII 130
		DE	20,20,20,20,20		;	ASCII 131
		DE	8,8,8,8,8		;	ASCII 132



	ORG	H'1300'
		

		DE "D.I.Y Scrolling display project.2048 character message memory,38x7 10mm blue led display."
  		DE "No need for PC'S once the message has been stored in the PIC."
  		DE "Future plans to add a handheld programmer which will be RF linked to the display."
  		DE "Visit pc-sys.co.uk for details on how to contact me if you wish to build this project."
  		DE "   This website is under construction.   "
  		DE "PC-SYS.CO.UK            PAUL@paulcollett.fsnet.co.uk."
		
		DE 0  			;TELL DISPLAY MESSAGE END

		

			ORG	0
			GOTO 	RESET

;SUBS END WITH RETURN-----------------------------------------------------------------------

LEDDELAY	


;		CALL	ADJDELAY	;CAN BE USED TO SET DISPLAY SPEED
;		RETURN

		MOVLW   D'14'      	;TIMER 2 VALUE  	
                MOVWF   TIMER2
LOOP1       	MOVLW   D'50'		;TIMER 1 VALUE.(DECREMENT THIS NO TILL 0 AND REPEAT 2 TIMES (VALUE OF TIMER2))	      		
                MOVWF   TIMER1
LOOP2		DECFSZ  TIMER1,F
                GOTO    LOOP2
                DECFSZ  TIMER2,F
                GOTO    LOOP1
		RETURN

ADJDELAY				;THIS SUB ISN'T USED.CAN BE USED TO SET THE DISPLAY SPEED BY USING AD ON PINS 2&3
		MOVF    SPD2,W      	;TIMER 2 VALUE  SET BY A2D	
                MOVWF   TIMER2
ALOOP1       	MOVF	SPD1,W		;TIMER 1 VALUE. SET BY A2D	      		
                MOVWF   TIMER1
ALOOP2		DECFSZ  TIMER1,F
                GOTO    ALOOP2
                DECFSZ  TIMER2,F
                GOTO    ALOOP1
		RETURN

CKPSF		BCF	PORTC,7		;THIS SUB SENDS 0 TO DATA THEN GIVES CLOCK PULSE TO POS REGS
		BSF	PORTB,7
		CALL	PULSEDELAY
		BCF	PORTB,7
		CALL	PULSEDELAY
		RETURN

CKPST		

		BSF	PORTC,7		;THIS SUB SENDS 1 TO DATA THEN GIVES CLOCK PULSE TO POS REGS
		CALL	PULSEDELAY
		BSF	PORTB,7
		CALL	PULSEDELAY
		BCF	PORTB,7
		BCF	PORTC,7
		CALL	PULSEDELAY
		RETURN

PULSEDELAY
		MOVLW	D'2'		;TIMER 1 VALUE THE LARGER THE LONGER THE DELAY
		MOVWF	TIMER1
PDLOO		DECFSZ	TIMER1,F
		GOTO	PDLOO
		RETURN

POSCLR		
		CLRF	PORTB
		CLRF	PORTC
		MOVLW	D'20'		;CLEAR ALL POS SHIFT REGISTERS
		MOVWF	POSLOOP
PSL		CALL	CKPSF
		DECFSZ	POSLOOP
		GOTO 	PSL		;THE ABOVE CODE SIMPLY TURNS OFF ENTIRE DISPLAY.
		RETURN



LOCCLEAR	MOVLW	D'39'		;THIS SUB CLEARS LOCS A0~A38
		MOVWF	LC
		MOVLW	H'A0'		
		MOVWF	FSR				
LCLOOP		CLRF	INDF		
		INCF	FSR,F		
		DECFSZ	LC,F
		GOTO	LCLOOP					
		RETURN			;END OF SUB


SHOWLOCS				;THIS SUB SHOWS LOCS A0~ + 37 'D' ON THE SCREEN AND THEN RETURNS
BEGIN		MOVLW	D'19'
		MOVWF	POSCNT	
		MOVLW	H'A0'
		MOVWF	FSRADRL
		MOVF	FSRADRL,W
		MOVWF	FSRL				
NXTDATA		MOVF	FSRL,W
		MOVWF	FSR
		MOVF	INDF,W
		
		XORLW	D'127'		;These extra lines fixes the leakage bug,
		ANDLW	D'127'		;basicly only sending logic 1s to the leds
		BANK1			;and going high impedence (set as inputs)
		MOVWF	TRISB		;Adding 14 diodes to the pic lines would of done the same job.
		BANK0			; So the extra code stops the pic going logic 0 on the data lines.
		XORLW	D'127'
		MOVWF	PORTB		

		CALL	LEDDELAY

		MOVLW	D'127'		;Had to add these extra lines because the leds after
		BANK1			;a while started to leak
		MOVWF	TRISB		;Random leds would light up because others were leaking
		BANK0			;back ov switched from the pics data lines.

		DECF	POSCNT,F
		BTFSC	STATUS,Z
		GOTO	SHOWR
		INCF	FSRL,F
		CALL	CKPSF
		GOTO	NXTDATA
SHOWR		INCF	FSRL,F
		MOVLW	D'19'
		MOVWF	POSCNT	
		CALL	CKPST
NXTDATAR	MOVF	FSRL,W
		MOVWF	FSR
		MOVF	INDF,W		
		
		XORLW	D'127'
		ANDLW	D'127'
		BANK1
		MOVWF	TRISC
		BANK0
		XORLW	D'127'
		MOVWF	PORTC	

		CALL	LEDDELAY
		
		MOVLW	D'127'
		BANK1
		MOVWF	TRISC
		BANK0

		DECF	POSCNT,F
		BTFSC	STATUS,Z
		GOTO	SHWDL
		INCF	FSRL,F
		CALL	CKPSF
		GOTO	NXTDATAR
SHWDL		CALL	CKPST
		RETURN



INIT					;INIT ROUTINE

		MOVLW	B'00000111'	;DISABLE COMPS.
		MOVWF	CMCON		;
		CLRF	INTCON		;DISABLE INTERUPTS

		BANK1			;SELECT BANK1
					;Disable pull-ups
					;INT on rising edge
					;TMR0 to CLKOUT
					;TMR0 Incr low2high trans.
					;Prescaler assign to Timer0
					;Prescaler rate is 1:256
		MOVLW	B'11010111'	;Set PIC options (See datasheet).
		MOVWF	OPTION_REG	;Write the OPTION register.
		MOVLW	D'6'
		MOVWF	ADCON1		;SET PORT A AS DIGITAL I/O'S NOT AS AD CVONVERTORS
					;START UP AS A/D PINS NOT AS DIGITAL I/O PINS WHY ?

		MOVLW	B'00000000'	;
		MOVWF	TRISB		;ALL PORT B OUTPUTS 						
		MOVWF	TRISC		;ALL PORT C OUTPUTS 
		MOVLW	B'11111111'	;ALL PORT A INPUTS
		MOVWF	TRISA
		BANK0			;SELECT BANK0
		CLRF	PORTB		;PORTB CLEAR
		CLRF	PORTC		;PORTC CLEAR
		CLRF	PORTA		;PORTA CLEAR
		CLRF	LOC1
		CLRF	MESEND
		RETURN			;END OF SUB


SHUFFLE		MOVLW	H'A0'		;SHUFFLE SUB ROUTINE
		MOVWF	FSRADRL
		MOVLW	D'0'
		BANK1
		MOVWF	H'CB'
		BANK0
		MOVLW	D'43'
		MOVWF	SHUFCNT
		MOVF	FSRADRL,W
		MOVWF	FSR
SHFLOOP		INCF	FSR,f
		MOVF	INDF,W		
		DECF	FSR,F
		MOVWF	INDF
		INCF	FSR,F
		DECFSZ	SHUFCNT,F
		GOTO	SHFLOOP	
		RETURN
		

FINDADR
		MOVLW	H'1B'
		MOVWF	CSUP
		MOVLW	H'00'
		MOVWF	CSLW
		MOVLW	D'5'
		MOVWF	FALOOP
		MOVF	MESUP,W
		MOVWF	PGMUP
		MOVF	MESLW,W
		MOVWF	PGMLW
		CALL	PGMGET
ADDLO		MOVF	PGMDATA,W
		BTFSC	STATUS,Z
		GOTO	MESSEND
		ADDWF	CSLW,F
		BTFSC	STATUS,C
		GOTO	CSET
ADDLO2		DECFSZ	FALOOP,F
		GOTO	ADDLO
		RETURN
CSET		BCF	STATUS,C
		INCF	CSUP,F
		GOTO	ADDLO2
MESSEND		BSF	MESEND,1
		RETURN


PGMGET		MOVF	PGMUP,W			;THIS SUB READS THE VALUE STORED IN PROGRAM MEMORY
		BSF	STATUS,RP1		;POINTED TO BY PGMUP,PGMLW
		MOVWF	EEADRH			;PGMUP=UPR VALUE OF ADR TO BE READ
		BCF	STATUS,RP1
		MOVF	PGMLW,W
		BSF	STATUS,RP1
		MOVWF	EEADR			;PGMLW=LWR VALUE OF ADR TO BE READ
		BSF	STATUS,RP0
		BSF	EECON1,EEPGD
		BSF	EECON1,RD
		NOP
		NOP
		BCF	STATUS,RP0		;BANK2
		MOVF	EEDATA,W		
		BCF	STATUS,RP1		;BANK0
		MOVWF	PGMDATA			;STORE VALUE OF LSB TO PGMDATA
		RETURN

FILCHRBUF
		MOVLW	D'5'
		MOVWF	BUFCNT
		CALL	FINDADR
		BTFSC	MESEND,1
		RETURN
		MOVF	CSUP,W
		MOVWF	PGMUP
		MOVF	CSLW,W
		MOVWF	PGMLW
		MOVLW	H'C6'
		MOVWF	FSR
BUFNXT		CALL	PGMGET
		MOVF	PGMDATA,W
		
		MOVWF	INDF
		INCF	PGMLW,F
		BTFSS	STATUS,Z
		GOTO	BUFLO
		INCF	PGMUP,F
BUFLO		INCF	FSR,F
		DECFSZ	BUFCNT,F
		GOTO	BUFNXT
		RETURN

ANTOE		BANK1
		MOVLW	B'00000100'
		MOVWF	ADCON1
		BANK0
		MOVLW	B'10000001'	
		MOVWF	ADCON0
		BSF	ADCON0,2
WAITAD		BTFSC	ADCON0,2
		GOTO	WAITAD
		MOVF	ADRESH,W
		BTFSC	STATUS,Z
		MOVLW	D'1'
		MOVWF	SPD1
		
		BANK1
		MOVLW	B'00000100'
		MOVWF	ADCON1
		BANK0
		MOVLW	B'10001001'	
		MOVWF	ADCON0
		BSF	ADCON0,2
WAITAD2		BTFSC	ADCON0,2
		GOTO	WAITAD2
		MOVF	ADRESH,W
		BTFSC	STATUS,Z
		MOVLW	D'1'
		MOVWF	SPD2
		RETURN	



;-----------------------------------------------------------------------------------------------

RESET		CALL	INIT		;SET UP PIC AND I'O PINS CLEAR LOCS ETC
		CALL	LOCCLEAR	;SUB TO SEND 0 DATA TO LOCS H'A0' ONWARD				
		CALL	POSCLR		;RESET ALL SHIFT REGISTERS;SEND 1 PULSE WITH DATA HIGH TO SR'S (CLOCK PULSE TRUE)
		CLRF	EPFSR

NEW		MOVLW	H'13'		;UPR PROGRAM MEM LOC NO. OFF MESSAGE
		MOVWF	MESUP
		MOVLW	H'00'		;LWR PROGRAM MEM LO NO.OFF MESSAGE
		MOVWF	MESLW
		MOVLW	D'80'
		MOVWF	SCROFFLO
		CALL	ANTOE

		CALL	CKPST

RESTART		
		CALL	FILCHRBUF
		BTFSC	MESEND,1
		GOTO	SCROLLOFF
		MOVLW	D'6'
		MOVWF	CHRLOOP

HERE		CALL	ANTOE
		CALL	SHOWLOCS
		CALL	SHUFFLE
		
		DECFSZ	CHRLOOP,F
		GOTO	HERE
		INCFSZ	MESLW,F
		GOTO	RESTART
		INCF	MESUP,F
		MOVF	MESUP,W
		XORLW	H'1B'
		BTFSS	STATUS,Z
		GOTO	RESTART

SCROLLOFF	CALL	SHOWLOCS
		CALL	SHUFFLE
		DECFSZ	SCROFFLO,F
		GOTO	SCROLLOFF
		BCF	MESEND,1
		

		GOTO	NEW				
		END

		

