Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- .TITLE TERVEHDYS
- .IDENT /V1.4/
- .LIBRARY /SYS$LIBRARY:STARLET.MLB/
- $SSDEF
- $DSCDEF
- .PSECT DATA,NOEXE,WRT,LONG
- UTC_TIME: .BLKQ 1
- UTCNUM: .BLKW 7
- FINNUM: .BLKW 7
- DAY: .BLKL 1
- YEAR: .BLKL 1
- HOUR: .BLKL 1
- MINUTE: .BLKL 1
- SECOND: .BLKL 1
- MAR_LAST: .BLKL 1
- OCT_LAST: .BLKL 1
- MONTH_PTR: .BLKL 1
- OFFSET_HOURS: .BLKL 1
- MONTH_LEN: .BLKL 1
- OUTBUF: .BLKB 132
- OUTLEN: .BLKW 1
- OUT_DSC:
- .WORD 132
- .BYTE DSC$K_DTYPE_T
- .BYTE DSC$K_CLASS_S
- .ADDRESS OUTBUF
- FMT_DATE: .ASCID /!UL. !AS !UL !2ZL:!2ZL:!2ZL Suomen aikaa/
- MON01: .ASCID /tammikuuta/
- MON02: .ASCID /helmikuuta/
- MON03: .ASCID /maaliskuuta/
- MON04: .ASCID /huhtikuuta/
- MON05: .ASCID /toukokuuta/
- MON06: .ASCID /kesakuuta/
- MON07: .ASCID /heinakuuta/
- MON08: .ASCID /elokuuta/
- MON09: .ASCID /syyskuuta/
- MON10: .ASCID /lokakuuta/
- MON11: .ASCID /marraskuuta/
- MON12: .ASCID /joulukuuta/
- MONTH_TABLE:
- .ADDRESS MON01,MON02,MON03,MON04,MON05,MON06
- .ADDRESS MON07,MON08,MON09,MON10,MON11,MON12
- MDAYS:
- .LONG 31,28,31,30,31,30,31,31,30,31,30,31
- MSG_TIME: .ASCID /Paivamaara ja aika:/
- GREET_MORN: .ASCID /Hyvaa huomenta!/
- GREET_DAY: .ASCID /Hyvaa paivaa!/
- GREET_EVE: .ASCID /Hyvaa iltaa!/
- GREET_NIGHT: .ASCID /Hyvaa yota!/
- .PSECT CODE,EXE,NOWRT,LONG
- .ENTRY START,^M<>
- $GETTIM_S TIMADR=UTC_TIME
- BLBS R0,10$
- JMP ERROR
- 10$:
- $NUMTIM_S TIMBUF=UTCNUM,TIMADR=UTC_TIME
- BLBS R0,20$
- JMP ERROR
- 20$:
- ; Find last Sunday of March and October in the UTC year.
- MOVZWL UTCNUM+0,R0
- MOVL #3,R1
- MOVL #31,R2
- BSBW LAST_SUNDAY
- MOVL R0,MAR_LAST
- MOVZWL UTCNUM+0,R0
- MOVL #10,R1
- MOVL #31,R2
- BSBW LAST_SUNDAY
- MOVL R0,OCT_LAST
- ; Default: Finnish winter time, UTC+2.
- MOVL #2,OFFSET_HOURS
- ; Finnish summer time: last Sunday of March 01:00 UTC
- ; through last Sunday of October before 01:00 UTC.
- MOVZWL UTCNUM+2,R0 ; UTC month
- CMPL R0,#3
- BLSS HAVE_OFFSET ; Jan-Feb
- CMPL R0,#10
- BGTR HAVE_OFFSET ; Nov-Dec
- CMPL R0,#3
- BEQL CHECK_MARCH
- CMPL R0,#10
- BEQL CHECK_OCTOBER
- MOVL #3,OFFSET_HOURS ; Apr-Sep
- BRW HAVE_OFFSET
- CHECK_MARCH:
- MOVZWL UTCNUM+4,R0 ; UTC day
- CMPL R0,MAR_LAST
- BLSS HAVE_OFFSET
- BGTR MARCH_DST
- MOVZWL UTCNUM+6,R0 ; UTC hour
- CMPL R0,#1
- BLSS HAVE_OFFSET
- MARCH_DST:
- MOVL #3,OFFSET_HOURS
- BRW HAVE_OFFSET
- CHECK_OCTOBER:
- MOVL #3,OFFSET_HOURS ; October is DST until cutoff
- MOVZWL UTCNUM+4,R0
- CMPL R0,OCT_LAST
- BLSS HAVE_OFFSET
- BGTR OCT_STD
- MOVZWL UTCNUM+6,R0
- CMPL R0,#1
- BLSS HAVE_OFFSET
- OCT_STD:
- MOVL #2,OFFSET_HOURS
- HAVE_OFFSET:
- ; Copy UTC numeric time to FINNUM.
- MOVW UTCNUM+0,FINNUM+0
- MOVW UTCNUM+2,FINNUM+2
- MOVW UTCNUM+4,FINNUM+4
- MOVW UTCNUM+6,FINNUM+6
- MOVW UTCNUM+8,FINNUM+8
- MOVW UTCNUM+10,FINNUM+10
- MOVW UTCNUM+12,FINNUM+12
- ; Add 2 or 3 hours.
- MOVZWL FINNUM+6,R0
- ADDL2 OFFSET_HOURS,R0
- CMPL R0,#24
- BLSS STORE_HOUR
- SUBL2 #24,R0
- MOVW R0,FINNUM+6
- BSBW INC_DATE
- BRW AFTER_HOUR
- STORE_HOUR:
- MOVW R0,FINNUM+6
- AFTER_HOUR:
- MOVZWL FINNUM+0,YEAR
- MOVZWL FINNUM+4,DAY
- MOVZWL FINNUM+6,HOUR
- MOVZWL FINNUM+8,MINUTE
- MOVZWL FINNUM+10,SECOND
- MOVZWL FINNUM+2,R1
- DECL R1
- MULL2 #4,R1
- MOVL MONTH_TABLE(R1),MONTH_PTR
- PUSHL SECOND
- PUSHL MINUTE
- PUSHL HOUR
- PUSHL YEAR
- PUSHL MONTH_PTR
- PUSHL DAY
- PUSHAQ OUT_DSC
- PUSHAL OUTLEN
- PUSHAQ FMT_DATE
- CALLS #9,G^LIB$SYS_FAO
- BLBS R0,30$
- JMP ERROR
- 30$:
- MOVW OUTLEN,OUT_DSC
- PUSHAQ MSG_TIME
- CALLS #1,G^LIB$PUT_OUTPUT
- PUSHAQ OUT_DSC
- CALLS #1,G^LIB$PUT_OUTPUT
- CMPW FINNUM+6,#6
- BLSS SAY_NIGHT
- CMPW FINNUM+6,#12
- BLSS SAY_MORN
- CMPW FINNUM+6,#18
- BLSS SAY_DAY
- CMPW FINNUM+6,#22
- BLSS SAY_EVE
- SAY_NIGHT:
- PUSHAQ GREET_NIGHT
- BRB PRINT_GREET
- SAY_MORN:
- PUSHAQ GREET_MORN
- BRB PRINT_GREET
- SAY_DAY:
- PUSHAQ GREET_DAY
- BRB PRINT_GREET
- SAY_EVE:
- PUSHAQ GREET_EVE
- PRINT_GREET:
- CALLS #1,G^LIB$PUT_OUTPUT
- MOVL #SS$_NORMAL,R0
- RET
- ERROR:
- PUSHL R0
- CALLS #1,G^LIB$STOP
- RET
- ; Increment FINNUM date by one day.
- INC_DATE:
- MOVZWL FINNUM+0,R0 ; year
- MOVZWL FINNUM+2,R1 ; month
- BSBW GET_MONTH_LENGTH
- MOVL R0,MONTH_LEN
- MOVZWL FINNUM+4,R0 ; day
- INCL R0
- CMPL R0,MONTH_LEN
- BGTR NEXT_MONTH
- MOVW R0,FINNUM+4
- RSB
- NEXT_MONTH:
- MOVW #1,FINNUM+4
- MOVZWL FINNUM+2,R0
- INCL R0
- CMPL R0,#12
- BGTR NEXT_YEAR
- MOVW R0,FINNUM+2
- RSB
- NEXT_YEAR:
- MOVW #1,FINNUM+2
- MOVZWL FINNUM+0,R0
- INCL R0
- MOVW R0,FINNUM+0
- RSB
- ; Input:
- ; R0 = year
- ; R1 = month
- ; Output:
- ; R0 = length of month
- GET_MONTH_LENGTH:
- DECL R1
- MULL2 #4,R1
- MOVL MDAYS(R1),R2
- ; February: check leap year.
- CMPL R1,#4 ; original month 2 -> index 1 -> offset 4
- BNEQ MONTH_LEN_DONE
- BSBW IS_LEAP
- TSTL R0
- BEQL MONTH_LEN_DONE
- MOVL #29,R2
- MONTH_LEN_DONE:
- MOVL R2,R0
- RSB
- ; Input:
- ; R0 = year
- ; Output:
- ; R0 = 1 if leap year, 0 otherwise
- IS_LEAP:
- MOVL R0,R3
- MOVL R3,R4
- DIVL2 #400,R4
- MULL2 #400,R4
- CMPL R3,R4
- BEQL LEAP_YES
- MOVL R3,R4
- DIVL2 #100,R4
- MULL2 #100,R4
- CMPL R3,R4
- BEQL LEAP_NO
- MOVL R3,R4
- DIVL2 #4,R4
- MULL2 #4,R4
- CMPL R3,R4
- BEQL LEAP_YES
- LEAP_NO:
- CLRL R0
- RSB
- LEAP_YES:
- MOVL #1,R0
- RSB
- ; Input:
- ; R0 = year
- ; R1 = month, 3 or 10
- ; R2 = last day of month
- ; Output:
- ; R0 = day number of last Sunday in that month
- LAST_SUNDAY:
- MOVL R0,R3
- MOVL R1,R4
- MOVL R2,R5
- ADDL3 #1,R4,R6
- MULL2 #13,R6
- DIVL2 #5,R6
- ADDL3 R5,R6,R7
- ADDL2 R3,R7
- MOVL R3,R8
- DIVL2 #4,R8
- ADDL2 R8,R7
- MOVL R3,R8
- DIVL2 #100,R8
- SUBL2 R8,R7
- MOVL R3,R8
- DIVL2 #400,R8
- ADDL2 R8,R7
- MOVL R7,R8
- DIVL2 #7,R8
- MULL2 #7,R8
- SUBL2 R8,R7
- ADDL2 #6,R7
- MOVL R7,R8
- DIVL2 #7,R8
- MULL2 #7,R8
- SUBL2 R8,R7
- SUBL3 R7,R5,R0
- RSB
- .END START
Advertisement