xplshn
·
2025-09-14
cal3.bx
Bx
1extrn printf, time, localtime;
2
3/*
4 * On amd64_sysv, the C struct tm has the following layout:
5 *
6 * struct tm {
7 * int tm_sec; // 0
8 * int tm_min; // 4
9 * int tm_hour; // 8
10 * int tm_mday; // 12
11 * int tm_mon; // 16
12 * int tm_year; // 20
13 * int tm_wday; // 24
14 * int tm_yday; // 28
15 * int tm_isdst; // 32
16 * };
17 *
18 * All members are 4-byte integers.
19 */
20
21int days_in_month(m int, y int) {
22 if (m == 1) { // February
23 if ((y % 400 == 0) | ((y % 4 == 0) & (y % 100 != 0))) {
24 return (29);
25 } else {
26 return (28);
27 };
28 };
29 if ((m == 0) | (m == 2) | (m == 4) | (m == 6) | (m == 7) | (m == 9) | (m == 11)) {
30 return (31);
31 };
32 return (30);
33}
34
35int main() {
36 now := time(0);
37 tptr := localtime(&now);
38
39 byte_ptr := (*byte)tptr;
40 year := *((*int)(byte_ptr + 20)) + 1900;
41 month := *((*int)(byte_ptr + 16)); // 0 = Jan
42 today := *((*int)(byte_ptr + 12));
43 wday := *((*int)(byte_ptr + 24));
44
45 days := days_in_month(month, year);
46
47 printf(" %d/%d\n", month + 1, year);
48 printf("Su Mo Tu We Th Fr Sa\n");
49
50 // Calculate the weekday of the first day of the month.
51 // wday is for today, so we go back (today - 1) days.
52 // The result must be non-negative, so we add 7 before the modulo
53 first_wday := (wday - (today - 1) % 7 + 7) % 7;
54
55 i := 0;
56 while (i < first_wday) {
57 printf(" ");
58 i = i + 1;
59 };
60
61 d := 1;
62 while (d <= days) {
63 if (d == today) {
64 printf("\033[31m%2d\033[0m ", d);
65 } else {
66 printf("%2d ", d);
67 };
68
69 current_wday := (first_wday + d - 1) % 7;
70 if (current_wday == 6) { // It's Saturday, add \n
71 printf("\n");
72 };
73 d = d + 1;
74 };
75 printf("\n");
76 return (0);
77}