;MACROS -------------------------------------------------------------------------- ; CycleFor <count> ; if the count is less than the interrupt period, compiles a delay loop of the ; required cycles. For large delays, compiles code to set up to a 3 byte timer ; to an interrupt count equal to the delay and then waits for the counter to ; zero. ; Delay value, [usec,msec,sec,cycles] ; Calculates cycles from delay value and units (milli seconds, micro seconds, ; or seconds). Calls cyclefor to delay that number of cycles IFNDEF CPUMHZ error 'Please define the speed the processor will run at. E.g. CPUMHz = 50 ' ENDIF IFNDEF IntPeriod IntPeriod = 256 ;set to the max value of delay possible without a real ISR. ENDIF IFNDEF Timers ; Timer ISR registers (sample: See sasmtemp.src for complete setup flags = 7 ;general flag register TimerFlag = flags.2 ;timer rollover flag Timers = $ ;timer TimerAccL = 8 ;timer accumulator low TimerAccH = 9 ;timer accumulator high TimerAccT = 10 ;timer accumulator top watch TimerFlag, 1, ubin watch TimerAccL, 24, uhex ENDIF mynop MACRO expand mov !7,w ;can't single step nop noexpand ENDM nsec EQU -9 usec EQU -6 msec EQU -3 sec EQU 1 cycles EQU 0 cyclefor MACRO 1 local _cycles,_temp,_ints3,_ints2,_ints1 noexpand _cycles = 1円 _temp = 0 IF _cycles - 10 > IntPeriod OR _cycles < 0 IF (IntPeriod =256) error 'This delay requires an actual ISR' ENDIF _cycles = _cycles - 10 _ints3 = $FF - (_cycles/(IntPeriod*10000ドル)) _ints2 = $FF - (_cycles/(IntPeriod*100ドル)//100ドル) _ints1 = $FF - (_cycles/IntPeriod//100ドル) IF Timers > 0ドルF ; ERROR 'Timers must be in bank 0' expand bank Timers noexpand ENDIF expand clr TimerAccL mov TimerAccT, #_ints3 mov TimerAccH, #_ints2 mov TimerAccL, #_ints1 clrb TimerFlag sb TimerFlag jmp $-2 noexpand _cycles = _cycles // IntPeriod ELSE expand ;cycles to delay: _temp = _cycles noexpand _temp = $ // 4 IF _temp == 2 IF _cycles < 5 REPT _cycles mynop ENDR _cycles = 0 ELSE mynop _cycles = _cycles -1 ENDIF ENDIF IF _temp == 1 IF _cycles < 7 REPT _cycles mynop ENDR _cycles = 0 ELSE _cycles = _cycles - 2 _loops = _cycles / 5 expand mov w, #_loops page $+1 decsz 1 jmp $-1 noexpand _cycles = _cycles // 5 ;cycles left over ENDIF ENDIF IF _cycles > 5 _cycles = _cycles - 1 _loops = _cycles / 5 expand mov w, #_loops decsz 1 clrb 2.1 noexpand _cycles = _cycles // 5 ;cycles left over ENDIF IF _cycles > 0 REPT _cycles mynop ENDR ENDIF ENDIF ENDM delayhelp MACRO ERROR 'USAGE: delay value, [usec,msec,sec,cycles]' ENDM delay MACRO value, units ; local _cycles ;if this is local, the call to cyclefor don't work. noexpand ;Calculates cycles from delay value and units (milli seconds, micro seconds, or seconds) ;calls cyclefor to delay that number of cycles. ;Expects CpuMhz set to CPU MHz. _cycles = 0 IF value < 1000 && value > 0 IF ?units=='sec' _cycles = (value * 100000000 / (100/CpuMhz)) ENDIF IF ?units=='msec' _cycles = (value * 1000000 / (1000/CpuMhz)) ENDIF IF ?units=='usec' _cycles = (value * 1000 / (1000/CpuMhz)) ENDIF IF ?units=='nsec' _cycles = (value * 10 + 5 / (10000/CpuMhz)) ENDIF IF ?units=='cycles' _cycles = value ENDIF IF _cycles < 1 expand ;delay less than one cycle at this processor speed' noexpand ELSE cyclefor _cycles ENDIF ELSE delayhelp ENDIF ENDM
.