1 /*
2 * This file is part of x48, an emulator of the HP-48sx Calculator.
3 * Copyright (C) 1994 Eddie C. Dost (ecd@dressler.de)
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 /* $Log: rpl.c,v $
21 * Revision 1.3 1995/01/11 18:20:01 ecd
22 * major update to support HP48 G/GX
23 *
24 * Revision 1.2 1994/12/07 20:20:50 ecd
25 * lots of more functions
26 *
27 * Revision 1.2 1994/12/07 20:20:50 ecd
28 * lots of more functions
29 *
30 * Revision 1.1 1994/12/07 10:15:47 ecd
31 * Initial revision
32 *
33 *
34 * $Id: rpl.c,v 1.3 1995/01/11 18:20:01 ecd Exp ecd $
35 */
36
37 #include "global.h"
38
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <unistd.h>
42 #include <string.h>
43
44 #include "hp48.h"
45 #include "hp48_emu.h"
46 #include "rpl.h"
47 #include "debugger.h"
48 #include "append.h"
49 #include "disasm.h"
50 #include "romio.h"
51 #define DEFINE_TRANS_TABLE 1
52 #include "hp48char.h"
53 #undef DEFINE_TRANS_TABLE
54
55 struct objfunc {
56 char *name;
57 short length;
58 word_20 prolog;
59 char *(*func) __ProtoType__((word_20 *addr, char *string));
60 } objects[] = {
61 { "System Binary", 0, DOBINT, dec_bin_int },
62 { "Real", 0, DOREAL, dec_real },
63 { "Long Real", 0, DOEREL, dec_long_real },
64 { "Complex", 0, DOCMP, dec_complex },
65 { "Long Complex", 0, DOECMP, dec_long_complex },
66 { "Character", 0, DOCHAR, dec_char },
67 { "Array", 0, DOARRY, dec_array },
68 { "Linked Array", 0, DOLNKARRY, dec_lnk_array },
69 { "String", 2, DOCSTR, dec_string },
70 { "Hex String", 1, DOHSTR, dec_hex_string },
71 { "List", 0, DOLIST, dec_list },
72 { "Directory", 0, DORRP, skip_ob },
73 { "Symbolic", 0, DOSYMB, dec_symb },
74 { "Unit", 0, DOEXT, dec_unit },
75 { "Tagged", 0, DOTAG, skip_ob },
76 { "Graphic", 0, DOGROB, skip_ob },
77 { "Library", 0, DOLIB, dec_library },
78 { "Backup", 0, DOBAK, skip_ob },
79 { "Library Data", 0, DOEXT0, dec_library_data },
80 { "ACPTR", 0, DOACPTR, dec_acptr },
81 { "External 2", 0, DOEXT2, skip_ob },
82 { "External 3", 0, DOEXT3, skip_ob },
83 { "External 4", 0, DOEXT4, skip_ob },
84 { "Program", 0, DOCOL, dec_prog },
85 { "Code", 1, DOCODE, dec_code },
86 { "Global Ident", 0, DOIDNT, dec_global_ident },
87 { "Local Ident", 0, DOLAM, dec_local_ident },
88 { "XLib Name", 0, DOROMP, dec_xlib_name },
89 { "*", 0, UM_MUL, dec_unit_op },
90 { "/", 0, UM_DIV, dec_unit_op },
91 { "^", 0, UM_POW, dec_unit_op },
92 { " ", 0, UM_PRE, dec_unit_op },
93 { "_", 0, UM_END, dec_unit_op },
94 { 0, 0, 0 }
95 };
96
97 char *
98 #ifdef __FunctionProto__
skip_ob(word_20 * addr,char * string)99 skip_ob(word_20 *addr, char *string)
100 #else
101 skip_ob(addr, string)
102 word_20 *addr;
103 char *string;
104 #endif
105 {
106 word_20 size, type;
107 char *p = string;
108 struct objfunc *op;
109
110 type = read_nibbles(*addr - 5, 5);
111 for (op = objects; op->prolog != 0; op++)
112 {
113 if (op->prolog == type)
114 break;
115 }
116
117 if (op->prolog)
118 {
119 sprintf(p, "%s", op->name);
120 p += strlen(p);
121 }
122
123 size = read_nibbles(*addr, 5);
124 *addr += size;
125
126 *p = '\0';
127 return p;
128 }
129
130 long
131 #ifdef __FunctionProto__
hxs2real(long hxs)132 hxs2real(long hxs)
133 #else
134 hxs2real(hxs)
135 long hxs;
136 #endif
137 {
138 int n = 0, c = 1;
139
140 while (hxs)
141 {
142 n += (hxs & 0xf) * c;
143 c *= 10;
144 hxs >>= 4;
145 }
146 return n;
147 }
148
149 char *
150 #ifdef __FunctionProto__
dec_bin_int(word_20 * addr,char * string)151 dec_bin_int(word_20 *addr, char *string)
152 #else
153 dec_bin_int(addr, string)
154 word_20 *addr;
155 char *string;
156 #endif
157 {
158 char *p = string;
159 word_20 n = 0;
160
161 n = read_nibbles(*addr, 5);
162 *addr += 5;
163 sprintf(p, "<%lXh>", (long)n);
164 p += strlen(p);
165 return p;
166 }
167
168 char *
169 #ifdef __FunctionProto__
real_number(word_20 * addr,char * string,int ml,int xl)170 real_number(word_20 *addr, char *string, int ml, int xl)
171 #else
172 real_number(addr, string, ml, xl)
173 word_20 *addr;
174 char *string;
175 int ml;
176 int xl;
177 #endif
178 {
179 hp_real r;
180 long re, xs;
181 int i;
182 char fmt[20];
183 char m[16];
184 char *p = string;
185
186 /*
187 * Read the number
188 */
189 r.x = read_nibbles(*addr, xl);
190 *addr += xl;
191 r.ml = read_nibbles(*addr, ml - 8);
192 *addr += ml - 8;
193 r.mh = read_nibbles(*addr, 8);
194 *addr += 8;
195 r.m = read_nibbles(*addr, 1);
196 (*addr)++;
197 r.s = read_nibbles(*addr, 1);
198 (*addr)++;
199
200 /*
201 * Figure out the exponent
202 */
203 xs = 5;
204 while (--xl) xs *= 10;
205 re = hxs2real(r.x);
206 if (re >= xs)
207 re = re - 2 * xs;
208
209
210 if ((re >= 0) && (re < ml + 1))
211 {
212 if (r.s >= 5)
213 *p++ = '-';
214
215 sprintf(fmt, "%%.1X%%.8lX%%.%dlX", ml - 8);
216 sprintf(m, fmt, r.m, r.mh, r.ml);
217
218 for (i = 0; i <= re; i++)
219 *p++ = m[i];
220 *p++ = '.';
221 for ( ; i < ml + 1; i++)
222 *p++ = m[i];
223 p--;
224 while(*p == '0') p--;
225 if (*p == '.') p--;
226 *++p = '\0';
227
228 return p;
229 }
230
231 if ((re < 0) && (re >= -ml - 1))
232 {
233 sprintf(fmt, "%%.1X%%.8lX%%.%dlX", ml - 8);
234 sprintf(m, fmt, r.m, r.mh, r.ml);
235
236 for (i = ml; m[i] == '0'; i--) ;
237
238 if (-re <= ml - i + 1)
239 {
240 if (r.s >= 5)
241 *p++ = '-';
242
243 *p++ = '.';
244
245 for (i = 1; i < -re; i++)
246 *p++ = '0';
247
248 for (i = 0; i < ml + 1; i++)
249 *p++ = m[i];
250 p--;
251 while(*p == '0') p--;
252 *++p = '\0';
253
254 return p;
255 }
256 }
257
258 sprintf(fmt, "%%s%%X.%%.8lX%%.%dlX", ml - 8);
259 sprintf(p, fmt, (r.s >= 5) ? "-" : "", r.m, r.mh, r.ml);
260
261 p += strlen(p) - 1;
262
263 while(*p == '0') p--;
264 *++p = '\0';
265
266 if (re)
267 {
268 sprintf(p, "E%ld", re);
269 p += strlen(p);
270 *p = '\0';
271 }
272
273 return p;
274 }
275
276 char *
277 #ifdef __FunctionProto__
dec_real(word_20 * addr,char * string)278 dec_real(word_20 *addr, char *string)
279 #else
280 dec_real(addr, string)
281 word_20 *addr;
282 char *string;
283 #endif
284 {
285 return real_number(addr, string, 11, 3);
286 }
287
288 char *
289 #ifdef __FunctionProto__
dec_long_real(word_20 * addr,char * string)290 dec_long_real(word_20 *addr, char *string)
291 #else
292 dec_long_real(addr, string)
293 word_20 *addr;
294 char *string;
295 #endif
296 {
297 return real_number(addr, string, 14, 5);
298 }
299
300 char *
301 #ifdef __FunctionProto__
dec_complex(word_20 * addr,char * string)302 dec_complex(word_20 *addr, char *string)
303 #else
304 dec_complex(addr, string)
305 word_20 *addr;
306 char *string;
307 #endif
308 {
309 char *p = string;
310
311 *p++ = '(';
312 p = real_number(addr, p, 11, 3);
313 *p++ = ',';
314 p = real_number(addr, p, 11, 3);
315 *p++ = ')';
316 *p = '\0';
317 return p;
318 }
319
320 char *
321 #ifdef __FunctionProto__
dec_long_complex(word_20 * addr,char * string)322 dec_long_complex(word_20 *addr, char *string)
323 #else
324 dec_long_complex(addr, string)
325 word_20 *addr;
326 char *string;
327 #endif
328 {
329 char *p = string;
330
331 *p++ = '(';
332 p = real_number(addr, p, 14, 5);
333 *p++ = ',';
334 p = real_number(addr, p, 14, 5);
335 *p++ = ')';
336 *p = '\0';
337 return p;
338 }
339
340 char *
341 #ifdef __FunctionProto__
dec_string(word_20 * addr,char * string)342 dec_string(word_20 *addr, char *string)
343 #else
344 dec_string(addr, string)
345 word_20 *addr;
346 char *string;
347 #endif
348 {
349 word_20 len;
350 unsigned char c;
351 char *p = string;
352 int i, n;
353
354 len = read_nibbles(*addr, 5);
355 *addr += 5;
356 len -= 5;
357 len /= 2;
358
359 n = len;
360 if (len > 1000)
361 n = 1000;
362
363 *p++ = '\"';
364 for (i = 0; i < n; i++)
365 {
366 c = read_nibbles(*addr, 2);
367 *addr += 2;
368 if (hp48_trans_tbl[c].trans)
369 {
370 sprintf(p, hp48_trans_tbl[c].trans);
371 p += strlen(p);
372 }
373 else
374 *p++ = c;
375 }
376
377 if (n != len)
378 {
379 *p++ = '.';
380 *p++ = '.';
381 *p++ = '.';
382 }
383
384 *p++ = '\"';
385 *p = '\0';
386 return p;
387 }
388
389 char *
390 #ifdef __FunctionProto__
dec_hex_string(word_20 * addr,char * string)391 dec_hex_string(word_20 *addr, char *string)
392 #else
393 dec_hex_string(addr, string)
394 word_20 *addr;
395 char *string;
396 #endif
397 {
398 int len, lead, i, n;
399 static char hex[] = "0123456789ABCDEF";
400 char *p = string;
401
402 len = read_nibbles(*addr, 5);
403 *addr += 5;
404 len -= 5;
405
406 if (len <= 16)
407 {
408 *p++ = '#';
409 *p++ = ' ';
410 lead = 1;
411 for (i = len - 1; i >= 0; i--)
412 {
413 *p = hex[read_nibble(*addr + i)];
414 if (lead)
415 if ((i != 0) && (*p == '0'))
416 p--;
417 else
418 lead = 0;
419 p++;
420 }
421
422 *p++ = 'h';
423 }
424 else
425 {
426 *p++ = 'C';
427 *p++ = '#';
428 *p++ = ' ';
429
430 sprintf(p, "%d", len);
431 p += strlen(p);
432
433 *p++ = ' ';
434
435 n = len;
436 if (len > 1000)
437 n = 1000;
438
439 for (i = 0; i < n; i++)
440 *p++ = hex[read_nibble(*addr + i)];
441
442 if (n != len)
443 {
444 *p++ = '.';
445 *p++ = '.';
446 *p++ = '.';
447 }
448 }
449
450 *addr += len;
451
452 *p = '\0';
453 return p;
454 }
455
456 char *
457 #ifdef __FunctionProto__
dec_list(word_20 * addr,char * string)458 dec_list(word_20 *addr, char *string)
459 #else
460 dec_list(addr, string)
461 word_20 *addr;
462 char *string;
463 #endif
464 {
465 word_20 semi;
466 char *p = string;
467
468 *p++ = '{';
469 *p++ = ' ';
470 semi = read_nibbles(*addr, 5);
471 while (semi != SEMI)
472 {
473 p = dec_rpl_obj(addr, p);
474 semi = read_nibbles(*addr, 5);
475 if (semi != SEMI)
476 {
477 *p++ = ' ';
478 *p = '\0';
479 }
480 }
481 *p++ = ' ';
482 *p++ = '}';
483 *p = '\0';
484
485 *addr += 5;
486 return p;
487 }
488
489 char *
490 #ifdef __FunctionProto__
dec_symb(word_20 * addr,char * string)491 dec_symb(word_20 *addr, char *string)
492 #else
493 dec_symb(addr, string)
494 word_20 *addr;
495 char *string;
496 #endif
497 {
498 word_20 semi;
499 char *p = string;
500
501 semi = read_nibbles(*addr, 5);
502 *p++ = '\'';
503 while (semi != SEMI)
504 {
505 p = dec_rpl_obj(addr, p);
506 semi = read_nibbles(*addr, 5);
507 if (semi != SEMI)
508 {
509 *p++ = ' ';
510 *p = '\0';
511 }
512 }
513 *addr += 5;
514
515 *p++ = '\'';
516 *p = '\0';
517 return p;
518 }
519
520 char *
521 #ifdef __FunctionProto__
dec_unit(word_20 * addr,char * string)522 dec_unit(word_20 *addr, char *string)
523 #else
524 dec_unit(addr, string)
525 word_20 *addr;
526 char *string;
527 #endif
528 {
529 word_20 semi;
530 char *p = string;
531
532 semi = read_nibbles(*addr, 5);
533 while (semi != SEMI)
534 {
535 p = dec_rpl_obj(addr, p);
536 semi = read_nibbles(*addr, 5);
537 if (semi != SEMI)
538 {
539 *p++ = ' ';
540 *p = '\0';
541 }
542 }
543 *addr += 5;
544 return p;
545 }
546
547 char *
548 #ifdef __FunctionProto__
dec_unit_op(word_20 * addr,char * string)549 dec_unit_op(word_20 *addr, char *string)
550 #else
551 dec_unit_op(addr, string)
552 word_20 *addr;
553 char *string;
554 #endif
555 {
556 word_20 op;
557 char *p = string;
558
559 op = read_nibbles(*addr - 5, 5);
560 switch (op)
561 {
562 case UM_MUL:
563 *p++ = '*';
564 break;
565 case UM_DIV:
566 *p++ = '/';
567 break;
568 case UM_POW:
569 *p++ = '^';
570 break;
571 case UM_END:
572 *p++ = '_';
573 break;
574 case UM_PRE:
575 p--;
576 break;
577 default:
578 break;
579 }
580 *p = '\0';
581 return p;
582 }
583
584 char *
585 #ifdef __FunctionProto__
dec_library(word_20 * addr,char * string)586 dec_library(word_20 *addr, char *string)
587 #else
588 dec_library(addr, string)
589 word_20 *addr;
590 char *string;
591 #endif
592 {
593 word_20 libsize, libidsize;
594 /*
595 word_20 hashoff, mesgoff, linkoff, cfgoff;
596 word_20 mesgloc, cfgloc;
597 */
598 int i, libnum;
599 unsigned char c;
600 char *p = string;
601
602 libsize = read_nibbles(*addr, 5);
603 libidsize = read_nibbles(*addr + 5, 2);
604 libnum = read_nibbles(*addr + 2 * libidsize + 9, 3);
605
606 sprintf(p, "Library %d: ", libnum);
607 p += strlen(p);
608
609 for (i = 0; i < libidsize; i++)
610 {
611 c = read_nibbles(*addr + 2 * i + 7, 2);
612 if (hp48_trans_tbl[c].trans)
613 {
614 sprintf(p, hp48_trans_tbl[c].trans);
615 p += strlen(p);
616 }
617 else
618 *p++ = c;
619 }
620
621 *addr += libsize;
622
623 *p = '\0';
624 return p;
625 }
626
627 char *
628 #ifdef __FunctionProto__
dec_library_data(word_20 * addr,char * string)629 dec_library_data(word_20 *addr, char *string)
630 #else
631 dec_library_data(addr, string)
632 word_20 *addr;
633 char *string;
634 #endif
635 {
636 word_20 size;
637 char *p = string;
638
639 size = read_nibbles(*addr, 5);
640
641 sprintf(p, "Library Data");
642 p += strlen(p);
643
644 *addr += size;
645
646 *p = '\0';
647 return p;
648 }
649
650 char *
651 #ifdef __FunctionProto__
dec_acptr(word_20 * addr,char * string)652 dec_acptr(word_20 *addr, char *string)
653 #else
654 dec_acptr(addr, string)
655 word_20 *addr;
656 char *string;
657 #endif
658 {
659 word_20 size;
660 char *p = string;
661 int i;
662 static char hex[] = "0123456789ABCDEF";
663
664 if (opt_gx)
665 {
666 size = 10;
667 sprintf(p, "ACPTR ");
668 p += strlen(p);
669 for (i = 0; i < 5; i++)
670 *p++ = hex[read_nibble(*addr + i)];
671 *p++ = ' ';
672 for (i = 5; i < 10; i++)
673 *p++ = hex[read_nibble(*addr + i)];
674 }
675 else
676 {
677 size = read_nibbles(*addr, 5);
678 sprintf(p, "Ext 1");
679 p += strlen(p);
680 }
681
682 *addr += size;
683
684 *p = '\0';
685 return p;
686 }
687
688 char *
689 #ifdef __FunctionProto__
dec_prog(word_20 * addr,char * string)690 dec_prog(word_20 *addr, char *string)
691 #else
692 dec_prog(addr, string)
693 word_20 *addr;
694 char *string;
695 #endif
696 {
697 word_20 semi;
698 char *p = string;
699
700 semi = read_nibbles(*addr, 5);
701 while (semi != SEMI)
702 {
703 p = dec_rpl_obj(addr, p);
704 semi = read_nibbles(*addr, 5);
705 if (semi != SEMI)
706 {
707 *p++ = ' ';
708 *p = '\0';
709 }
710 }
711 *addr += 5;
712 return p;
713 }
714
715 char *
716 #ifdef __FunctionProto__
dec_code(word_20 * addr,char * string)717 dec_code(word_20 *addr, char *string)
718 #else
719 dec_code(addr, string)
720 word_20 *addr;
721 char *string;
722 #endif
723 {
724 char *p = string;
725 word_20 n, len;
726
727 len = read_nibbles(*addr, 5);
728 sprintf(p, "Code");
729 p += strlen(p);
730
731 n = 0;
732 while (n < len)
733 {
734 /*
735 *addr = disassemble(*addr, p);
736 */
737 n += len;
738 }
739
740 *addr += len;
741 return p;
742 }
743
744 char *
745 #ifdef __FunctionProto__
dec_local_ident(word_20 * addr,char * string)746 dec_local_ident(word_20 *addr, char *string)
747 #else
748 dec_local_ident(addr, string)
749 word_20 *addr;
750 char *string;
751 #endif
752 {
753 int len, i, n;
754 char *p = string;
755 unsigned char c;
756
757 len = read_nibbles(*addr, 2);
758 *addr += 2;
759
760 n = len;
761 if (len > 1000)
762 n = 1000;
763
764 for (i = 0; i < n; i++)
765 {
766 c = read_nibbles(*addr, 2);
767 *addr += 2;
768 if (hp48_trans_tbl[c].trans)
769 {
770 sprintf(p, hp48_trans_tbl[c].trans);
771 p += strlen(p);
772 }
773 else
774 *p++ = c;
775 }
776
777 if (n != len)
778 {
779 *p++ = '.';
780 *p++ = '.';
781 *p++ = '.';
782 }
783
784 *p = '\0';
785 return p;
786 }
787
788 char *
789 #ifdef __FunctionProto__
dec_global_ident(word_20 * addr,char * string)790 dec_global_ident(word_20 *addr, char *string)
791 #else
792 dec_global_ident(addr, string)
793 word_20 *addr;
794 char *string;
795 #endif
796 {
797 int len, i, n;
798 char *p = string;
799 unsigned char c;
800
801 len = read_nibbles(*addr, 2);
802 *addr += 2;
803
804 n = len;
805 if (len > 1000)
806 n = 1000;
807
808 for (i = 0; i < n; i++)
809 {
810 c = read_nibbles(*addr, 2);
811 *addr += 2;
812 if (hp48_trans_tbl[c].trans)
813 {
814 sprintf(p, hp48_trans_tbl[c].trans);
815 p += strlen(p);
816 }
817 else
818 *p++ = c;
819 }
820
821 if (n != len)
822 {
823 *p++ = '.';
824 *p++ = '.';
825 *p++ = '.';
826 }
827
828 *p = '\0';
829 return p;
830 }
831
832 char *
833 #ifdef __FunctionProto__
xlib_name(int lib,int command,char * string)834 xlib_name(int lib, int command, char *string)
835 #else
836 xlib_name(lib, command, string)
837 int lib;
838 int command;
839 char *string;
840 #endif
841 {
842 int n, len;
843 int i, lib_n = 0;
844 unsigned char c;
845 word_20 romptab, acptr;
846 word_20 offset, hash_end;
847 word_20 lib_addr, name_addr;
848 word_20 type, ram_base, ram_mask;
849 short present = 0;
850 char *p = string;
851
852 /*
853 * Configure RAM to address 0x70000
854 */
855 ram_base = saturn.mem_cntl[1].config[0];
856 ram_mask = saturn.mem_cntl[1].config[1];
857 if (opt_gx)
858 {
859 saturn.mem_cntl[1].config[0] = 0x80000;
860 saturn.mem_cntl[1].config[1] = 0xc0000;
861 romptab = ROMPTAB_GX;
862 }
863 else
864 {
865 saturn.mem_cntl[1].config[0] = 0x70000;
866 saturn.mem_cntl[1].config[1] = 0xf0000;
867 romptab = ROMPTAB_SX;
868 }
869
870 /*
871 * look up number of installed libs in romptab
872 */
873 n = read_nibbles(romptab, 3);
874 romptab += 3;
875
876 if (n > 0)
877 {
878 /*
879 * look up lib number in romptab
880 */
881 while (n--)
882 {
883 lib_n = read_nibbles(romptab, 3);
884 romptab += 3;
885 if (lib_n == lib)
886 break;
887 romptab += 5;
888 if (opt_gx)
889 romptab += 8;
890 }
891 if (lib_n == lib)
892 {
893 /*
894 * look at hash table pointer
895 */
896 lib_addr = read_nibbles(romptab, 5);
897 if (opt_gx)
898 {
899 romptab += 5;
900 acptr = read_nibbles(romptab, 5);
901 if (acptr != 0x00000)
902 {
903 saturn.mem_cntl[1].config[0] = ram_base;
904 saturn.mem_cntl[1].config[1] = ram_mask;
905 sprintf(p, "XLIB %d %d", lib, command);
906 p += strlen(p);
907 return p;
908 }
909 }
910 lib_addr += 3;
911 offset = read_nibbles(lib_addr, 5);
912 if (offset > 0)
913 {
914 /*
915 * look at the hash table
916 */
917 lib_addr += offset;
918
919 /*
920 * check if library is in ROM
921 */
922 if (!opt_gx)
923 if (lib_addr < 0x70000)
924 saturn.mem_cntl[1].config[0] = 0xf0000;
925
926 /*
927 * check pointer type
928 */
929 type = read_nibbles(lib_addr, 5);
930 if (type == DOBINT)
931 {
932 /*
933 * follow pointer to real address
934 */
935 lib_addr += 5;
936 lib_addr = read_nibbles(lib_addr, 5);
937 }
938 else if (type == DOACPTR)
939 {
940 /*
941 * follow pointer to real address
942 */
943 lib_addr += 5;
944 acptr = lib_addr + 5;
945 lib_addr = read_nibbles(lib_addr, 5);
946 acptr = read_nibbles(acptr, 5);
947 if (acptr != 0x00000)
948 {
949 saturn.mem_cntl[1].config[0] = ram_base;
950 saturn.mem_cntl[1].config[1] = ram_mask;
951 sprintf(p, "XLIB %d %d", lib, command);
952 p += strlen(p);
953 return p;
954 }
955 }
956
957 /*
958 * get length of hash table
959 */
960 lib_addr += 5;
961 hash_end = read_nibbles(lib_addr, 5);
962 hash_end += lib_addr;
963
964 /*
965 * go into real name table
966 */
967 lib_addr += 85;
968 offset = read_nibbles(lib_addr, 5);
969 lib_addr += offset;
970
971 /*
972 * look at library name number 'command'
973 */
974 offset = 5 * command;
975 lib_addr += offset;
976 if (lib_addr < hash_end)
977 {
978 offset = read_nibbles(lib_addr, 5);
979 if (offset > 0)
980 {
981 name_addr = lib_addr - offset;
982 len = read_nibbles(name_addr, 2);
983 name_addr += 2;
984 present = 1;
985 for (i = 0; i < len; i++)
986 {
987 c = read_nibbles(name_addr, 2);
988 name_addr += 2;
989 if (hp48_trans_tbl[c].trans)
990 {
991 sprintf(p, hp48_trans_tbl[c].trans);
992 p += strlen(p);
993 }
994 else
995 *p++ = c;
996 }
997 *p = '\0';
998 }
999 }
1000 }
1001 }
1002 }
1003
1004 /*
1005 * Reconfigure RAM
1006 */
1007 saturn.mem_cntl[1].config[0] = ram_base;
1008 saturn.mem_cntl[1].config[1] = ram_mask;
1009
1010 if (!present)
1011 {
1012 sprintf(p, "XLIB %d %d", lib, command);
1013 p += strlen(p);
1014 }
1015 return p;
1016 }
1017
1018 char *
1019 #ifdef __FunctionProto__
dec_xlib_name(word_20 * addr,char * string)1020 dec_xlib_name(word_20 *addr, char *string)
1021 #else
1022 dec_xlib_name(addr, string)
1023 word_20 *addr;
1024 char *string;
1025 #endif
1026 {
1027 int lib, command;
1028
1029 lib = read_nibbles(*addr, 3);
1030 *addr += 3;
1031 command = read_nibbles(*addr, 3);
1032 *addr += 3;
1033
1034 return xlib_name(lib, command, string);
1035 }
1036
1037 char *
1038 #ifdef __FunctionProto__
any_array(word_20 * addr,char * string,short lnk_flag)1039 any_array(word_20 *addr, char *string, short lnk_flag)
1040 #else
1041 any_array(addr, string, lnk_flag)
1042 word_20 *addr;
1043 char *string;
1044 short lnk_flag;
1045 #endif
1046 {
1047 word_20 len, type, dim;
1048 word_20 *dim_lens, *dims;
1049 word_20 array_addr, elem_addr;
1050 long elems;
1051 int d, i;
1052 char *p = string;
1053 struct objfunc *op;
1054
1055 array_addr = *addr;
1056 len = read_nibbles(*addr, 5);
1057 *addr += 5;
1058 type = read_nibbles(*addr, 5);
1059 *addr += 5;
1060 dim = read_nibbles(*addr, 5);
1061 *addr += 5;
1062
1063 for (op = objects; op->prolog != 0; op++)
1064 {
1065 if (op->prolog == type)
1066 break;
1067 }
1068
1069 dim_lens = (word_20 *)malloc(dim * sizeof(word_20));
1070 dims = (word_20 *)malloc(dim * sizeof(word_20));
1071 elems = 1;
1072 for (i = 0; i < dim; i++)
1073 {
1074 dim_lens[i] = read_nibbles(*addr, 5);
1075 dims[i] = dim_lens[i];
1076 elems *= dim_lens[i];
1077 *addr += 5;
1078 }
1079
1080 if (op->prolog == 0)
1081 {
1082 sprintf(p, "of Type %.5lX, Dim %ld, Size ", type, (long)dim);
1083 p += strlen(p);
1084 for (i = 0; i < dim; i++)
1085 {
1086 sprintf(p, "%ld", (long)dim_lens[i]);
1087 p += strlen(p);
1088 if (i < dim - 1)
1089 {
1090 sprintf(p, " x ");
1091 p += strlen(p);
1092 }
1093 }
1094 *p = '\0';
1095 *addr = array_addr + len;
1096 free(dim_lens);
1097 free(dims);
1098 return p;
1099 }
1100
1101 d = -1;
1102 while (elems--)
1103 {
1104 if (d < dim - 1)
1105 {
1106 for ( ; d < dim - 1; d++)
1107 {
1108 *p++ = '[';
1109 }
1110 d = dim - 1;
1111 }
1112 if (lnk_flag)
1113 {
1114 elem_addr = read_nibbles(*addr, 5);
1115 elem_addr += *addr;
1116 *addr += 5;
1117 p = (*op->func)(&elem_addr, p);
1118 }
1119 else
1120 p = (*op->func)(addr, p);
1121 *p = '\0';
1122 dims[d]--;
1123 if (dims[d])
1124 *p++ = ' ';
1125 while (dims[d] == 0)
1126 {
1127 dims[d] = dim_lens[d];
1128 d--;
1129 dims[d]--;
1130 *p++ = ']';
1131 }
1132 }
1133
1134 free(dim_lens);
1135 free(dims);
1136 *addr = array_addr + len;
1137
1138 *p = '\0';
1139 return p;
1140 }
1141
1142 char *
1143 #ifdef __FunctionProto__
dec_array(word_20 * addr,char * string)1144 dec_array(word_20 *addr, char *string)
1145 #else
1146 dec_array(addr, string)
1147 word_20 *addr;
1148 char *string;
1149 #endif
1150 {
1151 return any_array(addr, string, 0);
1152 }
1153
1154 char *
1155 #ifdef __FunctionProto__
dec_lnk_array(word_20 * addr,char * string)1156 dec_lnk_array(word_20 *addr, char *string)
1157 #else
1158 dec_lnk_array(addr, string)
1159 word_20 *addr;
1160 char *string;
1161 #endif
1162 {
1163 return any_array(addr, string, 1);
1164 }
1165
1166 char *
1167 #ifdef __FunctionProto__
dec_char(word_20 * addr,char * string)1168 dec_char(word_20 *addr, char *string)
1169 #else
1170 dec_char(addr, string)
1171 word_20 *addr;
1172 char *string;
1173 #endif
1174 {
1175 char *p = string;
1176 unsigned char c;
1177
1178 c = read_nibbles(*addr, 2);
1179 *addr += 2;
1180
1181 *p++ = '\'';
1182 if (hp48_trans_tbl[c].trans)
1183 {
1184 sprintf(p, hp48_trans_tbl[c].trans);
1185 p += strlen(p);
1186 }
1187 else
1188 *p++ = c;
1189 *p++ = '\'';
1190
1191 *p = 0;
1192 return p;
1193 }
1194
1195 short
1196 #ifdef __FunctionProto__
check_xlib(word_20 addr,char * string)1197 check_xlib(word_20 addr, char *string)
1198 #else
1199 check_xlib(addr, string)
1200 word_20 addr;
1201 char *string;
1202 #endif
1203 {
1204 int n, lib, command;
1205 word_20 romptab;
1206 word_20 offset, link_end;
1207 word_20 acptr;
1208 word_20 lib_addr;
1209 word_20 type, ram_base, ram_mask;
1210 char *p = string;
1211
1212 /*
1213 * Configure RAM to address 0x70000
1214 */
1215 ram_base = saturn.mem_cntl[1].config[0];
1216 ram_mask = saturn.mem_cntl[1].config[1];
1217 if (opt_gx)
1218 {
1219 saturn.mem_cntl[1].config[0] = 0x80000;
1220 saturn.mem_cntl[1].config[1] = 0xc0000;
1221 romptab = ROMPTAB_GX;
1222 }
1223 else
1224 {
1225 saturn.mem_cntl[1].config[0] = 0x70000;
1226 saturn.mem_cntl[1].config[1] = 0xf0000;
1227 romptab = ROMPTAB_SX;
1228 }
1229
1230 /*
1231 * look up number of installed libs in romptab
1232 */
1233 n = read_nibbles(romptab, 3);
1234 romptab += 3;
1235
1236 /*
1237 fprintf(stderr, "Number of Libraries = %d\n", n);
1238 fflush(stderr);
1239 */
1240
1241 if (n > 0)
1242 {
1243 /*
1244 * look up lib number in romptab
1245 */
1246 while (n--)
1247 {
1248 lib = read_nibbles(romptab, 3);
1249 romptab += 3;
1250 /*
1251 fprintf(stderr, "Library num = %d\n", lib);
1252 fflush(stderr);
1253 */
1254 /*
1255 * look at link table pointer
1256 */
1257 lib_addr = read_nibbles(romptab, 5);
1258 /*
1259 fprintf(stderr, "Library addr = %.5lx\n", lib_addr);
1260 fflush(stderr);
1261 */
1262 romptab += 5;
1263
1264 if (opt_gx)
1265 {
1266 acptr = read_nibbles(romptab, 5);
1267 romptab += 8;
1268 if (acptr != 0x00000)
1269 continue;
1270 }
1271
1272 lib_addr += 13;
1273 offset = read_nibbles(lib_addr, 5);
1274 if (offset > 0)
1275 {
1276 /*
1277 * look at the link table
1278 */
1279 lib_addr += offset;
1280 /*
1281 fprintf(stderr, "Link table addr = %.5lx\n", lib_addr);
1282 fflush(stderr);
1283 */
1284 /*
1285 * check if library is in ROM
1286 */
1287 if (!opt_gx)
1288 if (lib_addr < 0x70000)
1289 saturn.mem_cntl[1].config[0] = 0xf0000;
1290
1291 /*
1292 * check pointer type
1293 */
1294 type = read_nibbles(lib_addr, 5);
1295 if (type == DOBINT)
1296 {
1297 /*
1298 * follow pointer to real address
1299 */
1300 lib_addr += 5;
1301 lib_addr = read_nibbles(lib_addr, 5);
1302 }
1303 /*
1304 fprintf(stderr, "Link table addr (2) = %.5lx\n", lib_addr);
1305 fflush(stderr);
1306 */
1307 /*
1308 * get length of link table
1309 */
1310 lib_addr += 5;
1311 link_end = read_nibbles(lib_addr, 5);
1312 link_end += lib_addr;
1313 /*
1314 fprintf(stderr, "Link table end = %.5lx\n", link_end);
1315 fflush(stderr);
1316 */
1317 /*
1318 * look at library commands
1319 */
1320 lib_addr += 5;
1321 command = 0;
1322 while (lib_addr < link_end)
1323 {
1324 offset = read_nibbles(lib_addr, 5);
1325 if (offset > 0)
1326 {
1327 if (addr == ((lib_addr + offset) & 0xfffff))
1328 {
1329 p = xlib_name(lib, command, p);
1330 saturn.mem_cntl[1].config[0] = ram_base;
1331 saturn.mem_cntl[1].config[1] = ram_mask;
1332 return 1;
1333 }
1334 }
1335 lib_addr += 5;
1336 command++;
1337 }
1338 if (opt_gx)
1339 saturn.mem_cntl[1].config[0] = 0x80000;
1340 else
1341 saturn.mem_cntl[1].config[0] = 0x70000;
1342 }
1343 }
1344 }
1345
1346 /*
1347 * Reconfigure RAM
1348 */
1349 saturn.mem_cntl[1].config[0] = ram_base;
1350 saturn.mem_cntl[1].config[1] = ram_mask;
1351
1352 return 0;
1353 }
1354
1355
1356 char *
1357 #ifdef __FunctionProto__
dec_rpl_obj(word_20 * addr,char * string)1358 dec_rpl_obj(word_20 *addr, char *string)
1359 #else
1360 dec_rpl_obj(addr, string)
1361 word_20 *addr;
1362 char *string;
1363 #endif
1364 {
1365 word_20 prolog = 0;
1366 word_20 prolog_2;
1367 char *p = string;
1368 char tmp_str[80];
1369 struct objfunc *op;
1370
1371 prolog = read_nibbles(*addr, 5);
1372
1373 for (op = objects; op->prolog != 0; op++)
1374 {
1375 if (op->prolog == prolog)
1376 break;
1377 }
1378
1379 if (op->prolog == 0)
1380 {
1381 if (check_xlib(prolog, tmp_str))
1382 {
1383 p = append_str(p, tmp_str);
1384 }
1385 else
1386 {
1387 prolog_2 = read_nibbles(prolog, 5);
1388 for (op = objects; op->prolog != 0; op++)
1389 {
1390 if (op->prolog == prolog_2)
1391 break;
1392 }
1393 if (op->prolog)
1394 p = dec_rpl_obj(&prolog, p);
1395 else
1396 p = append_str(p, "External");
1397 }
1398 *addr += 5;
1399 return p;
1400 }
1401
1402 *addr += 5;
1403 p = (*op->func)(addr, p);
1404
1405 return p;
1406 }
1407
1408 void
1409 #ifdef __FunctionProto__
decode_rpl_obj_2(word_20 addr,char * typ,char * dat)1410 decode_rpl_obj_2(word_20 addr, char *typ, char *dat)
1411 #else
1412 decode_rpl_obj_2(addr, typ, dat)
1413 word_20 addr;
1414 char *typ;
1415 char *dat;
1416 #endif
1417 {
1418 word_20 prolog = 0;
1419 int len;
1420 char tmp_str[80];
1421 struct objfunc *op;
1422
1423 typ[0] = '\0';
1424 dat[0] = '\0';
1425
1426 prolog = read_nibbles(addr, 5);
1427
1428 for (op = objects; op->prolog != 0; op++)
1429 {
1430 if (op->prolog == prolog)
1431 break;
1432 }
1433
1434 if (op->prolog == 0)
1435 {
1436 if (addr == SEMI)
1437 {
1438 append_str(typ, "Primitive Code");
1439 append_str(dat, "SEMI");
1440 }
1441 else if (addr + 5 == prolog)
1442 {
1443 append_str(typ, "Primitive Code");
1444 sprintf(dat, "at %.5lX", prolog);
1445 }
1446 else
1447 {
1448 append_str(typ, "PTR");
1449 sprintf(dat, "%.5lX", prolog);
1450 }
1451 return;
1452 }
1453
1454 if (op->prolog == DOCOL)
1455 {
1456 if (check_xlib(addr, tmp_str))
1457 {
1458 append_str(typ, "XLib Call");
1459 append_str(dat, tmp_str);
1460 return;
1461 }
1462 }
1463
1464 if (op->length)
1465 {
1466 len = (read_nibbles(addr + 5, 5) - 5) / op->length;
1467 sprintf(typ, "%s %d", op->name, len);
1468 }
1469 else
1470 {
1471 append_str(typ, op->name);
1472 }
1473
1474 addr += 5;
1475 (*op->func)(&addr, dat);
1476
1477 return;
1478 }
1479
1480 char *
1481 #ifdef __FunctionProto__
decode_rpl_obj(word_20 addr,char * buf)1482 decode_rpl_obj(word_20 addr, char *buf)
1483 #else
1484 decode_rpl_obj(addr, buf)
1485 word_20 addr;
1486 char *buf;
1487 #endif
1488 {
1489 word_20 prolog = 0;
1490 int len;
1491 char *p = buf;
1492 char tmp_str[80];
1493 struct objfunc *op;
1494
1495 prolog = read_nibbles(addr, 5);
1496
1497 for (op = objects; op->prolog != 0; op++)
1498 {
1499 if (op->prolog == prolog)
1500 break;
1501 }
1502
1503 if (op->prolog == 0)
1504 {
1505 if (addr == SEMI)
1506 {
1507 p = append_str(buf, "Primitive Code");
1508 p = append_tab_16(buf);
1509 p = append_str(p, "SEMI");
1510 }
1511 else if (addr + 5 == prolog)
1512 {
1513 p = append_str(buf, "Primitive Code");
1514 p = append_tab_16(buf);
1515 sprintf(p, "at %.5lX", prolog);
1516 p += strlen(p);
1517 *p = '\0';
1518 }
1519 else
1520 {
1521 p = append_str(buf, "PTR");
1522 p = append_tab_16(buf);
1523 sprintf(p, "%.5lX", prolog);
1524 p += strlen(p);
1525 *p = '\0';
1526 }
1527 return p;
1528 }
1529
1530 if (op->prolog == DOCOL)
1531 {
1532 if (check_xlib(addr, tmp_str))
1533 {
1534 p = append_str(buf, "XLib Call");
1535 p = append_tab_16(buf);
1536 p = append_str(p, tmp_str);
1537 return p;
1538 }
1539 }
1540
1541 p = append_str(buf, op->name);
1542
1543 if (op->length)
1544 {
1545 len = (read_nibbles(addr + 5, 5) - 5) / op->length;
1546 sprintf(p, " %d", len);
1547 p += strlen(p);
1548 }
1549
1550 p = append_tab_16(buf);
1551 addr += 5;
1552 p = (*op->func)(&addr, p);
1553
1554 return p;
1555 }
1556
1557