r5d.c (1936B)
1 // Copyright 2020, Brian Swetland <swetland@frotz.net> 2 // Licensed under the Apache License, Version 2.0. 3 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <stdint.h> 7 #include <unistd.h> 8 #include <fcntl.h> 9 #include <string.h> 10 11 #include "risc5.h" 12 13 void disasm(uint32_t pc, uint32_t ins) { 14 char buf[256]; 15 risc5dis(pc, ins, buf); 16 printf("%08x: %08x %s\n", pc, ins, buf); 17 } 18 19 const char* readname(int fd) { 20 static char name[64]; 21 for (int n = 0; n < 64; n++) { 22 if (read(fd, name + n, 1) != 1) exit(1); 23 if (name[n] == 0) return name; 24 } 25 exit(1); 26 return NULL; 27 } 28 29 uint32_t readint(int fd) { 30 uint32_t n; 31 if (read(fd, &n, 4) != 4) exit(1); 32 return n; 33 } 34 35 uint32_t readbyte(int fd) { 36 uint8_t n; 37 if (read(fd, &n, 1) != 1) exit(1); 38 return n; 39 } 40 41 uint32_t dishdr(int fd) { 42 const char* name = readname(fd); 43 uint32_t key = readint(fd); 44 uint32_t cls = readbyte(fd); 45 uint32_t size = readint(fd); 46 printf("[ name='%s', key=%08x, class=%02x, size=%u ]\n", 47 name, key, cls, size); 48 printf("[ imports:"); 49 for (;;) { 50 name = readname(fd); 51 if (name[0] == 0) break; 52 printf(" %s(%08x)", name, readint(fd)); 53 } 54 printf(" ]\n"); 55 // type descrs? 56 uint32_t n = readint(fd) / 4; 57 printf("[ typedesc=%u", n); 58 while (n > 0) { readint(fd); n--; } 59 // data? 60 n = readint(fd); 61 printf(", data=%08x", n); 62 // stringdata 63 n = readint(fd); 64 printf(", stringdata=%u", n); 65 while (n > 0) { readbyte(fd); n--; } 66 // instructions 67 n = readint(fd); 68 printf(", instructions=%u ]\n", n); 69 return n; 70 } 71 72 int main(int argc, char** argv) { 73 int fd; 74 if (argc != 2) return -1; 75 if ((fd = open(argv[1], O_RDONLY)) < 0) return -1; 76 77 uint32_t count; 78 count = strlen(argv[1]); 79 if ((count > 5) && (!strcmp(argv[1] + count - 4, ".rsc"))) { 80 count = dishdr(fd); 81 } else { 82 count = 0xffffffff; 83 } 84 85 uint32_t ins; 86 uint32_t pc = 0; 87 while (count > 0) { 88 count--; 89 if (read(fd, &ins, sizeof(ins)) != sizeof(ins)) break; 90 disasm(pc, ins); 91 pc += 4; 92 } 93 return 0; 94 }