Nugget
Bare-metal libraries and examples for the original PlayStation
Loading...
Searching...
No Matches
gte-regio.c
Go to the documentation of this file.
1// GTE register I/O tests: data/control register read/write, sign extension,
2// SXY FIFO, IRGB/ORGB, LZCS/LZCR, FLAG register, CTC2 sign extension.
3
4// ==========================================================================
5// Data register roundtrip and sign/zero extension
6// ==========================================================================
7
8// clang-format off
9
10CESTER_TEST(regio_mac0_roundtrip, gte_tests,
11 cop2_put(24, 0x12345678);
12 uint32_t out;
13 cop2_get(24, out);
14 cester_assert_uint_eq(0x12345678, out);
15)
16
17CESTER_TEST(regio_mac1_roundtrip, gte_tests,
18 cop2_put(25, 0xdeadbeef);
19 uint32_t out;
20 cop2_get(25, out);
21 cester_assert_uint_eq(0xdeadbeef, out);
22)
23
24CESTER_TEST(regio_ir0_sign_extend, gte_tests,
25 cop2_put(8, 0x0000ffff);
26 uint32_t out;
27 cop2_get(8, out);
28 cester_assert_uint_eq(0xffffffff, out);
29)
30
31CESTER_TEST(regio_ir1_sign_extend, gte_tests,
32 cop2_put(9, 0x00008000);
33 uint32_t out;
34 cop2_get(9, out);
35 cester_assert_uint_eq(0xffff8000, out);
36)
37
38CESTER_TEST(regio_ir2_positive, gte_tests,
39 cop2_put(10, 0x00001234);
40 uint32_t out;
41 cop2_get(10, out);
42 cester_assert_uint_eq(0x00001234, out);
43)
44
45CESTER_TEST(regio_ir3_positive, gte_tests,
46 cop2_put(11, 0x00007fff);
47 uint32_t out;
48 cop2_get(11, out);
49 cester_assert_uint_eq(0x00007fff, out);
50)
51
52CESTER_TEST(regio_vz0_sign_extend, gte_tests,
53 cop2_put(1, 0x0000ff00);
54 uint32_t out;
55 cop2_get(1, out);
56 cester_assert_uint_eq(0xffffff00, out);
57)
58
59CESTER_TEST(regio_vxy0_packed, gte_tests,
60 cop2_put(0, 0x00640032);
61 uint32_t out;
62 cop2_get(0, out);
63 cester_assert_uint_eq(0x00640032, out);
64)
65
66CESTER_TEST(regio_otz_zero_extend, gte_tests,
67 cop2_put(7, 0xffffffff);
68 uint32_t out;
69 cop2_get(7, out);
70 cester_assert_uint_eq(0x0000ffff, out);
71)
72
73CESTER_TEST(regio_sz_zero_extend, gte_tests,
74 cop2_put(16, 0xdeadbeef);
75 uint32_t out;
76 cop2_get(16, out);
77 cester_assert_uint_eq(0x0000beef, out);
78)
79
80CESTER_TEST(regio_rgbc_roundtrip, gte_tests,
81 cop2_put(6, 0xaa554080);
82 uint32_t out;
83 cop2_get(6, out);
84 cester_assert_uint_eq(0xaa554080, out);
85)
86
87CESTER_TEST(regio_res1_readwrite, gte_tests,
88 cop2_put(23, 0xdeadbeef);
89 uint32_t out;
90 cop2_get(23, out);
91 cester_assert_uint_eq(0xdeadbeef, out);
92)
93
94// ==========================================================================
95// SXY FIFO
96// ==========================================================================
97
98CESTER_TEST(regio_sxy_fifo_push, gte_tests,
99 cop2_put(12, 0x00010002);
100 cop2_put(13, 0x00030004);
101 cop2_put(14, 0x00050006);
102 cop2_put(15, 0x00070008);
103 uint32_t sxy0, sxy1, sxy2;
104 cop2_get(12, sxy0);
105 cop2_get(13, sxy1);
106 cop2_get(14, sxy2);
107 cester_assert_uint_eq(0x00030004, sxy0);
108 cester_assert_uint_eq(0x00050006, sxy1);
109 cester_assert_uint_eq(0x00070008, sxy2);
110)
111
112CESTER_TEST(regio_sxyp_read_returns_sxy2, gte_tests,
113 cop2_put(14, 0xaabbccdd);
114 uint32_t sxyp;
115 cop2_get(15, sxyp);
116 cester_assert_uint_eq(0xaabbccdd, sxyp);
117)
118
119CESTER_TEST(regio_sxy_fifo_triple_push, gte_tests,
120 cop2_put(15, 0x11111111);
121 cop2_put(15, 0x22222222);
122 cop2_put(15, 0x33333333);
123 uint32_t sxy0, sxy1, sxy2;
124 cop2_get(12, sxy0);
125 cop2_get(13, sxy1);
126 cop2_get(14, sxy2);
127 cester_assert_uint_eq(0x11111111, sxy0);
128 cester_assert_uint_eq(0x22222222, sxy1);
129 cester_assert_uint_eq(0x33333333, sxy2);
130)
131
132// ==========================================================================
133// IRGB / ORGB
134// ==========================================================================
135
136CESTER_TEST(regio_irgb_expand, gte_tests,
137 cop2_put(28, 0x7fff);
138 __asm__ volatile("nop; nop; nop; nop");
139 uint32_t ir1, ir2, ir3;
140 cop2_get(9, ir1);
141 cop2_get(10, ir2);
142 cop2_get(11, ir3);
143 cester_assert_uint_eq(0x00000f80, ir1);
144 cester_assert_uint_eq(0x00000f80, ir2);
145 cester_assert_uint_eq(0x00000f80, ir3);
146)
147
148CESTER_TEST(regio_irgb_individual, gte_tests,
149 cop2_put(28, 0x000a); // R=10, G=0, B=0
150 __asm__ volatile("nop; nop; nop; nop");
151 uint32_t ir1, ir2, ir3;
152 cop2_get(9, ir1);
153 cop2_get(10, ir2);
154 cop2_get(11, ir3);
155 cester_assert_uint_eq(0x00000500, ir1); // 10 << 7
156 cester_assert_uint_eq(0x00000000, ir2);
157 cester_assert_uint_eq(0x00000000, ir3);
158)
159
160CESTER_TEST(regio_orgb_pack, gte_tests,
161 cop2_put(9, 0x0f80);
162 cop2_put(10, 0x0f80);
163 cop2_put(11, 0x0f80);
164 uint32_t orgb;
165 cop2_get(29, orgb);
166 cester_assert_uint_eq(0x7fff, orgb);
167)
168
169// ORGB saturates, not truncates (psx-spx correct, Sony SDK wrong)
170CESTER_TEST(regio_orgb_saturate_negative, gte_tests,
171 cop2_put(9, 0xffff8000); // IR1 = -32768 (negative)
172 cop2_put(10, 0x00002000); // IR2 = 8192 (large positive)
173 cop2_put(11, 0x00000380); // IR3 = 896 (normal)
174 uint32_t orgb;
175 cop2_get(29, orgb);
176 uint32_t r = orgb & 0x1f;
177 uint32_t g = (orgb >> 5) & 0x1f;
178 uint32_t b = (orgb >> 10) & 0x1f;
179 cester_assert_uint_eq(0, r); // negative saturated to 0
180 cester_assert_uint_eq(31, g); // large saturated to 0x1f
181 cester_assert_uint_eq(7, b); // 896 >> 7 = 7
182)
183
184CESTER_TEST(regio_orgb_saturate_large, gte_tests,
185 cop2_put(9, 0x1000);
186 cop2_put(10, 0x1000);
187 cop2_put(11, 0x1000);
188 uint32_t orgb;
189 cop2_get(29, orgb);
190 // 0x1000>>7 = 0x20 = 32, saturated to 31
191 cester_assert_uint_eq(0x7fff, orgb);
192)
193
194// ==========================================================================
195// LZCS / LZCR
196// ==========================================================================
197
198CESTER_TEST(regio_lzcr_zero, gte_tests,
199 cop2_put(30, 0x00000000);
200 uint32_t lzcr;
201 cop2_get(31, lzcr);
202 cester_assert_uint_eq(32, lzcr);
203)
204
205CESTER_TEST(regio_lzcr_all_ones, gte_tests,
206 cop2_put(30, 0xffffffff);
207 uint32_t lzcr;
208 cop2_get(31, lzcr);
209 cester_assert_uint_eq(32, lzcr);
210)
211
212CESTER_TEST(regio_lzcr_one, gte_tests,
213 cop2_put(30, 0x00000001);
214 uint32_t lzcr;
215 cop2_get(31, lzcr);
216 cester_assert_uint_eq(31, lzcr);
217)
218
219CESTER_TEST(regio_lzcr_msb_set, gte_tests,
220 cop2_put(30, 0x80000000);
221 uint32_t lzcr;
222 cop2_get(31, lzcr);
223 cester_assert_uint_eq(1, lzcr);
224)
225
226CESTER_TEST(regio_lzcr_positive_mid, gte_tests,
227 cop2_put(30, 0x00010000);
228 uint32_t lzcr;
229 cop2_get(31, lzcr);
230 cester_assert_uint_eq(15, lzcr);
231)
232
233CESTER_TEST(regio_lzcr_negative_mid, gte_tests,
234 cop2_put(30, 0xfffe0000);
235 uint32_t lzcr;
236 cop2_get(31, lzcr);
237 cester_assert_uint_eq(15, lzcr);
238)
239
240// ==========================================================================
241// FLAG register
242// ==========================================================================
243
244CESTER_TEST(regio_flag_write_mask, gte_tests,
245 cop2_putc(31, 0xffffffff);
246 uint32_t flag = gte_read_flag();
247 cester_assert_uint_eq(0xfffff000, flag);
248)
249
250// Writing all-ones cannot tell 7FFFF000h from FFFFF000h: under the first, bit31 is
251// dropped on write and recomputed to 1 from the bits 13-18/23-30 that all-ones also
252// sets, so both masks yield 0xfffff000. Bit31 on its own is the discriminator.
253CESTER_TEST(regio_flag_bit31_not_writable, gte_tests,
254 cop2_putc(31, 1u << 31);
255 uint32_t flag = gte_read_flag();
256 ramsyscall_printf("FLAG bit31 alone reads back 0x%08x\n", flag);
258)
259
260CESTER_TEST(regio_flag_low_bits_masked, gte_tests,
261 cop2_putc(31, 0x00000fff);
262 uint32_t flag = gte_read_flag();
264)
265
266CESTER_TEST(regio_flag_bit12_no_summary, gte_tests,
267 cop2_putc(31, (1 << 12));
268 uint32_t flag = gte_read_flag();
269 cester_assert_uint_eq((1 << 12), flag);
270)
271
272CESTER_TEST(regio_flag_bits19_22_no_summary, gte_tests,
273 uint32_t flag;
274 int ok = 1;
275 int i;
276 for (i = 19; i <= 22; i++) {
277 cop2_putc(31, (1u << i));
278 flag = gte_read_flag();
279 if (flag != (1u << i)) ok = 0;
280 }
282)
283
284CESTER_TEST(regio_flag_bits13_18_set_summary, gte_tests,
285 uint32_t flag;
286 int ok = 1;
287 int i;
288 for (i = 13; i <= 18; i++) {
289 cop2_putc(31, (1u << i));
290 flag = gte_read_flag();
291 if (flag != ((1u << i) | (1u << 31))) ok = 0;
292 }
294)
295
296CESTER_TEST(regio_flag_bits23_30_set_summary, gte_tests,
297 uint32_t flag;
298 int ok = 1;
299 int i;
300 for (i = 23; i <= 30; i++) {
301 cop2_putc(31, (1u << i));
302 flag = gte_read_flag();
303 if (flag != ((1u << i) | (1u << 31))) ok = 0;
304 }
306)
307
308// ==========================================================================
309// Control register sign extension
310// ==========================================================================
311
312CESTER_TEST(regio_ctrl_r33_sign_extend, gte_tests,
313 cop2_putc(4, 0x00008000);
314 uint32_t out;
315 cop2_getc(4, out);
316 cester_assert_uint_eq(0xffff8000, out);
317)
318
319CESTER_TEST(regio_ctrl_zsf3_sign_extend, gte_tests,
320 cop2_putc(29, 0x0000ffff);
321 uint32_t out;
322 cop2_getc(29, out);
323 cester_assert_uint_eq(0xffffffff, out);
324)
325
326// H register sign-extension bug (psx-spx documented, Sony omitted)
327CESTER_TEST(regio_h_sign_extension_bug, gte_tests,
328 cop2_putc(26, 0x8000);
329 uint32_t h;
330 cop2_getc(26, h);
331 cester_assert_uint_eq(0xffff8000, h);
332)
333
334CESTER_TEST(regio_h_positive, gte_tests,
335 cop2_putc(26, 0x7fff);
336 uint32_t h;
337 cop2_getc(26, h);
338 cester_assert_uint_eq(0x00007fff, h);
339)
340
341// All single-16bit control regs sign-extend
342CESTER_TEST(regio_ctc2_sign_extend_all, gte_tests,
343 uint32_t out;
344 int ok = 1;
345 // R33(4), L33(12), LB3(20), H(26), DQA(27), ZSF3(29), ZSF4(30)
346 cop2_putc(4, 0x8000); cop2_getc(4, out); if (out != 0xffff8000) ok = 0;
347 cop2_putc(12, 0x8000); cop2_getc(12, out); if (out != 0xffff8000) ok = 0;
348 cop2_putc(20, 0x8000); cop2_getc(20, out); if (out != 0xffff8000) ok = 0;
349 cop2_putc(26, 0x8000); cop2_getc(26, out); if (out != 0xffff8000) ok = 0;
350 cop2_putc(27, 0x8000); cop2_getc(27, out); if (out != 0xffff8000) ok = 0;
351 cop2_putc(29, 0x8000); cop2_getc(29, out); if (out != 0xffff8000) ok = 0;
352 cop2_putc(30, 0x8000); cop2_getc(30, out); if (out != 0xffff8000) ok = 0;
354)
355
356// lm flag clamp behavior
357CESTER_TEST(regio_lm_clamp, gte_tests,
358 // GPF sf=1 lm=0: IR clamp -0x8000..0x7fff
359 cop2_put(8, 0x1000);
360 cop2_put(9, 0xffff8000);
361 cop2_put(10, 0x100);
362 cop2_put(11, 0x7fff);
363 cop2_put(6, 0x00808080);
365 cop2_cmd(COP2_GPF(1, 0));
366 int32_t mac1_lm0;
367 uint32_t ir1_lm0;
368 cop2_get(25, mac1_lm0);
369 cop2_get(9, ir1_lm0);
370 // GPF sf=1 lm=1
371 cop2_put(8, 0x1000);
372 cop2_put(9, 0xffff8000);
373 cop2_put(10, 0x100);
374 cop2_put(11, 0x7fff);
375 cop2_put(6, 0x00808080);
377 cop2_cmd(COP2_GPF(1, 1));
378 int32_t mac1_lm1;
379 uint32_t ir1_lm1;
380 cop2_get(25, mac1_lm1);
381 cop2_get(9, ir1_lm1);
382 cester_assert_int_eq(-32768, mac1_lm0);
383 cester_assert_int_eq(-32768, mac1_lm1);
384 cester_assert_uint_eq(0xffff8000, ir1_lm0); // lm=0: stays -32768
385 cester_assert_uint_eq(0x00000000, ir1_lm1); // lm=1: clamped to 0
386)
387
388// ==========================================================================
389// 32bit control registers: read-back fidelity, and whether commands write them
390//
391// psx-spx leaves an unanswered "(Input?, R/W?)" on TR (cnt5-7), BK
392// (cnt13-15), FC (cnt21-23), screen offset (cnt24-25) and DQB (cnt28). The
393// sign-extension tests above cover the 16bit control registers only.
394//
395// The assertion is that all-ones does not read back as zero. A "two reads
396// agree" check does not work here: it passes on a register stuck at zero.
397// ==========================================================================
398
399#define GTE_CTRL32_EACH(M) \
400 M(5) M(6) M(7) M(13) M(14) M(15) M(21) M(22) M(23) M(24) M(25) M(28)
401
402#define GTE_CTRL32_PROBE(r) \
403 { \
404 uint32_t _a; \
405 cop2_putc(r, _pat); \
406 cop2_getc(r, _a); \
407 if (_pat == 0xffffffffu && _a == 0u) _responds = 0; \
408 ramsyscall_printf(" c%d=0x%08x", (r), _a); \
409 }
410
411#define GTE_CTRL32_SET(r) cop2_putc(r, 0x0bad0000u | (r));
412
413#define GTE_CTRL32_CHECK(r) \
414 { \
415 uint32_t _o; \
416 cop2_getc(r, _o); \
417 if (_o != (0x0bad0000u | (r))) { \
418 _changed++; \
419 ramsyscall_printf("CTRL32 %s wrote c%d: 0x%08x\n", _nm, (r), _o); \
420 } \
421 }
422
423// FLAG is the one control register that is an output. Seed it with a pattern no
424// command can reproduce (all-ones reads back as 0xfffff000) and check the seed is
425// gone afterwards: that is what "the command rewrites FLAG" means, and a command
426// whose own result is zero would be invisible to an "it changed" test.
427#define GTE_CTRL32_CMDPROBE(NAME, OP) \
428 do { \
429 const char *_nm = (NAME); \
430 uint32_t _flag; \
431 GTE_CTRL32_EACH(GTE_CTRL32_SET) \
432 cop2_putc(31, 0xffffffffu); \
433 cop2_cmd(OP); \
434 cop2_getc(31, _flag); \
435 if (_flag == 0xfffff000u) { \
436 _flagkept++; \
437 ramsyscall_printf("CTRL32 %s left FLAG seeded\n", _nm); \
438 } \
439 ramsyscall_printf("CTRL32 %s FLAG=0x%08x\n", _nm, _flag); \
440 GTE_CTRL32_EACH(GTE_CTRL32_CHECK) \
441 } while (0)
442
443CESTER_TEST(regio_ctrl32_readback_table, gte_tests,
444 static const uint32_t pats[] = {
445 0x00000000u, 0xffffffffu, 0x12345678u, 0xa5a5a5a5u,
446 0x80000000u, 0x7fffffffu, 0x0000ffffu, 0xffff0000u,
447 };
448 int _responds = 1;
449 for (unsigned p = 0; p < sizeof(pats) / sizeof(pats[0]); p++) {
450 uint32_t _pat = pats[p];
451 ramsyscall_printf("CTRL32 pat=0x%08x", _pat);
453 ramsyscall_printf("\n");
454 }
456)
457
458CESTER_TEST(regio_ctrl32_command_writes, gte_tests,
459 int _changed = 0;
460 int _flagkept = 0;
461 cop2_put(0, 0x00200010); cop2_put(1, 0x00000040);
462 cop2_put(2, 0x0018000c); cop2_put(3, 0x00000050);
463 cop2_put(4, 0x00140008); cop2_put(5, 0x00000060);
464 cop2_put(6, 0x00808080); cop2_put(8, 0x1000);
465 GTE_CTRL32_CMDPROBE("RTPS", COP2_RTPS(0, 0));
466 GTE_CTRL32_CMDPROBE("RTPT", COP2_RTPT(0, 0));
470 GTE_CTRL32_CMDPROBE("SQR", COP2_SQR(0, 0));
471 GTE_CTRL32_CMDPROBE("DPCS", COP2_DPCS(0, 0));
472 GTE_CTRL32_CMDPROBE("DPCT", COP2_DPCT(0, 0));
473 GTE_CTRL32_CMDPROBE("DCPL", COP2_DCPL(0, 0));
474 GTE_CTRL32_CMDPROBE("INTPL", COP2_INTPL(0, 0));
475 GTE_CTRL32_CMDPROBE("NCS", COP2_NCS(0, 0));
476 GTE_CTRL32_CMDPROBE("NCT", COP2_NCT(0, 0));
477 GTE_CTRL32_CMDPROBE("NCCS", COP2_NCCS(0, 0));
478 GTE_CTRL32_CMDPROBE("NCCT", COP2_NCCT(0, 0));
479 GTE_CTRL32_CMDPROBE("NCDS", COP2_NCDS(0, 0));
480 GTE_CTRL32_CMDPROBE("NCDT", COP2_NCDT(0, 0));
481 GTE_CTRL32_CMDPROBE("CC", COP2_CC(0, 0));
482 GTE_CTRL32_CMDPROBE("CDP", COP2_CDP(0, 0));
483 GTE_CTRL32_CMDPROBE("GPF", COP2_GPF(0, 0));
484 GTE_CTRL32_CMDPROBE("GPL", COP2_GPL(0, 0));
485 GTE_CTRL32_CMDPROBE("MVMVA", COP2_MVMVA(0, 0, 0, 0, 0));
486 ramsyscall_printf("CTRL32 command-write count: %d, FLAG kept: %d\n", _changed, _flagkept);
487 cester_assert_int_eq(0, _changed);
488 cester_assert_int_eq(0, _flagkept);
489)
cester_assert_uint_eq(5, cause1)
ramsyscall_printf("T21 phase=%s t=%u v=%02x cause=%u size=%u stat=%02x\n", phase, t/1000, response[0], cause, size,(nopCause==3 &&nopSize >=1) ? stat[0] :0xff)
#define COP2_INTPL(sf, lm)
Definition cop2.h:142
#define cop2_cmd(op)
Definition cop2.h:175
#define COP2_GPL(sf, lm)
Definition cop2.h:169
#define COP2_NCS(sf, lm)
Definition cop2.h:149
#define COP2_NCCS(sf, lm)
Definition cop2.h:151
#define COP2_DPCT(sf, lm)
Definition cop2.h:140
#define cop2_put(reg, val)
Definition cop2.h:191
#define COP2_SQR(sf, lm)
Definition cop2.h:161
#define COP2_NCDS(sf, lm)
Definition cop2.h:153
#define COP2_NCCT(sf, lm)
Definition cop2.h:152
#define COP2_RTPT(sf, lm)
Definition cop2.h:130
#define cop2_getc(reg, dest)
Definition cop2.h:212
#define COP2_CDP(sf, lm)
Definition cop2.h:158
#define COP2_GPF(sf, lm)
Definition cop2.h:168
#define COP2_NCLIP
Definition cop2.h:133
#define cop2_putc(reg, val)
Definition cop2.h:205
#define COP2_RTPS(sf, lm)
Definition cop2.h:129
#define COP2_NCT(sf, lm)
Definition cop2.h:150
#define COP2_AVSZ3
Definition cop2.h:164
#define COP2_DPCS(sf, lm)
Definition cop2.h:139
#define COP2_MVMVA(sf, mx, v, cv, lm)
Definition cop2.h:145
#define cop2_get(reg, dest)
Definition cop2.h:198
#define COP2_DCPL(sf, lm)
Definition cop2.h:141
#define COP2_AVSZ4
Definition cop2.h:165
#define COP2_CC(sf, lm)
Definition cop2.h:157
#define COP2_NCDT(sf, lm)
Definition cop2.h:154
uint32_t r
Definition cpu.c:310
uint32_t out
Definition cpu.c:62
uint8_t g
Definition gte-depthcue.c:40
uint8_t b
Definition gte-depthcue.c:41
gte_clear_flag()
uint32_t ir1
Definition gte-edgecase.c:110
uint32_t sxy2
Definition gte-edgecase.c:38
uint32_t ir3
Definition gte-precision.c:322
int ok
Definition gte-regio.c:298
#define GTE_CTRL32_PROBE(r)
CESTER_TEST(regio_mac0_roundtrip, CESTER_TEST(gte_tests, cop2_put(24, 0x12345678);uint32_t out;cop2_get(24, out);cester_assert_uint_eq(0x12345678, out);)
Definition gte-regio.c:10
#define GTE_CTRL32_CMDPROBE(NAME, OP)
#define GTE_CTRL32_EACH(M)
gte_tests
Definition gte-regio.c:296
int _responds
Definition gte-regio.c:448
cester_assert_int_eq(1, ok)
uint32_t flag
Definition gte-regio.c:297
int i
Definition gte-regio.c:299
uint32_t sxy0
Definition gte-rtps.c:166
uint32_t sxy1
Definition gte-rtps.c:166
uint32_t ir2
Definition gte-sqr.c:26
__asm__(" .section .text.monitorSlotEntry, \"ax\", @progbits\n" " .align 2\n" " .global monitorSlotEntry\n" " .type monitorSlotEntry, @function\n" " .set push\n" " .set noreorder\n" " .set noat\n" "monitorSlotEntry:\n" " mfc0 $v0, $13\n" " nop\n" " andi $v0, $v0, 0x7c\n" " beqz $v0, 1f\n" " srl $v0, $v0, 2\n" " li $v1, " MON_STR(MON_SLOT_EXCMASK) "\n" " srlv $v1, $v1, $v0\n" " andi $v1, $v1, 1\n" " bnez $v1, 2f\n" " nop\n" " jr $ra\n" " nop\n" "1:\n" MON_SLOT_RX_TEST " jr $ra\n" " nop\n" "2:\n" " sw $a0, 0x10($k0)\n" " sw $a1, 0x14($k0)\n" " sw $a2, 0x18($k0)\n" " sw $a3, 0x1c($k0)\n" " mfc0 $a0, $12\n" " nop\n" " sw $a0, 0x8c($k0)\n" " mfc0 $a1, $13\n" " nop\n" " sw $a1, 0x90($k0)\n" " sw $k1, 0x6c($k0)\n" " sw $s0, 0x40($k0)\n" " sw $s1, 0x44($k0)\n" " sw $s2, 0x48($k0)\n" " sw $s3, 0x4c($k0)\n" " sw $s4, 0x50($k0)\n" " sw $s5, 0x54($k0)\n" " sw $s6, 0x58($k0)\n" " sw $s7, 0x5c($k0)\n" " sw $t0, 0x20($k0)\n" " sw $t1, 0x24($k0)\n" " sw $t2, 0x28($k0)\n" " sw $t3, 0x2c($k0)\n" " sw $t4, 0x30($k0)\n" " sw $t5, 0x34($k0)\n" " sw $t6, 0x38($k0)\n" " sw $t7, 0x3c($k0)\n" " sw $t8, 0x60($k0)\n" " sw $t9, 0x64($k0)\n" " sw $gp, 0x70($k0)\n" " sw $sp, 0x74($k0)\n" " sw $fp, 0x78($k0)\n" " mfhi $a0\n" " nop\n" " sw $a0, 0x84($k0)\n" " mflo $a0\n" " nop\n" " sw $a0, 0x88($k0)\n" " move $s0, $ra\n" " la $sp, monitorSlotStack + " MON_STR(MONITOR_SLOT_STACK_WORDS) " * 4 - 16\n" " jal monitorSlotDispatch\n" " nop\n" " lw $k0, 0x108($zero)\n" " move $ra, $s0\n" " lw $k0, 0($k0)\n" " nop\n" " addiu $k0, $k0, 8\n" " lw $a0, 0x84($k0)\n" " lw $a1, 0x88($k0)\n" " mthi $a0\n" " mtlo $a1\n" " lw $a0, 0x10($k0)\n" " lw $a1, 0x14($k0)\n" " lw $a2, 0x18($k0)\n" " lw $a3, 0x1c($k0)\n" " lw $t0, 0x20($k0)\n" " lw $t1, 0x24($k0)\n" " lw $t2, 0x28($k0)\n" " lw $t3, 0x2c($k0)\n" " lw $t4, 0x30($k0)\n" " lw $t5, 0x34($k0)\n" " lw $t6, 0x38($k0)\n" " lw $t7, 0x3c($k0)\n" " lw $t8, 0x60($k0)\n" " lw $t9, 0x64($k0)\n" " lw $s0, 0x40($k0)\n" " lw $sp, 0x74($k0)\n" " jr $ra\n" " nop\n" " .set pop\n" " .size monitorSlotEntry, . - monitorSlotEntry\n" " .previous\n")