; 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
dur1
tmpsped1
tmpsped2
tmpsped3
tmpsped4
sped1
dir1
dur2
sped2
dir2
dur3
sped3
dir3
vidsel
viddur
viddur1
sped4
inbit
oldinbit
val1
val2
val3
val4
latch1
latch2
latch3
step1
step2
step3
durr3
tmpdurr3
inner1
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 latch2
	movwf latch3
       movwf dur1
       movwf dur2
       movwf dur3
       movwf dir1
       movwf dir2
       movwf dir3
       movwf vidsel
       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
nin	movlw 0x10
	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  btfss latch2,0
	goto slat
	swapf val2,0
	addwf val1,0
	clrf PORTA
	movwf PORTD		
	bsf PORTA,0		
;	movlw D'2'                                                                 
;	movwf del  
;	call yadelay       

; second latch
slat	btfss latch3,0
	goto thit
	movf val3,0
	clrf PORTA
	movwf PORTD
	bsf PORTA,1
;	movlw D'2'                                                                 
;	movwf del  
;	call yadelay       
	
; third latch

thit	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     	
		bcf latch2,0	
		bcf latch3,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
	
Laslatch1 bcf PORTA,4
	  bsf PORTA,5
	  return

Laslatch2 bcf PORTA,5
	  bsf PORTA,4
	  return

; deal with output dpendent on dir here

Layer1	
;	decfsz gendur1,1
;	goto laye1
la1	
;	movlw 0x10
;	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
	bsf latch2,0
	return

Layer2	decfsz gendur2,1
	goto laye2
la2	movlw 0x02
	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
	bsf latch2,0	
	return

Layer3	decfsz tmpdurr3,1
	return	
;	decfsz gendur3,1
;	goto laye3
;	movlw 0x02
;	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
	bsf latch3,0
	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 oldinbit,0
	  andlw 0x3f
	  movwf sped1
	  incf sped1,1
	  movf inbit,0
	  andlw 0x3f
	  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 0x3f
	  movwf sped2
	  incf sped2,1
	  movf oldinbit,0
	  andlw 0x3f
	  movwf dur2
	  incf dur2,1
	  btfsc oldinbit,0
	  bcf dir2,0
	  btfss oldinbit,0
	  bsf dir2,0
	  return ; set speed1/dir1/dur1 from inbit

Decision3 movf oldinbit,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
	
		

