An emulator, assembler, and disassembler for the Sega Game Gear
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 

186 lignes
4.0 KiB

  1. /* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
  2. Released under the terms of the MIT License. See LICENSE for details. */
  3. #include <stdlib.h>
  4. #include "state.h"
  5. #include "io.h"
  6. #include "../logging.h"
  7. /*
  8. Initialize default values in an AssemblerState object.
  9. */
  10. void state_init(AssemblerState *state)
  11. {
  12. state->header.offset = DEFAULT_HEADER_OFFSET;
  13. state->header.checksum = true;
  14. state->header.product_code = 0;
  15. state->header.version = 0;
  16. state->header.region = DEFAULT_REGION;
  17. state->header.rom_size = DEFAULT_DECLSIZE;
  18. state->optimizer = false;
  19. state->rom_size = 0;
  20. state->lines = NULL;
  21. state->includes = NULL;
  22. state->instructions = NULL;
  23. state->data = NULL;
  24. state->symtable = NULL;
  25. }
  26. /*
  27. Deallocate the contents of an AssemblerState object.
  28. */
  29. void state_free(AssemblerState *state)
  30. {
  31. asm_lines_free(state->lines);
  32. asm_includes_free(state->includes);
  33. asm_instructions_free(state->instructions);
  34. asm_data_free(state->data);
  35. asm_symtable_free(state->symtable);
  36. }
  37. /*
  38. Initialize an ASMSymbolTable and place it in *symtable_ptr.
  39. */
  40. void asm_symtable_init(ASMSymbolTable **symtable_ptr)
  41. {
  42. ASMSymbolTable *symtable;
  43. if (!(symtable = malloc(sizeof(ASMSymbolTable))))
  44. OUT_OF_MEMORY()
  45. for (size_t bucket = 0; bucket < SYMBOL_TABLE_BUCKETS; bucket++)
  46. symtable->buckets[bucket] = NULL;
  47. *symtable_ptr = symtable;
  48. }
  49. /*
  50. Deallocate an ASMLine list.
  51. */
  52. void asm_lines_free(ASMLine *line)
  53. {
  54. while (line) {
  55. ASMLine *temp = line->next;
  56. free(line->data);
  57. free(line);
  58. line = temp;
  59. }
  60. }
  61. /*
  62. Deallocate an ASMInclude list.
  63. */
  64. void asm_includes_free(ASMInclude *include)
  65. {
  66. while (include) {
  67. ASMInclude *temp = include->next;
  68. line_buffer_free(include->lines);
  69. free(include);
  70. include = temp;
  71. }
  72. }
  73. /*
  74. Deallocate an ASMInstruction list.
  75. */
  76. void asm_instructions_free(ASMInstruction *inst)
  77. {
  78. while (inst) {
  79. ASMInstruction *temp = inst->next;
  80. if (inst->symbol)
  81. free(inst->symbol);
  82. free(inst);
  83. inst = temp;
  84. }
  85. }
  86. /*
  87. Deallocate an ASMData list.
  88. */
  89. void asm_data_free(ASMData *data)
  90. {
  91. while (data) {
  92. ASMData *temp = data->next;
  93. free(data->data);
  94. free(data);
  95. data = temp;
  96. }
  97. }
  98. /*
  99. Deallocate an ASMSymbolTable.
  100. */
  101. void asm_symtable_free(ASMSymbolTable *symtable)
  102. {
  103. if (!symtable)
  104. return;
  105. for (size_t bucket = 0; bucket < SYMBOL_TABLE_BUCKETS; bucket++) {
  106. ASMSymbol *sym = symtable->buckets[bucket], *temp;
  107. while (sym) {
  108. temp = sym->next;
  109. free(sym->symbol);
  110. free(sym);
  111. sym = temp;
  112. }
  113. }
  114. free(symtable);
  115. }
  116. /*
  117. Hash a string key into a symbol table bucket index.
  118. This uses the djb2 algorithm: http://www.cse.yorku.ca/~oz/hash.html
  119. */
  120. static inline size_t hash_key(const char *key)
  121. {
  122. size_t hash = 5381;
  123. while (*key)
  124. hash = ((hash << 5) + hash) + *(key++);
  125. return hash % SYMBOL_TABLE_BUCKETS;
  126. }
  127. /*
  128. Search for a key in the symbol table.
  129. Return the corresponding symbol on success and NULL on failure.
  130. */
  131. const ASMSymbol* asm_symtable_find(const ASMSymbolTable *tab, const char *key)
  132. {
  133. ASMSymbol *symbol = tab->buckets[hash_key(key)];
  134. while (symbol) {
  135. if (!strcmp(key, symbol->symbol))
  136. return symbol;
  137. symbol = symbol->next;
  138. }
  139. return NULL;
  140. }
  141. /*
  142. Insert a symbol into the table.
  143. TODO: return boolean on success instead of void.
  144. */
  145. void asm_symtable_insert(ASMSymbolTable *tab, ASMSymbol *symbol)
  146. {
  147. size_t index = hash_key(symbol->symbol);
  148. symbol->next = tab->buckets[index];
  149. tab->buckets[index] = symbol;
  150. }
  151. #ifdef DEBUG_MODE
  152. /*
  153. DEBUG FUNCTION: Print out an ASMLine list to stdout.
  154. */
  155. void asm_lines_print(const ASMLine *line)
  156. {
  157. DEBUG("Dumping ASMLines:")
  158. while (line) {
  159. DEBUG("- %-40.*s [%s:%02zu]", (int) line->length, line->data,
  160. line->filename, line->original->lineno)
  161. line = line->next;
  162. }
  163. }
  164. #endif