/* Sun Mar 21 18:15:59 JST 2004 */ /* Sun Mar 21 18:43:45 JST 2004 */ /* Sun Mar 21 19:40:22 JST 2004 */ #include #include typedef struct { char symbol[16]; int value; int dupe; } symbol_t; symbol_t symbols[128]; int n_symbols; typedef struct { int start; int refers[512]; int n_refers; unsigned short bytes[8192]; int n_bytes; } object_t; object_t objects[1024]; int n_objects; int n_bytes; int checksum; #define DOLLAR 1024 int symbolcmp(const void *_x, const void *_y) { symbol_t *x = (symbol_t *)_x, *y = (symbol_t *)_y; return strcmp(x->symbol, y->symbol); } int register_symbol(char *s, int value) { int i; for (i = 0; i < n_symbols; i++) { if (strcmp(symbols[i].symbol, s) == 0) { if (symbols[i].value < 0) { symbols[i].value = value; } else { symbols[i].dupe = 1; } return i; } } strcpy(symbols[n_symbols].symbol, s); symbols[n_symbols].value = value; symbols[n_symbols].dupe = 0; n_symbols++; return n_symbols-1; } int find_symbol(char *s) { int i; for (i = 0; i < n_symbols; i++) { if (strcmp(symbols[i].symbol, s) == 0) { return i; } } return -1; } int parse(char *s) { char *p, *q, *r; int i, value, index, n_value; p = strtok(s, " "); switch (*p) { case 'D': q = strtok(NULL, " "); sscanf(strtok(NULL, " "), "%x", &value); register_symbol(q, objects[n_objects-1].start + value); break; case 'E': q = strtok(NULL, " "); index = find_symbol(q); if (index == -1) { objects[n_objects-1].refers[objects[n_objects-1].n_refers] = register_symbol(q, -1); } else { objects[n_objects-1].refers[objects[n_objects-1].n_refers] = index; } objects[n_objects-1].n_refers++; break; case 'C': sscanf(strtok(NULL, " "), "%x", &n_value); for (i = 0; i < n_value; i++) { q = strtok(NULL, " "); if (strcmp(q, "$") == 0) { objects[n_objects-1].bytes[objects[n_objects-1].n_bytes] = DOLLAR; objects[n_objects-1].n_bytes++; sscanf(strtok(NULL, " "), "%x", &objects[n_objects-1].bytes[objects[n_objects-1].n_bytes]); objects[n_objects-1].n_bytes++; i++; } else { sscanf(q, "%x", &objects[n_objects-1].bytes[objects[n_objects-1].n_bytes]); objects[n_objects-1].n_bytes++; } } break; case 'Z': objects[n_objects].n_refers = 0; objects[n_objects].n_bytes = 0; objects[n_objects].start = objects[n_objects-1].start + objects[n_objects-1].n_bytes; n_objects++; break; } } int main() { int icase, iline, i, j; char s[1024]; for (icase = 1; ; icase++) { n_symbols = 0; n_objects = 1; objects[0].n_refers = 0; objects[0].n_bytes = 0; objects[0].start = 0x100; for (iline = 0; ; iline++) { gets(s); if (strcmp(s, "$") == 0) { if (iline == 0) { return 0; } break; } parse(s); } n_bytes = 0; checksum = 0; for (i = 0; i < n_objects; i++) { for (j = 0; j < objects[i].n_bytes; j++, n_bytes++) { if (objects[i].bytes[j] == DOLLAR) { if (symbols[objects[i].refers[objects[i].bytes[j+1]]].value < 0) { objects[i].bytes[j] = objects[i].bytes[j+1] = 0; } else { objects[i].bytes[j ] = symbols[objects[i].refers[objects[i].bytes[j+1]]].value >> 8; objects[i].bytes[j+1] = symbols[objects[i].refers[objects[i].bytes[j+1]]].value & 0xff; } } checksum = (checksum << 1) | ((checksum & 0x8000) ? 1 : 0); checksum += objects[i].bytes[j]; checksum &= 0xffff; } } if (icase > 1) { printf("\n"); } printf("Case %d: checksum = %04X\n", icase, checksum); printf(" SYMBOL ADDR\n"); printf("-------- ----\n"); qsort(symbols, n_symbols, sizeof(symbol_t), symbolcmp); for (i = 0; i < n_symbols; i++) { if (symbols[i].value < 0) { printf("%-8s ????", symbols[i].symbol); } else { printf("%-8s %04X", symbols[i].symbol, symbols[i].value); } if (symbols[i].dupe) { printf(" M\n"); } else { printf("\n"); } } } }