.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