📄 gencode.c
字号:
/* Fatal error message and exit. This method is called when an inconsistency is detected in the generation table. */voidfatal_error (const struct m6811_opcode_def *opcode, const char *msg, ...){ va_list argp; fprintf (stderr, "Fatal error: "); va_start (argp, msg); vfprintf (stderr, msg, argp); va_end (argp); fprintf (stderr, "\n"); if (opcode) { fprintf (stderr, "Opcode: 0x%02x %s %s\n", opcode->insn_code, opcode->name ? opcode->name : "(null)", opcode->operands ? opcode->operands : "(null)"); } exit (1);}/* Format and pretty print for the code generation. (printf like format). */voidprint (FILE *fp, int col, const char *msg, ...){ va_list argp; char buf[1024]; int cur_col = -1; int i; /* Format in a buffer. */ va_start (argp, msg); vsprintf (buf, msg, argp); va_end (argp); /* Basic pretty print: - Every line is indented at column 'col', - Indentation is updated when '{' and '}' are found, - Indentation is incremented by the special character '@' (not displayed). - New lines inserted automatically after ';' */ for (i = 0; buf[i]; i++) { if (buf[i] == '{') col += indent_level; else if (buf[i] == '}') col -= indent_level; else if (buf[i] == '@') { col += indent_level; continue; } if (cur_col == -1 && buf[i] != ' ' && buf[i] != '\t' && buf[i] != '\n') { cur_col = 0; while (cur_col < col) { fputc (' ', fp); cur_col++; } } if (buf[i] == '}') col -= indent_level; else if (buf[i] == '{') col += indent_level; else if (buf[i] == '\n') cur_col = -1; if (cur_col != -1 || buf[i] == '\n') fputc (buf[i], fp); if (buf[i] == ';') { fputc ('\n', fp); cur_col = -1; } }}/* Generate the code to obtain the operands before execution of the instruction. Operands are copied in local variables. This allows to have the same instruction pattern and different operand formats. There is a maximum of 3 variables: 8-bits 16-bits 1st operand: src8 src16 2nd operand: dst8 dst16 alt operand: addr addr The operand string is interpreted as follows: a Copy A register in the local 8-bits variable. b " B " ccr " ccr " d " D " " " 16-bits variable. x " X " y " Y " sp " SP " pc " PC " * 68HC11 page0 memory pointer. Get 8-bits page0 offset from program, set up 'addr' local variable to refer to the location in page0. Copy the 8/16-bits value pointed to by 'addr' in a 8/16-bits variable. (x) 68HC11 indirect access with X register. Get 8-bits unsigned offset from program, set up 'addr' = X + offset. Copy the 8/16-bits value pointed to by 'addr' in a 8/16-bits variable. (y) Same as (x) with Y register. () 68HC11 extended address mode (global variable). Get 16-bits address from program and set 'addr'. Copy the 8/16-bits value pointed to by 'addr' in a 8/16-bits variable. [] 68HC12 indexed addressing mode (sp) Pop Pop a 8/16-bits value from stack and set in a 8/16-bits variable. r Relative branch Get 8-bits relative branch, compute absolute address and set 'addr' # 68HC11 immediate value Get a 8/16-bits value from program and set a 8/16-bits variable. &(x) &(y) &() Similar to (x), (y) and () except that we don't read the value pointed to by 'addr' (ie, only 'addr' is setup). Used by jmp/jsr. &[] Similar to [] but don't read the value pointed to by the address. , Operand separator. - End of input operands. Example: (x),a->a addr = x + (uint16) (fetch8 (proc)); src8 = a *,#,r addr = (uint16) (fetch8 (proc)) <- Temporary 'addr' src8 = read_mem8 (proc, addr) dst8 = fetch8 (proc) addr = fetch_relbranch (proc) <- Final 'addr' Returns 1 if the 'addr' operand is set, 0 otherwise. */intgen_fetch_operands (FILE *fp, int col, const struct m6811_opcode_def *opcode, const char *operand_size){ static char *vars[2] = { "src", "dst" }; char c; int addr_set = 0; int cur_var = 0; const char *operands = opcode->operands; if (operands == 0) operands = ""; while ((c = *operands++) != 0) { switch (c) { case 'a': if (cur_var >= 2) fatal_error (opcode, "Too many locals"); print (fp, col, "%s8 = cpu_get_a (proc);", vars[cur_var]); break; case 'b': if (cur_var >= 2) fatal_error (opcode, "Too many locals"); print (fp, col, "%s8 = cpu_get_b (proc);", vars[cur_var]); break; case 'd': if (cur_var >= 2) fatal_error (opcode, "Too many locals"); print (fp, col, "%s16 = cpu_get_d (proc);", vars[cur_var]); break; case 'x': if (cur_var >= 2) fatal_error (opcode, "Too many locals"); print (fp, col, "%s16 = cpu_get_x (proc);", vars[cur_var]); break; case 'y': if (cur_var >= 2) fatal_error (opcode, "Too many locals"); print (fp, col, "%s16 = cpu_get_y (proc);", vars[cur_var]); break; case '*': if (cur_var >= 2) fatal_error (opcode, "Too many locals"); if (addr_set) fatal_error (opcode, "Wrong use of '*', 'addr' already used"); addr_set = 1; current_insn_size += 1; print (fp, col, "addr = (uint16) cpu_fetch8 (proc);"); print (fp, col, "%s%s = memory_read%s (proc, addr);", vars[cur_var], operand_size, operand_size); break; case '&': if (addr_set) fatal_error (opcode, "Wrong use of '&', 'addr' already used"); addr_set = 1; if (strncmp (operands, "(x)", 3) == 0) { current_insn_size += 1; print (fp, col, "addr = cpu_get_x (proc) + (uint16) cpu_fetch8 (proc);"); operands += 3; } else if (strncmp (operands, "(y)", 3) == 0) { current_insn_size += 1; print (fp, col, "addr = cpu_get_y (proc) + (uint16) cpu_fetch8 (proc);"); operands += 3; } else if (strncmp (operands, "()", 2) == 0) { current_insn_size += 2; print (fp, col, "addr = cpu_fetch16 (proc);"); operands += 2; } else if (strncmp (operands, "[]", 2) == 0) { current_insn_size += 1; print (fp, col, "addr = cpu_get_indexed_operand_addr (proc, 0);"); operands += 2; } else { fatal_error (opcode, "Unknown operand"); } break; case '(': if (cur_var >= 2) fatal_error (opcode, "Too many locals"); if (addr_set) fatal_error (opcode, "Wrong use of '(', 'addr' already used"); if (strncmp (operands, "x)", 2) == 0) { addr_set = 1; current_insn_size += 1; print (fp, col, "addr = cpu_get_x (proc) + (uint16) cpu_fetch8 (proc);"); print (fp, col, "%s%s = memory_read%s (proc, addr);", vars[cur_var], operand_size, operand_size); operands += 2; } else if (strncmp (operands, "y)", 2) == 0) { addr_set = 1; current_insn_size += 1; print (fp, col, "addr = cpu_get_y (proc) + (uint16) cpu_fetch8 (proc);"); print (fp, col, "%s%s = memory_read%s (proc, addr);", vars[cur_var], operand_size, operand_size); operands += 2; } else if (strncmp (operands, ")", 1) == 0) { addr_set = 1; current_insn_size += 2; print (fp, col, "addr = cpu_fetch16 (proc);"); print (fp, col, "%s%s = memory_read%s (proc, addr);", vars[cur_var], operand_size, operand_size); operands++; } else if (strncmp (operands, "@)", 2) == 0) { current_insn_size += 2; print (fp, col, "addr = cpu_fetch16 (proc);"); print (fp, col, "%s%s = memory_read%s (proc, addr);", vars[cur_var], operand_size, operand_size); operands += 2; } else if (strncmp (operands, "sp)", 3) == 0) { print (fp, col, "%s%s = cpu_%s_pop_uint
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -