?? stime.s
字號:
;---------------------------------------------------------------------------;
; Simple time functions (C)ChaN,2005
;
; mktime() and gmtime() are sub-set of the functions defined in ANSI C.
; tm_isdst member is not returned and assumed as zero.
; mktime() does not change given tm structure and each members must be
; normalized or it returns -1.
.nolist
#include <avr/io.h>
#ifdef SPM_PAGESIZE // The device has "lpm Rd,Z+" and "movw".
.macro _MOVW dh,dl, sh,sl
movw \dl, \sl
.endm
#else // The device does not have "lpm Rd,Z+" nor "movw".
.macro _MOVW dh,dl, sh,sl
mov \dl, \sl
mov \dh, \sh
.endm
#endif
.list
.section .bss
.global time_tm
time_tm: ; Static tm structure
.ds.w 9 ; { sec, min, hour, mday, mon, year, wday, yday, isdst }
.section .text
samurai:
.dc.b 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
;---------------------------------------------------------------------------;
; time_t mktime( struct tm *timeptr );
;
;Size: 89/88 words
.global mktime
.func mktime
mktime:
push YL
push YH
_MOVW YH,YL, r25,r24
adiw YL, 12
ldi r20, 138 ; (365..366) * tm_year
rcall ldcp16
clr r22
clr r23
ldi r19, 70
0: ldi XL, lo8(366)
ldi XH, hi8(366)
mov r21, r19
andi r21, 3
breq 1f
sbiw XL, 1
1: cp r19, r18
breq 2f
brcc 91f
add r22, XL
adc r23, XH
inc r19
rjmp 0b
2:
ldi r20, 12 ; + (28..31) * tm_mon
rcall ldcp16
ldi ZL, lo8(samurai)
ldi ZH, hi8(samurai)
ldi r19, 0
3: lpm
adiw ZL, 1
cpi r19, 1
brne 4f
cpse r21, r1
dec r0
4: cp r19, r18
brcc 5f
add r22, r0
adc r23, r1
inc r19
rjmp 3b
5:
mov r20, r0 ; + tm_mday
inc r20
rcall ldcp16
subi r18, 1
brcs 91f
add r22, r18
adc r23, r1
clr r24
clr r25
; r25:r22 = days from orign
ldi r20, 24 ; * 24 + tm_hour
rcall ldcp16
rcall muladd3208
ldi r20, 60 ; * 60 + tm_min
rcall ldcp16
rcall muladd3208
ldi r18, 60 ; * 60 + tm_sec
rcall ldcp16
rcall muladd3208
rjmp 92f
ldcp16: ld r19, -Y ; Load an item with error check (< r20)
ld r18, -Y
cp r18, r20
cpc r19, r1
brcs 93f
pop r0
pop r0
91: ldi r22, -1 ; parameter error
ldi r23, -1
ldi r24, -1
ldi r25, -1
92: pop YH
pop YL
93: ret
muladd3208:
ldi r21, 33 ; r25:r22 *= r20;
sub r26, r26
0: brcc 1f
add r26, r20
1: ror r26
ror r25
ror r24
ror r23
ror r22
dec r21
brne 0b
add r22, r18 ; r25:r22 += r18;
adc r23, r1
adc r24, r1
adc r25, r1
ret
.endfunc
;---------------------------------------------------------------------------;
; struct tm *gmtime( const time_t *timer );
;
;Size: 93/89 words
.global gmtime
.func gmtime
gmtime:
push YL
push YH
_MOVW ZH,ZL, r25,r24 ;r21:r18 = utc
ldd r18, Z+0 ;
ldd r19, Z+1 ;
ldd r20, Z+2 ;
ldd r21, Z+3 ;/
clr YL ;Invalid time?
clr YH ;
sbrc r21, 7 ;
rjmp 99f ;/
ldi YL, lo8(time_tm)
ldi YH, hi8(time_tm)
; r21:r18 = seconds from origin
ldi r22, 60 ;tm_sec = % 60
rcall div3208 ;
std Y+0, r0 ;
std Y+1, r1 ;/
rcall div3208 ;tm_min = % 60
std Y+2, r0 ;
std Y+3, r1 ;/
ldi r22, 24 ;tm_hour = % 24
rcall div3208 ;
std Y+4, r0 ;
std Y+5, r1 ;/
; r19:r18 = days from origin
_MOVW ZH,ZL, r19,r18
subi r18, lo8(-4) ;tm_wday
sbci r19, hi8(-4) ;
ldi r22, 7 ;
rcall div3208 ;
std Y+12, r0 ;
std Y+13, r1 ;/
_MOVW r19,r18, ZH,ZL
ldi XL, 70 ;tm_year
0: ldi ZL, lo8(366) ;
ldi ZH, hi8(366) ;
mov XH, XL ;
andi XH, 3 ;
breq 1f ;
sbiw ZL, 1 ;
1: cp r18, ZL ;
cpc r19, ZH ;
brcs 2f ;
sub r18, ZL ;
sbc r19, ZH ;
inc XL ;
rjmp 0b ;
2: std Y+10, XL ;
std Y+11, r1 ;/
std Y+14, r18 ;tm_yday
std Y+15, r19 ;/
; r19:r18 = days in year
ldi ZL, lo8(samurai) ;tm_mon
ldi ZH, hi8(samurai) ;
clr XL ;
3: lpm ;
adiw ZL, 1 ;
cpi XL, 1 ;
brne 4f ;
cpse XH, r1 ;
dec r0 ;
4: cp r18, r0 ;
cpc r19, r1 ;
brcs 5f ;
sub r18, r0 ;
sbc r19, r1 ;
inc XL ;
rjmp 3b ;
5: std Y+8, XL ;
std Y+9, r1 ;/
inc r18 ;tm_mday
std Y+6, r18 ;
std Y+7, r19 ;/
99: _MOVW r25,r24, YH,YL ;Return pointer to internal tm buffer
pop YH
pop YL
ret
div3208: ; r0 = r21:r18 % r22;
clr r0 ; r21:r18 /= r22;
ldi r23, 32
1: lsl r18
rol r19
rol r20
rol r21
rol r0
cp r0, r22
brcs 2f
sub r0, r22
inc r18
2: dec r23
brne 1b
ret
.endfunc
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -