; basic configuration

;
        Title "multiplexorr."
;
        list P = 16F877
;
        include "p16f877.inc"  ; use definition file for 16F877
;
	__CONFIG b'11111101111001'



;
; memory - counters and max timing values in memory + rot value list
        CBLOCK 0x20   ; RAM starts at address 20h
del1
del
dur1
tmpsped1
tmpsped2
tmpsped3
tmpsped4
sped1
dir1
dur2
sped2
dir2
dur3
sped3
dir3
vidsel
viddur
viddur1
sped4
inbit
oldinbit
olderbit
indel
val1
val2
val3
val4
latch1
step1
step2
step3
msd
lsd
durr3
tmpdurr3
inner1
led1
gendur1
gendur2
gendur3	
	ENDC
;
        org 0x0000      ; start address = 0000h
	nop
	goto start
	nop

Table1    addwf PCL, 1
	  nop
	  retlw d'5'
	  retlw d'6'
	  retlw d'10'
	  retlw d'9'  

Table2	addwf PCL, 1
	nop
	retlw 1
	retlw 2
	retlw 4
	retlw 8
	retlw 1
	retlw 2
	retlw 4
	retlw 8
	retlw 1
	retlw 2
	retlw 4
	retlw 8
	retlw 1
	retlw 2
	retlw 4
	retlw 8

	
;
; set up I/O ports - all digital outs except portb digital in
start   movlw b'00000000'       ; all port pins = low
        movwf PORTA
        movlw b'00000000'
        movwf PORTC
        movlw b'00000000'
        movwf PORTD
        movlw b'00000000'
        movwf PORTE
	bcf STATUS,RP1
        bsf STATUS,RP0  ; set RAM Page 1 for TRIS registers

; INITIALISE PORTS
; binary used to see individual pin IO status

        movlw b'00000000'       ; all IO pins = outputs
        movwf TRISA
        movlw b'11111111'
        movwf TRISB
        movlw b'00000000'
        movwf TRISC
        movlw b'00000000'
        movwf TRISD
        movlw b'00000000'
        movwf TRISE
        movlw b'00000110'       ; all analog pins = digital
        movwf ADCON1

        bcf STATUS,RP0  ; back to RAM page 0

; zero variables

       movlw 0x00
	movwf latch1
	movwf led1
       movwf dur1
       movwf dur2
       movwf dur3
       movwf dir1
       movwf dir2
       movwf dir3
       movwf vidsel
       movwf indel       
       movlw 0x01
       movwf step1
       movwf step2
       movwf step3
       
       movlw 4
	movwf inner1
	movlw 0x05
	movwf sped4
	movwf tmpsped4	
	movlw 0x02
	movwf tmpdurr3
	movwf durr3
	movlw 0x10
       movwf sped1
       movwf sped2
       movwf sped3
       movwf tmpsped1
       movwf tmpsped2
       movwf tmpsped3
       movwf tmpsped4
	movlw 0x05
	movwf viddur1	
	movwf viddur
	movlw 0x20
	movwf gendur1
	movwf gendur2
	movwf gendur3	
		
;main loop

Loop	movf PORTB,0	;	input value from portb
	movwf inbit;

	
;		rot 1,2,3 + vidswitch decisions and timing
; if respective durs not up then do new decisions=set speed and dur and dir

; speed 
	decfsz inner1,1
	goto endlay
	movlw d'20'
	movwf inner1	
	decfsz tmpsped1,1
	goto lay2
	call Layer1
lay2	decfsz tmpsped2,1
	goto lay3
	call Layer2
lay3	decfsz tmpsped3,1
	goto lay4
	call Layer3
lay4	decfsz tmpsped4,1
	goto endlay
	call Layer4	

;				output /select porta / laser out / rot value out / vidswitch out / led

; val1,2,3,4 - latch then value

;val1 and 2 on first latch

endlay  
	swapf val2,0
	addwf val1,0
	clrf PORTA
	movwf PORTD		
	bsf PORTA,0		
;	movlw D'2'                                                                 
;	movwf del  
;	call yadelay       

; second latch

	movf val3,0
	clrf PORTA
	movwf PORTD
	bsf PORTA,1
;	movlw D'2'                                                                 
;	movwf del  
;	call yadelay       
	
; third latch

	btfss latch1,0
	goto endthird
	movf val4,0
	clrf PORTA
	movwf PORTD
	bsf PORTA,2
;	movlw D'2'                                                                 
;	movwf del  
;	call yadelay  


; laser out
; latch

endthird	bcf latch1,0     	
		movf inbit,0
	movwf PORTC
	call Laslatch2
	movf oldinbit,0
	movwf PORTC
	call Laslatch1
	
	
;led if we have data flow
	movf inbit,0
	xorwf oldinbit,1
	btfss STATUS,Z		
	call Led		
	movf inbit,0
	movwf oldinbit	
;	movlw D'100'                                                                 
;	movwf del  		
;	call yadelay       
	goto Loop
	
; subs  various delays

Newdelay	movlw 0x03              ; ????
                movwf   msd             ; 
                clrf    lsd             ;
