home *** CD-ROM | disk | FTP | other *** search
- GET a:SWICalls
- GET a:Registers
-
- ; This call was written to get round a stupid bug in Clib's time
- ; functions
- ;
- ;
-
- AREA |C$$code|,CODE,READONLY
-
- r_s RN 0 ;seconds on exit
- r_c RN 1 ;centi seconds
- r_a RN 2 ;LS 32 bits of 40bit Risc OS time of day
- r_b RN 3 ;MS 8 bits of 40bit Risc OS time of day
- r_v RN 4 ;Temp reg
-
- ^ 0
- ost_csec # 4
- ost_sec # 4
- ost_min # 4
- ost_hour # 4
- ost_day # 4
- ost_month # 4
- ost_year # 4
- ost_wday # 4
- ost_yday # 4
- ost_size * @
-
- ^ 0
- tm_sec # 4
- tm_min # 4
- tm_hour # 4
- tm_day # 4
- tm_month # 4
- tm_year # 4
- tm_wday # 4
- tm_yday # 4
- tm_dst # 4
- tm_size * @
-
- ; -------------------------------------------------------------------------
- ; Convert 40 bit Risc OS time value into 32 bit time_t
- ;
- ;On entry:
- ; R0 = pointer to 5 byte Risc OS time value
- ;On exit:
- ; R0 = 32 bit time_t
- ;
- time_40to32
- STMFD sp!, {r1-r4, lr}
- LDMIA r0, {r_a, r_b}
-
- AND r_b, r_b, #&ff ;real time bits 39-32 - get rid of 40+
- LDR r_v, =&6e996a00 ;To Unix and C time range
- SUBS r_a, r_a, r_v ;5 byte time - 0x336e996a00
- SBC r_c, r_b, #&33 ;Risc OS time on 1st Jan 1970
-
- ; r_t is a temp, r_v is a temp, r_c is csecs, r_s is secs
- ; The following is a 40 bit div/mod by 100
-
-
-
- MOV r_s, #0 ;sec = 0
- ;;; MOV r_c, #0 ;csec = 0
- ;b is real time bits 39-32
- ;;; ORR r_c, r_b, r_c, LSL #8 ;csec = (csec<<8) | t;
- BL divmod100 ;csec = csec % 100;
- ORR r_s, r_b, r_s, LSL #8 ;sec = (sec<<8) | (csec/100);
-
- div32by100b
- MOV r_b, r_a, LSR #24 ;b is real time bits 31-24
- ORR r_c, r_b, r_c, LSL #8 ;csec = (csec<<8) | t;
- BL divmod100 ;csec = csec % 100;
- ORR r_s, r_b, r_s, LSL #8 ;sec = (sec<<8) | (csec/100);
-
- MOV r_b, r_a, LSR #16
- AND r_b, r_b, #&ff ;b is real time bits 23-16
- ORR r_c, r_b, r_c, LSL #8 ;csec = (csec<<8) | t;
- BL divmod100 ;csec = csec % 100;
- ORR r_s, r_b, r_s, LSL #8 ;sec = (sec<<8) | (csec/100);
-
- MOV r_b, r_a, LSR #8
- AND r_b, r_b, #&ff ;b is real time bits 15-8
- ORR r_c, r_b, r_c, LSL #8 ;csec = (csec<<8) | t;
- BL divmod100 ;csec = csec % 100;
- ORR r_s, r_b, r_s, LSL #8 ;sec = (sec<<8) | (csec/100);
-
- MOV r_b, r_a
- AND r_b, r_a, #&ff ;b is real time bits 7-0
- ORR r_c, r_b, r_c, LSL #8 ;csec = (csec<<8) | t;
- BL divmod100 ;csec = csec % 100;
- ORR r_s, r_b, r_s, LSL #8 ;sec = (sec<<8) | (csec/100);
-
- LDMFD sp!, {r1-r4, pc}^
-
- ; Part of timezone convertion below
- div32by100 STMFD sp!, {r1-r4, lr}
- MOVS r_a, r1
- RSBMI r_a, r_a, #0 ;absolute value
- MOV r_s, #0 ;so that value of result is correct
- MOV r_c, #0 ;even if the sign isnt
- B div32by100
-
-
- ; ----------
- ; Highly optimised 16 bit div/mod 100
- ; (r1) r_c = r_c%100
- ; (r3) _b = r_c/100
- ; (r4 used)
- divmod100
- MOV r_v, r_c, LSR #1 ;Divide by 100 to get seconds
- RSB r_v, r_v, r_v, LSL #3
- RSB r_v, r_v, r_v, LSL #3
- RSB r_b, r_v, r_v, LSL #7
- ADD r_v, r_v, r_v, LSL #2
- SUB r_v, r_b, r_v, LSL #2
- MOV r_b, r_v, LSR #18 ;result in r_b
-
- ADD r_v, r_b, r_b, LSL #2 ;Remainder of division (0-99)
- ADD r_v, r_v, r_v, LSL #2
- SUB r_c, r_c, r_v, LSL #2 ;remainder back in r_c
-
- MOVS pc, lr
-
-
- ; -------------------------------------------------------------------------
- ; Convert 32 bit time_t into 40 bit Risc OS time value
- ;
- ;On entry:
- ; R0 = time_t
- ; R1 = pointer to 5 byte buffer to time value
- ;On exit:
- ; -
- EXPORT time_32to40
- time_32to40
- STMFD sp!, {r0, r2-r3, lr}
-
- MOV r3, r0, LSR #24 ;32 bit * 100 -> 40 bit value
- BIC r0, r0, #&FF000000
-
- ADD r3, r3, r3, LSL#2
- ADD r3, r3, r3, LSL#2
- MOV r3, r3, LSL#2
-
- ADD r0, r0, r0, LSL#2
- ADD r0, r0, r0, LSL#2
- MOV r0, r0, LSL#2
-
- MOV r2, r3, LSR#8
- ADDS r0, r0, r3, LSL#24
- ADC r3, r2, #0
-
- LDR r2, =&6e996a00 ;To Risc OS time range
- ADDS r0, r0, r2
- ADC r3, r3, #&33
-
- STR r0, [r1, #0]
- STRB r3, [r1, #4]
-
- LDMFD sp!, {r0, r2-r3, pc}^
-
-
- ; -------------------------------------------------------------------------
- ; Convert timezone for csecs to secs
- ;
- ;On entry:
- ; R1 = signed timezone in centiseconds
- ;On exit:
- ; R0 = signed timezone in seconds
- ;
- time_convtz
- STMFD sp!, {lr}
- BL div32by100
- MOVS r1, r1
- RSBMI r0, r1, #0
- LDMFD sp!, {pc}^
-
-
- ; -------------------------------------------------------------------------
- ; Read current GMT time
- ;
- ;On entry:
- ; -
- ;On exit:
- ; R0 = GMT time
- ;
- EXPORT time_readgmt
- time_readgmt
- STMFD sp!, {r1, lr}
- SUB sp, sp, #8
- MOV r0, #3
- STRB r0, [sp, #0]
- MOV r0, #14
- MOV r1, sp
- SWI XOS_Word
- MOV r0, r1
- BL time_40to32
- ADD sp, sp, #8
- LDMFD sp!, {r1, pc}^
-
-
- ; -------------------------------------------------------------------------
- ; Convert time to ordinals
- ;
- ;On entry:
- ; R0 = time
- ; R1 = pointer to ANSI-C tm struture <time.h>
- ;On exit:
- ; Buffer is filled, except DST flag is allways zero a this is GMT
- ;
- EXPORT time_timetoordinals
- time_timetoordinals
- STMFD sp!, {r0-r4, lr}
- SUB sp, sp, #8+ost_size
- MOV r3, r1
- MOV r1, sp
- BL time_32to40
- MOV r0, sp
- BL time_tolocal40
- MOV r0, #-1
- ADD r2, sp, #8
- SWI XTerritory_ConvertTimeToOrdinals
-
- LDR r0, [r2, #ost_sec]
- STR r0, [r3, #tm_sec]
- LDR r0, [r2, #ost_min]
- STR r0, [r3, #tm_min]
- LDR r0, [r2, #ost_hour]
- STR r0, [r3, #tm_hour]
- LDR r0, [r2, #ost_day]
- STR r0, [r3, #tm_day]
- LDR r0, [r2, #ost_month]
- SUB r0, r0, #1
- STR r0, [r3, #tm_month]
- LDR r0, [r2, #ost_year]
- LDR r1, =1900
- SUB r0, r0, r1
- STR r0, [r3, #tm_year]
- LDR r0, [r2, #ost_wday]
- STR r0, [r3, #tm_wday]
- LDR r0, [r2, #ost_yday]
- STR r0, [r3, #tm_yday]
- MOV r0, #0
- STR r0, [r3, #tm_dst]
- ADD sp, sp, #8+ost_size
- LDMFD sp!, {r0-r4, pc}^
-
-
- ; -------------------------------------------------------------------------
- ; Convert ordinals to time
- ;
- ;On entry:
- ; R0 = pointer to ANSI-C tm struture <time.h>
- ;On exit:
- ; R0 = time
- ;
- EXPORT time_ordinalstotime
- time_ordinalstotime
- STMFD sp!, {r1-r3, lr}
- SUB sp, sp, #8+ost_size
- ADD r2, sp, #8
- MOV r1, #0
- STR r1, [r2, #ost_csec]
- LDR r1, [r0, #tm_sec]
- STR r1, [r2, #ost_sec]
- LDR r1, [r0, #tm_min]
- STR r1, [r2, #ost_min]
- LDR r1, [r0, #tm_hour]
- STR r1, [r2, #ost_hour]
- LDR r1, [r0, #tm_day]
- STR r1, [r2, #ost_day]
- LDR r1, [r0, #tm_month]
- ADD r1, r1, #1
- STR r1, [r2, #ost_month]
- LDR r1, [r0, #tm_year]
- LDR r3, =1900
- ADD r1, r1, r3
- STR r1, [r2, #ost_year]
- LDR r1, [r0, #tm_wday]
- STR r1, [r2, #ost_wday]
- LDR r1, [r0, #tm_yday]
- STR r1, [r2, #ost_yday]
- MOV r0, #-1
- MOV r1, sp
- SWI XTerritory_ConvertOrdinalsToTime
- MOV r0, sp
- BL time_togmt40
- BL time_40to32
- ADD sp, sp, #8+ost_size
- LDMFD sp!, {r1-r3, pc}^
-
-
-
- ; -------------------------------------------------------------------------
- ; Convert 40 bit from local time to gmt
- ;
- ;On entry:
- ; R0 = pointer to ANSI-C tm struture <time.h>
- ;On exit:
- ; -
- ;
- time_togmt40
- STMFD sp!, {r0-r2, lr}
- MOV r2, r0
- SWI XTerritory_ReadCurrentTimeZone
- LDR r0, [r2, #0]
- ADDS r0, r0, r1
- STR r0, [r2, #0]
- LDRB r0, [r2, #4]
- ADC r0, r0, r1, ASR #31
- STRB r0, [r2, #4]
- LDMFD sp!, {r0-r2, pc}^
-
-
- ; -------------------------------------------------------------------------
- ; Convert 40 bit from gmt to local time
- ;
- ;On entry:
- ; R0 = pointer to ANSI-C tm struture <time.h>
- ;On exit:
- ; -
- ;
- time_tolocal40
- STMFD sp!, {r0-r2, lr}
- MOV r2, r0
- SWI XTerritory_ReadCurrentTimeZone
- LDR r0, [r2, #0]
- SUBS r0, r0, r1
- STR r0, [r2, #0]
- LDRB r0, [r2, #4]
- SBC r0, r0, r1, ASR #31
- STRB r0, [r2, #4]
- LDMFD sp!, {r0-r2, pc}^
-
- END
-