.MODEL TINY .CODE .486 ORG 100H ;.COM FILES START HERE YEAR EQU 1969 ;DISPLAY CALENDAR FOR SPECIFIED YEAR START: MOV CX, 61 ;SPACE(61); TEXT(0, "[SNOOPY]"); CRLF(0) CALL SPACE MOV DX, OFFSET SNOOPY CALL TEXT MOV CL, 63 ;SPACE(63); INTOUT(0, YEAR); CRLF(0); CRLF(0) CALL SPACE MOV AX, YEAR CALL INTOUT CALL CRLF CALL CRLF MOV DI, 1 ;FOR MONTH:= 1 TO 12 DO DI=MONTH L22: XOR SI, SI ; FOR COL:= 0 TO 6-1 DO SI=COL L23: MOV CL, 5 ; SPACE(5) CALL SPACE MOV DX, DI ; TEXT(0, MONAME(MONTH+COL-1)); SPACE(7); DEC DX ; DX:= (MONTH+COL-1)*10+MONAME ADD DX, SI IMUL DX, 10 ADD DX, OFFSET MONAME CALL TEXT MOV CL, 7 CALL SPACE CMP SI, 5 ; IF COL<5 THEN SPACE(1); JGE L24 MOV CL, 1 CALL SPACE INC SI JMP L23 L24: CALL CRLF MOV SI, 6 ; FOR COL:= 0 TO 6-1 DO L25: MOV DX, OFFSET SUMO ; TEXT(0, "SU MO TU WE TH FR SA"); CALL TEXT DEC SI ; IF COL<5 THEN SPACE(2); JE L27 MOV CL, 2 CALL SPACE JMP L25 L27: CALL CRLF XOR SI, SI ;FOR COL:= 0 TO 6-1 DO L28: MOV BX, DI ;DAY OF FIRST SUNDAY OF MONTH (CAN BE NEGATIVE) ADD BX, SI ;DAY(COL):= 1 - WEEKDAY(YEAR, MONTH+COL, 1); MOV BP, YEAR ;DAY OF WEEK FOR FIRST DAY OF THE MONTH (0=SUN 1=MON..6=SAT) CMP BL, 2 ;IF MONTH<=2 THEN JG L3 ADD BL, 12 ; MONTH:= MONTH+12; DEC BP ; YEAR:= YEAR-1; L3: ;REM((1-1 + (MONTH+1)*26/10 + YEAR + YEAR/4 + YEAR/100*6 + YEAR/400)/7) INC BX ;MONTH IMUL AX, BX, 26 MOV CL, 10 CWD IDIV CX MOV BX, AX MOV AX, BP ;YEAR ADD BX, AX SHR AX, 2 ADD BX, AX MOV CL, 25 CWD IDIV CX IMUL DX, AX, 6 ;YEAR/100*6 ADD BX, DX SHR AX, 2 ;YEAR/400 ADD AX, BX MOV CL, 7 CWD IDIV CX NEG DX INC DX MOV [SI+DAY], DL ;COL+DAY INC SI CMP SI, 5 JLE L28 MOV BP, 6 ;FOR LINE:= 0 TO 6-1 DO BP=LINE L29: XOR SI, SI ; FOR COL:= 0 TO 6-1 DO SI=COL L30: MOV BX, DI ; DAYMAX:= DAYS(MONTH+COL); MOV BL, [BX+SI+DAYS] ;IF MONTH+COL=2 & (REM(YEAR/4)=0 & REM(YEAR/100)#0 ! REM(YEAR/400)=0) THEN MOV AX, DI ;MONTH ADD AX, SI CMP AL, 2 JNE L32 MOV AX, YEAR TEST AL, 03H JNE L32 MOV CL,100 CWD IDIV CX TEST DX, DX JNE L31 TEST AL, 03H JNE L32 L31: INC BX ;IF FEBRUARY AND LEAP YEAR THEN ADD A DAY L32: MOV DX, 7 ;FOR WEEKDAY:= 0 TO 7-1 DO L33: MOVZX AX, [SI+DAY] ; IF DAY(COL)>=1 & DAY(COL)<=DAYMAX THEN CMP AL, 1 JL L34 CMP AL, BL JG L34 CALL INTOUT ; INTOUT(0, DAY(COL)); CMP AL, 10 ; IF DAY(COL)<10 THEN SPACE(1); LEFT JUSTIFY JGE L36 MOV CL, 1 CALL SPACE JMP L36 L34: MOV CL, 2 ; ELSE SPACE(2); CALL SPACE ; SUPPRESS OUT OF RANGE DAYS L36: MOV CL, 1 ; SPACE(1); CALL SPACE INC BYTE PTR [SI+DAY] ; DAY(COL):= DAY(COL)+1; DEC DX ;NEXT WEEKDAY JNE L33 CMP SI, 5 ;IF COL<5 THEN SPACE(1); JGE L37 MOV CL, 1 CALL SPACE INC SI JMP L30 L37: CALL CRLF DEC BP ;NEXT LINE DOWN JNE L29 CALL CRLF ADD DI, 6 ;NEXT 6 MONTHS CMP DI, 12 JLE L22 RET ;DISPLAY POSITIVE INTEGER IN AX INTOUT: PUSHA MOV BX, 10 XOR CX, CX NO10: CWD IDIV BX PUSH DX INC CX TEST AX, AX JNE NO10 NO20: MOV AH, 02H POP DX ADD DL, '0' INT 21H LOOP NO20 POPA RET ;DISPLAY CX SPACE CHARACTERS SPACE: PUSHA SP10: MOV AH, 02H MOV DL, 20H INT 21H LOOP SP10 POPA RET ;START A NEW LINE CRLF: MOV DX, OFFSET LCRLF ;DISPLAY STRING AT DX TEXT: MOV AH, 09H INT 21H RET SNOOPY DB "[SNOOPY]" LCRLF DB 0DH, 0AH, '$' MONAME DB " JANUARY $ FEBRUARY$ MARCH $ APRIL $ MAY $ JUNE $" DB " JULY $ AUGUST $SEPTEMBER$ OCTOBER$ NOVEMBER$ DECEMBER$" SUMO DB "SU MO TU WE TH FR SA$" DAYS DB 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 DAY DB ?, ?, ?, ?, ?, ? END START