loop2		decfsz  lsd, f          ; delay time = msd * ((3 * 20 *256) + 3) * tcy
                goto    loop2           ;
                decfsz  msd, f          ;
                goto    loop2           ;
                return

yadelay		
		movlw D'142'                                                                
		movwf del1                                                    
		nop                                                                         
		nop           
yadelay1	nop
		nop
		nop
		nop
		decfsz del1, 1                                                
		goto yadelay1                                                             
		nop                                                                         
		decfsz del, 1   
		goto yadelay                                                           
		nop                                                                         
		return

Laslatch1 bcf PORTA,4
	  bsf PORTA,5
	  return

Laslatch2 bcf PORTA,5
	  bsf PORTA,4
	  return

Led	  movf led1,0
	  xorlw 8
	  movwf PORTA
	 movwf led1
	 movf oldinbit,0	 
	 movwf olderbit
	  return

; deal with output dpendent on dir here

Layer1	decfsz gendur1,1
	goto laye1
la1	movlw 0x03
	movwf gendur1
	decfsz dur1,1
	goto laye1
	call Decision1
	; do output based on dir here
laye1	btfss dir1,0
	call Bac1
	btfsc dir1,0
	call For1
	; val1 is step1 in array location
	movf sped1,0
	movwf tmpsped1
	return

Layer2	decfsz gendur2,1
	goto laye2
la2	movlw 0x03
	movwf gendur2
	decfsz dur2,1
	goto laye2
	call Decision2
	; do output based on dir here
laye2	btfss dir2,0
	call Bac2
	btfsc dir2,0
	call For2
	; val1 is step1 in array location
	movf sped2,0
	movwf tmpsped2	
	return

Layer3	decfsz tmpdurr3,1
	return	
	decfsz gendur3,1
	goto laye3
	movlw 0x03
	movwf gendur3
Inner3	decfsz dur3,1
	goto laye3
	call Decision3
	; do output based on dir here
laye3	btfss dir3,0
	call Bac3
	btfsc dir3,0
	call For3
	movf durr3,0
	movwf tmpdurr3
	movf sped3,0
	movwf tmpsped3
	; val1 is step1 in array location
	return

Layer4	decfsz viddur1,1	
	goto laye4
	decfsz viddur,1
	goto laye5
	call Decision4
; put speed back
laye5	movlw 0x10
	movwf viddur1	
laye4	movf sped4,0
	movwf tmpsped4
	return  

Decision1 movf olderbit,0
	  andlw 0x1f
	  movwf sped1
	  incf sped1,1
	  movf inbit,0
	  andlw 0x1f
	  movwf dur1
	  incf dur1,1
	  btfsc inbit,0
	  bcf dir1,0
	  btfss inbit,0
	  bsf dir1,0
	  return ; set speed1/dir1/dur1 from inbit

Decision2 movf inbit,0
	  andlw 0x1f
	  movwf sped2
	  incf sped2,1
	  movf olderbit,0
	  andlw 0x1f
	  movwf dur2
	  incf dur2,1
	  btfsc olderbit,0
	  bcf dir2,0
	  btfss olderbit,0
	  bsf dir2,0
	  return ; set speed1/dir1/dur1 from inbit

Decision3 movf olderbit,0
	  andlw 0x1f
	  movwf sped3
	  incf sped3,1
	  movf inbit,0
	  andlw 0x1f
	  movwf dur3
	  incf dur3,1
	  btfsc inbit,0
	  bcf dir3,0
	  btfss inbit,0
	  bsf dir3,0
	  return ; set speed1/dir1/dur1 from inbit

Decision4 movf inbit,0
	andlw d'15'
	movwf val4
	incf val4,0
	call Table2	
	movwf val4
	movf inbit,0
	andlw 0x1f
	movwf viddur
	incf viddur,1 
	bsf latch1,0
	  return ; speed is constant/ set dur ALSO output new value

Bac1	decf step1,1
	btfss step1,7
	goto bacc1
	movlw 0x03
	movwf step1
bacc1	incf step1,0		
	call Table1 
	movwf val1
	  return

Bac2	decf step2,1
	btfss step2,7
	goto bacc2
	movlw 0x03
	movwf step2
bacc2	incf step2,0
	call Table1 
	movwf val2
	  return


	
Bac3	decf step3,1
	btfss step3,7
	goto bacc3
	movlw 0x03
	movwf step3
bacc3	incf step3,0
	call Table1 
	movwf val3
	  return
	
For1	  movlw 4
	  incf step1,1
	  subwf step1,0
	  btfsc STATUS,C
	  movwf step1
	incf step1,0
	  call Table1
	movwf val1
	  return

For2	  movlw 4
	  incf step2,1
	  subwf step2,0
	  btfsc STATUS,C
	  movwf step2
	  incf step2,0
	  call Table1
	movwf val2
	  return

For3	  movlw 4
	  incf step3,1
	  subwf step3,0
	  btfsc STATUS,C
	  movwf step3
	  incf step3,0
	  call Table1
	movwf val3
	  return

	
		
	end
	
		

