xplshn
·
2025-08-13
6502.b
B
1exit(code) {
2 0(code);
3}
4
5abort() {
6 exit(69);
7}
8
9putchar(c) {
10 0xFFEF(c);
11}
12
13char __asm__(
14 "TSX",
15 "CLC",
16 "ADC $0103,X", // i&0xFF
17 "STA $00", // we can safely use zero-page, as our assembler
18 // doesn't expect it to be preserved across op-boundaries
19 "TYA",
20 "ADC $0104,X", // i&0xFF00 >> 8
21 "STA $01",
22 "LDY #0",
23 "LDA ($00),Y",
24 "RTS"
25);
26
27lchar __asm__(
28 "TSX",
29 "CLC",
30 "ADC $0103,X", // i&0xFF
31 "STA $00", // we can safely use zero-page, as our assembler
32 // doesn't expect it to be preserved across op-boundaries
33 "TYA",
34 "ADC $0104,X", // i&0xFF00 >> 8
35 "STA $01",
36 "LDA $0105,X",
37 "LDY #0",
38 "STA ($00),Y",
39 "RTS"
40);
41
42/* TODO: fd not supported */
43fputc(c, fd) {
44 putchar(c);
45}
46
47/* TODO: actually allocate something */
48__heap_ptr 0x0200;
49malloc(size) {
50 extrn printf;
51 auto ptr;
52 ptr = __heap_ptr;
53 __heap_ptr += size;
54 if (__heap_ptr >= 0x1000) {
55 printf("Allocation reached end: %p\nTODO: allow allocating more, implement free\n", __heap_ptr);
56 abort();
57 }
58 return (ptr);
59}
60/* TODO: free someting? */
61realloc(ptr, size) {
62 return (malloc(size));
63}
64
65/* TODO: Try to implement this function with assembly
66 Problem with this implementation is that it is not
67 mapped to the operator
68 We cannot call this function `div` as it conflicts
69 with the `divmod` test
70*/
71_div(a, b) {
72 auto d, sign;
73 sign = 0;
74 if (a < 0) {
75 sign = !sign;
76 a = -a;
77 }
78 if (b < 0) {
79 sign = !sign;
80 b = -a;
81 }
82
83 d = 0; while(a >= b) {
84 a = a - b;
85 d++;
86 }
87 if (sign) d = -d;
88 return (d);
89}
90_udiv(a, b) {
91 auto d;
92 d = 0; while(a >= b | a < 0) {
93 a = a - b;
94 d++;
95 }
96 return (d);
97}
98
99/* TODO: Try to implement this function with assembly
100 Problem with this implementation is that it is not
101 mapped to the operator */
102_rem (a, b) {
103 auto d;
104 while(a >= b) {
105 a = a - b;
106 }
107 return (a);
108}
109_urem(a, b) {
110 auto d;
111 while(a >= b | a < 0) {
112 a = a - b;
113 }
114 return (a);
115}
116
117printn(n, b, sign) {
118 auto a, c, d, __div, __rem;
119
120 /* use correct div/rem based on sign */
121 __div = sign ? &_div : &_udiv;
122 __rem = sign ? &_rem : &_urem;
123
124 if (sign & n < 0) {
125 putchar('-');
126 n = -n;
127 }
128
129 if(a=__div(n, b)) /* assignment, not test for equality */
130 printn(a, b, 0); /* recursive */
131 c = __rem(n,b) + '0';
132 if (c > '9') c += 7;
133 putchar(c);
134}
135
136printf(str, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) {
137 auto i, j, arg, c;
138 i = 0;
139 j = 0;
140
141 arg = &x1;
142
143 c = char(str, i);
144 while (c != 0) {
145 if (c == '\n') {
146 putchar(0xD); // \r
147 }
148
149 if(c == '%') {
150 i += 1;
151 c = char(str, i);
152 if (c == 0) {
153 return;
154 } else if (c == 'd') {
155 printn(*arg, 10, 1);
156 } else if (c == 'u') {
157 printn(*arg, 10, 0);
158 } else if (c == 'p') {
159 putchar('$');
160 printn(*arg, 16, 0);
161 } else if (c == 'c') {
162 putchar(*arg);
163 } else if (c == 's') { /* clobbers `c`, the last one */
164 while (c = char(*arg, j++)) {
165 putchar(c);
166 }
167 } else if (c == 'z' | c == 'l') { /* hack for %zu %lu, % */
168 c = '%';
169 goto while_end;
170 } else {
171 putchar('%');
172 arg += 2; /* word size */
173 }
174 arg -= 2; /* word size */
175 } else {
176 putchar(c); /* ECHO */
177 }
178 i++;
179 c = char(str, i);
180 while_end:;
181 }
182}
183
184strlen(s) {
185 auto n;
186 n = 0;
187 while (char(s, n)) n++;
188 return (n);
189}
190
191toupper(c) {
192 if ('a' <= c & c <= 'z') return (c - 'a' + 'A');
193 return (c);
194}
195
196
197/* memory related functions */
198memset(addr, val, size) {
199 extrn lchar;
200 auto i;
201 i = 0;
202 while (i < size) {
203 lchar(addr, i, val);
204 i += 1;
205 }
206}