DacStateCurrentLinear EQU 0 DacStateRunningSum EQU 1 DacStateTarget EQU 2 DacStateRate EQU 3 DacStateCurrentLow EQU 4 DacStateCurrentHigh EQU 5 ; Each 1-bit dac is maintained as 2 bytes: ; the brightness and the running-sum. ; (a third byte is sometimes the "target brightness") ; Put the current 1-bit dac on-offness ; into the specified bit of the dest ; cycles: 3 StepDac MACRO dacState,destReg,destBit MOVFW dacState+DacStateCurrentLinear ADDWF dacState+DacStateRunningSum,F IFC BSF destReg,destBit IFNC BCF destReg,destBit ENDM StepBrightness MACRO dacState LOCAL _doBumpUp,_didBump,_upperHalf,_done MOVFW dacState+DacStateCurrentHigh SUBWF dacState+DacStateTarget,W ; target - current: positive sets C and means, increment towards ; negative clears C and means, decrement towards IFZ GOTO _didBump MOVFW dacState+DacStateRate ; moving up IFC GOTO _doBumpUp GOTO _didBump SUBWF dacState+DacStateCurrentLow,F IFNC DECF dacState+DacStateCurrentHigh,F ; MOVFF dacState+DacStateTarget,dacState+DacStateCurrentHigh ; just slam it NOT RIGHT GOTO _didBump _doBumpUp: ADDWF dacState+DacStateCurrentLow,F IFC INCF dacState+DacStateCurrentHigh,F _didBump: IFBS dacState+DacStateCurrentHigh,7 GOTO _upperHalf ; we are in lower half of brightness range, slow it down ; map 0-0x7f into 0-0x3f BCF STATUS,C RRF dacState+DacStateCurrentHigh,W MOVWF dacState+DacStateCurrentLinear GOTO _done _upperHalf: ; we are in upper half of brighness range, speed it up ; map 0x80-0xff into 0x40-0xff ; f(x) = 0x40 + (x - 0x80) + (x - 0x80) / 2 ; f(x) = 0x40 + (x - 0x80) + x/2 - 0x40 ; f(x) = x + x/2 - 0x80 BCF STATUS,C RRF dacState+DacStateCurrentHigh,W ; x/2 ADDWF dacState+DacStateCurrentHigh,W ; +x ADDLW 0x80 MOVWF dacState+DacStateCurrentLinear _done: ;MOVFF dacState+DacStateCurrentHigh,dacState+DacStateCurrentLinear ENDM