;
; 50 usec (100 cycle) interrupts, approx 50% ISR "overhead"
;
; 100 pwm "steps", 200 Hz refresh rate, 5 msec frame rate
;
org 0x0004
radix dec
isr
movwf w_isr ; save W-reg |B?
swapf STATUS,W ; don't change STATUS bits |B?
movwf s_isr ; save STATUS reg |B?
clrf STATUS ; bank 0 |B0
movf PCLATH,W ; get PCLATH |B0
movwf p_isr ; save PCLATH |B0
clrf PCLATH ; page 0 |B0
;
; reload Timer 0 for 50 usec interrupts (8 Mhz, prescaler 1)
; for a 200 Hz refresh rate and a 5 msec frame rate
;
movlw -100+2 ; 100 500-nsec ticks = 50 usecs |B0
addwf TMR0,F ; add to free running TMR0 reg |B0
bcf INTCON,TMR0IF ; clear Timer O interrupt flag |B0
;
; do a 1/100th pwm 'step', 25 cycles (isochronous)
;
movf led+0,W ; led0 pwm value, 0..99 |B0
subwf dcy,W ; C = led0 => dcy |B0
rrf shadow,F ; |B0
movf led+1,W ; led1 pwm value, 0..99 |B0
subwf dcy,W ; C = led1 => dcy |B0
rrf shadow,F ; |B0
movf led+2,W ; led2 pwm value, 0..99 |B0
subwf dcy,W ; C = led2 => dcy |B0
rrf shadow,F ; |B0
movf led+3,W ; led3 pwm value, 0..99 |B0
subwf dcy,W ; C = led3 => dcy |B0
rrf shadow,F ; |B0
movf led+4,W ; led4 pwm value, 0..99 |B0
subwf dcy,W ; C = led4 => dcy |B0
rrf shadow,F ; |B0
movf led+5,W ; led5 pwm value, 0..99 |B0
subwf dcy,W ; C = led5 => dcy |B0
rrf shadow,F ; |B0
movf led+6,W ; led6 pwm value, 0..99 |B0
subwf dcy,W ; C = led6 => dcy |B0
rrf shadow,F ; |B0
movf led+7,W ; led7 pwm value, 0..99 |B0
subwf dcy,W ; C = led7 => dcy |B0
rrf shadow,W ; W = led 'step' output |B0
; xorlw 0xFF ; for active hi outputs |B0
movwf PORTB ; update LEDs |B0
;
; bump duty cycle, 5 cycles (isochronous)
;
incf dcy,F ; dcy++, 0..99 inclusive |B0
movf dcy,W ; |B0
xorlw 100 ; end of 5 msec frame? |B0
skpnz ; no, skip, else |B0
clrf dcy ; reset duty cycle counter |B0
;
; restore context, 8 cycles (isochronous)
;
isr_xit
movf p_isr,W ; |B0
movwf PCLATH ; restore PCLATH |B0
swapf s_isr,W ; |B0
movwf STATUS ; restore STATUS |B0
swapf w_isr,f ; don't screw up STATUS |B0
swapf w_isr,W ; restore WREG |B0
retfie ; return from interrupt |B0
;