int test_disassembler() { uint8_t tests[] = { 0x3a, 0x34, 0x12, // LD A, (0x1234) 0xdd, 0xcb, 0x12, 0x06, // RLC (IX + 0x12) 0xfd, 0x36, 0x10, 0x20, // LD (IY + 0x10), 0x20 }; struct disassemble_memory mem = { dis_read_byte, 0 }; dis_input = tests; parse_instruction(&mem, dis_write, false); dis_pointer = dis_buffer; if (strcmp(dis_buffer, "LD A, (0x1234)") != 0) { return 1; } parse_instruction(&mem, dis_write, false); dis_pointer = dis_buffer; if (strcmp(dis_buffer, "RLC (IX + 0x12)") != 0) { return 2; } parse_instruction(&mem, dis_write, false); dis_pointer = dis_buffer; if (strcmp(dis_buffer, "LD (IY + 0x10), 0x20") != 0) { return 3; } return 0; }
struct instruction *parse_instruction(void) { struct expr *expr; struct instruction *res; switch (lookahead[0]->type) { case WHILE: return parse_while(); case DO: return parse_do(); case IDENTIFIER: case LPAREN: expr = parse_expression(); switch(lookahead[0]->type) { case ASSIGN: return parse_assignment_instr(expr); case EOL: if (expr->exprtype != funcalltype) { if (expr->exprtype == binopexprtype && expr->val.binopexpr.op == EQ) { error(expr->pos, "unexpected =, did you mean <- ?"); exit(1); } else syntaxerror("expected instruction, not expression"); } eat(EOL); res = funcallinstr(expr->val.funcall.fun_ident, expr->val.funcall.args, expr->pos); free(expr); return res; default: next(); syntaxerror("unexpected %s", tok->val); return parse_instruction(); } case RETURN: eat(RETURN); if (lookahead[0]->type == EOL) { eat(EOL); return return_stmt(NULL); } else { expr = parse_expression(); eat(EOL); return return_stmt(expr); } case FOR: return parse_for(); case IF: return parse_if(); case SWITCH: return parse_switch(); case ENDOFFILE: return NULL; default: next(); syntaxerror("expected instruction, not %s", tok->val); return parse_instruction(); } }
/* * Our child has snuffed it. check if it was an editor, and update the * session list if that is the case. */ void sig_chld_bottomhalf __P0 (void) { int fd, pid, ret; editsess **sp, *p; /* GH: while() instead of just one check */ while ((pid = waitpid(-1, &ret, WNOHANG)) > 0) { /* GH: check for WIFSTOPPED unnecessary since no */ /* WUNTRACED to waitpid() */ for (sp = &edit_sess; *sp && (*sp)->pid != pid; sp = &(*sp)->next) ; if (*sp) { finish_edit(*sp); p = *sp; *sp = p->next; fd = p->fd; free(p->descr); free(p->file); free(p); /* GH: only send message if found matching session */ /* send the edit_end message if this is the last editor... */ if ((!edit_sess) && (*edit_end)) { int otcp_fd = tcp_fd; /* backup current socket fd */ tcp_fd = fd; error = 0; parse_instruction(edit_end, 0, 0, 1); history_done = 0; tcp_fd = otcp_fd; } } } }
program_ptr Parser::parse_program() { int start_line = current_lexeme().line(); instructions program_body; instructions functions; instruction_ptr instruction = instruction_ptr(); while (match_current_lexeme(kEndofLine)) next_line(); while (!finished() && ErrorHandler::is_ok()) { instruction = instruction_ptr(); instruction = parse_function_definition(); if (instruction) { functions.push_back(instruction); continue; } instruction = parse_instruction(); if (!instruction) { report_current_syntax_error(); return program_ptr(); } program_body.push_back(instruction); } return program_ptr(new Program(start_line, program_body, functions)); }
struct instruction *parse_instruction() { struct instruction *i; i = malloc(sizeof(struct instruction)); if (i == NULL) { perror("No memory"); return NULL; } i->s = parse_single(); if (i->s == NULL) { free(i); return NULL; } if (get_token().type != T_SEP) { unget_token(); i->i = NULL; return i; } i->i = parse_instruction(); if (i->i == NULL) { unget_token(); } return i; }
static int parse_file(int fd_src, t_parser *parser, int fd_dest, header_t *header) { int fd[2]; int size_header; char *temp; fd[0] = fd_src; fd[1] = fd_dest; g_list = NULL; parser->line_nb = 0; parser->current_address = 0; size_header = 0; if (parse_header(fd_src, parser, header, &size_header) == 1 || parse_instruction(fd_src, parser, &g_list) == 1 || write_header(fd_dest, header, parser) == 1) return (1); if (lseek(fd_src, 0, SEEK_SET) == -1) return (1); if ((temp = malloc(size_header)) == NULL) return (1); if (read(fd[0], temp, size_header) == -1) return (1); free(temp); if (parse_and_translate(fd) == 1) return (1); free_list(&g_list); return (0); }
int command_disassemble(struct debugger_state *state, int argc, char **argv) { if (argc > 3) { state->print(state, "%s `start` `count` - Print the disassembled commands\n" " Prints `count` disassembled commands starting in memory from `start`.\n", argv[0]); return 0; } z80cpu_t *cpu = state->asic->cpu; uint16_t start = state->asic->cpu->registers.PC; uint16_t count = 10; if (argc > 1) { start = parse_expression(state, argv[1]); } if (argc > 2) { count = parse_expression(state, argv[2]); } uint16_t i = 0; struct mmu_disassemble_memory str = { { disassemble_read, start }, cpu, state }; for (i = 0; i < count; i++) { state->print(state, "0x%04X: ", str.mem.current); parse_instruction(&(str.mem), disassemble_print); state->print(state, "\n"); } return 0; }
instructionlist_t parse_block(void) { instructionlist_t block = empty_instructionlist(); while (lookahead[0]->type != END && lookahead[0]->type != ENDOFFILE && lookahead[0]->type != ELSE && lookahead[1]->type != COMMA && lookahead[1]->type != COLON && lookahead[0]->type != OTHERWISE) list_push_back(block, parse_instruction()); return block; }
void run_part_one() { std::string line; InstructionRunner runner; std::array<int,REGISTER_COUNT> registers = {0,0}; while(std::getline(std::cin,line)) { runner.add_instruction(parse_instruction(line)); } runner.run(registers); std::cout<<registers[1]<<std::endl; }
static boolean translate( struct translate_ctx *ctx ) { eat_opt_white( &ctx->cur ); if (!parse_header( ctx )) return FALSE; if (ctx->processor == TGSI_PROCESSOR_TESS_CTRL || ctx->processor == TGSI_PROCESSOR_TESS_EVAL) ctx->implied_array_size = 32; while (*ctx->cur != '\0') { uint label_val = 0; if (!eat_white( &ctx->cur )) { report_error( ctx, "Syntax error" ); return FALSE; } if (*ctx->cur == '\0') break; if (parse_label( ctx, &label_val )) { if (!parse_instruction( ctx, TRUE )) return FALSE; } else if (str_match_nocase_whole( &ctx->cur, "DCL" )) { if (!parse_declaration( ctx )) return FALSE; } else if (str_match_nocase_whole( &ctx->cur, "IMM" )) { if (!parse_immediate( ctx )) return FALSE; } else if (str_match_nocase_whole( &ctx->cur, "PROPERTY" )) { if (!parse_property( ctx )) return FALSE; } else if (!parse_instruction( ctx, FALSE )) { return FALSE; } } return TRUE; }
int interpret_program(tvm_program_t* p, char* filename, tvm_memory_t* pMemory) { int i; FILE* pFile = NULL; int source_length = 0; char* source = NULL; tvm_lexer_t* lexer = NULL; /* Attempt to open the file. If the file cannot be opened, try once more. */ if(filename) for(i = 0; i < 2; i++) if(!pFile) pFile = tvm_fopen(filename, ".vm", "r"); if(!pFile) { printf("File was not found, or does not exist. Unable to interpret.\n"); return 1; } source_length = tvm_flength(pFile); source = malloc(source_length); tvm_fcopy(source, source_length, pFile); lexer = lexer_create(); lex(lexer, source); free(source); fclose(pFile); if(parse_labels(p, (const char***)lexer->tokens) != 0) return 1; for(i = 0; lexer->tokens[i]; i++) { p->instr = (int*)realloc(p->instr, sizeof(int) * (i + 2)); p->instr[i] = 0; p->args = (int***)realloc(p->args, sizeof(int**) * (i + 2)); p->args[i] = (int**)calloc(MAX_ARGS, sizeof(int*)); parse_instruction(p, (const char**)lexer->tokens[i], pMemory); } lexer_destroy(lexer); p->args[i] = NULL; p->instr[i] = -0x1; return 0; }
static boolean translate( struct translate_ctx *ctx ) { eat_opt_white( &ctx->cur ); if (!parse_header( ctx )) return FALSE; while (*ctx->cur != '\0') { uint label_val = 0; if (!eat_white( &ctx->cur )) { report_error( ctx, "Syntax error" ); return FALSE; } if (*ctx->cur == '\0') break; if (parse_label( ctx, &label_val )) { if (!parse_instruction( ctx, TRUE )) return FALSE; } else if (str_match_no_case( &ctx->cur, "DCL" )) { if (!parse_declaration( ctx )) return FALSE; } else if (str_match_no_case( &ctx->cur, "IMM" )) { if (!parse_immediate( ctx )) return FALSE; } else if (str_match_no_case( &ctx->cur, "PROPERTY" )) { if (!parse_property( ctx )) return FALSE; } else if (!parse_instruction( ctx, FALSE )) { return FALSE; } } return TRUE; }
struct program *parse_program() { struct program *p; if (get_token().type != T_HAI) { unget_token(); return NULL; } if (get_token().type != T_SEP) { unget_token(); parse_error("expected separator"); return NULL; } p = malloc(sizeof(struct program)); if (p == NULL) { perror("No memory"); return NULL; } p->v = parse_vars(); if (p->v != NULL) if (get_token().type != T_SEP) { parse_error("expected separator"); free(p); return NULL; } p->i = parse_instruction(); while (get_token().type == T_SEP); unget_token(); if (tokens[current_token].type != T_EOF) { parse_error("expecting instruction"); return NULL; } return p; }
/******************************************************************************* * * Invokes the assembling of a collection of MIPS assembly instructions. * ******************************************************************************* * * PARAMETERS * mips_assembly Vector holding the MIPS assembly instructions which * are to be assembled. * machine_code Empty vector to hold the 32-bit binary instructions * which will result from the assembling. * ******************************************************************************/ void assemble( vector_string_t * mips_assembly, vector_uint_t * machine_code ) { int i; global_machine_code = machine_code; JmpTable = HashTableAllocate(HASH_WORD); StringTable = StringTableAllocate(); RelocTable = HashTableAllocate(HASH_WORD); instruction_table = HashTableAllocate(HASH_STRING); register_table = HashTableAllocate(HASH_STRING); { register_entry_t* iter; for(iter = register_build_table; iter->name != NULL; iter++) HashTableInsertString(register_table, iter->name, &i)->data.ptr = iter; } { instruction_entry_t* iter; for(iter = instruction_build_table; iter->name != NULL; iter++) HashTableInsertString(instruction_table, iter->name, &i)->data.ptr = iter; } for(i = 0; i < mips_assembly->size; i++) { parse_instruction(vector_string_get(mips_assembly, i)); } for(i = 0; i < RelocTable->nnodes; i++) { uint32_t br, abs, inst; br = HashTableInsertWord(RelocTable, i, NULL)->data.uint32; inst = vector_uint_get(machine_code, br); if(inst >> 26 == 1 || inst >> 26 == 5) { abs = HashTableInsertWord(JmpTable, inst & 0x0000FFFF, NULL)->data.uint32; inst = emit_itype(inst >> 26, (inst >> 21) & 0x1F, (inst >> 16) & 0x1F, ((int16_t)abs) - ((int16_t)br + 1)); } else { abs = HashTableInsertWord(JmpTable, inst & 0x03FFFFFF, NULL)->data.uint32; inst = emit_jtype(inst >> 26, ((int32_t)abs) - ((int32_t)br + 1)); } vector_uint_set(machine_code, inst, br); }
void parse( llist *bytecode ) { token tok; do { tok = getNextToken(); switch( tok.type ) { case INSTRUCTION: parse_instruction( tok.value.name, bytecode ); break; } } while ( tok.type != END ); }
/* * execute walk if word is valid [speed]walk sequence - * return 1 if walked, 0 if not */ int map_walk(char *word, int silent, int maponly) { char buf[16]; int n = strlen(word); int is_main = (tcp_fd == tcp_main_fd); if (!is_main && !maponly && !opt_speedwalk) return 0; if (!n || (n > 1 && !opt_speedwalk && !maponly) || !strchr("neswud", word[n - 1]) || (int)strspn(word, "neswud0123456789") != n) return 0; if (maponly) silent = 1; buf[1] = '\0'; while (*word) { if (!silent) { status(1); tty_putc('['); } if (isdigit(*word)) { n = strtol(word, &word, 10); if (!silent) tty_printf("%d", n); } else n = 1; if (!silent) tty_putc(*word); while (n--) { *buf = *word; if (!maponly) { if (*lookup_alias(buf)) parse_instruction(buf, 1, 0, 0); // we want to execute aliases n,e,s,w,u,d else tcp_write(tcp_fd, buf); } if (is_main || maponly) map_add_dir(*word); } if (!silent) tty_puts("] "); word++; } if (!silent) tty_putc('\n'); return !maponly; }
instruction_ptr Parser::parse_while_block() { int start_line = current_lexeme().line(); if (!match_current_lexeme(kWhileKeyword)) return instruction_ptr(); next_lexeme(); instruction_ptr condition = parse_condition(); if(!condition) { report_current_syntax_error(); return instruction_ptr(); } if(!match_current_lexeme(kColon)) { report_current_syntax_error(); return instruction_ptr(); } next_lexeme(); next_line(); instructions block; while (!match_current_lexeme(kEndKeyword)) { instruction_ptr instruction = parse_instruction(); if (!instruction) { report_current_syntax_error(); return instruction_ptr(); } block.push_back(instruction); } next_lexeme(); return instruction_ptr(new WhileBlock(start_line, block, condition)); }
struct instruction *parse_do(void) { struct expr *cond; instructionlist_t block = empty_instructionlist(); instructionlist_t subblock; eat(DO); eat(EOL); while (true) { if (lookahead[0]->type != WHILE) list_push_back(block, parse_instruction()); else // while could close the do..while or start a while..do { eat(WHILE); if (current_lang == LANG_FR) eat(SO); cond = parse_expression(); if (lookahead[0]->type == EOL) // closing the do..while { eat(EOL); return dowhileblock(block, cond); } else // starting a while..do { eat(DO); eat(EOL); subblock = parse_block(); eat(END); eat(WHILE); if (current_lang == LANG_FR) eat(SO); eat(EOL); list_push_back(block, whileblock(cond, subblock)); } } } }
instruction_ptr Parser::parse_function_definition() { int start_line = current_lexeme().line(); if (!match_current_lexeme(kDefKeyword)) return instruction_ptr(); next_lexeme(); if (!match_current_lexeme(kId)) { report_current_syntax_error(); return instruction_ptr(); } string name = current_lexeme().value(); next_lexeme(); if (!match_current_lexeme(kLeftBracket)) { report_current_syntax_error(); return instruction_ptr(); } next_lexeme(); vector<string> parameters; if (!match_current_lexeme(kRightBracket)) { while (true) { if (!match_current_lexeme(kId)) { report_current_syntax_error(); return instruction_ptr(); } parameters.push_back(current_lexeme().value()); next_lexeme(); if (!match_current_lexeme(kComma)) break; next_lexeme(); } } if (!match_current_lexeme(kRightBracket)) { report_current_syntax_error(); return instruction_ptr(); } next_lexeme(); if (!match_current_lexeme(kColon)) { report_current_syntax_error(); return instruction_ptr(); } next_lexeme(); next_line(); instructions function_body; while (!match_current_lexeme(kEndKeyword)) { instruction_ptr instruction = parse_instruction(); if (!instruction) { report_current_syntax_error(); return instruction_ptr(); } function_body.push_back(instruction); } next_lexeme(); next_line(); return instruction_ptr(new Function(start_line, function_body, name, parameters)); }
void parse(void) { char *s,*line,*ext[MAX_QUALIFIERS?MAX_QUALIFIERS:1],*op[MAX_OPERANDS]; char *labname,*start; int inst_len,ext_len[MAX_QUALIFIERS?MAX_QUALIFIERS:1],op_len[MAX_OPERANDS]; int ext_cnt,op_cnt; instruction *ip; while (line=read_next_line()){ if (clev >= MAXCONDLEV) syntax_error(16,clev); /* nesting depth exceeded */ if (!cond[clev]) { /* skip source until ELSE or ENDIF */ int idx; s = line; idx = check_directive(&s); if (idx >= 0) { if (!strncmp(directives[idx].name,"if",2)) { ifnesting++; } else if (ifnesting==0 && !strncmp(directives[idx].name,"else",4)) { cond[clev] = 1; } else if (directives[idx].func == handle_endif) { if (ifnesting == 0) { if (clev > 0) clev--; else syntax_error(14); /* endif without if */ } else ifnesting--; } } continue; } s=skip(line); if(handle_directive(s)) continue; /* skip spaces */ s=skip(s); if(!*s||*s==commentchar) continue; /* check for label */ start=s; if(labname=get_local_label(&s)){ /* local label? */ if(*s!=':'){ s=start; myfree(labname); labname=NULL; } } else if(ISIDSTART(*s)){ /* or global label? */ s++; while(ISIDCHAR(*s)) s++; if(*s!=':') s=start; else labname=cnvstr(start,s-start); } if(labname){ /* we have found a valid global or local label */ add_atom(0,new_label_atom(new_labsym(0,labname))); s=skip(s+1); myfree(labname); } if(!*s||*s==commentchar) continue; s=skip(parse_cpu_special(s)); if(*s==0||*s==commentchar) continue; if(handle_directive(s)) continue; /* read mnemonic name */ start=s; ext_cnt=0; if(!ISIDSTART(*s)){ syntax_error(10); continue; } #if MAX_QUALIFIERS==0 while(*s&&!isspace((unsigned char)*s)) s++; inst_len=s-start; #else s=parse_instruction(s,&inst_len,ext,ext_len,&ext_cnt); #endif s=skip(s); if(execute_macro(start,inst_len,ext,ext_len,ext_cnt,s,clev)) continue; /* read operands, terminated by comma (unless in parentheses) */ op_cnt=0; while(*s&&*s!=commentchar&&op_cnt<MAX_OPERANDS){ op[op_cnt]=s; s=skip_operand(s); op_len[op_cnt]=oplen(s,op[op_cnt]); #if !ALLOW_EMPTY_OPS if(op_len[op_cnt]<=0) syntax_error(5); else #endif op_cnt++; s=skip(s); if(*s!=','){ break; }else{ s=skip(s+1); } } s=skip(s); if(*s!=0&&*s!=commentchar) syntax_error(6); ip=new_inst(start,inst_len,op_cnt,op,op_len); #if MAX_QUALIFIERS>0 if(ip){ int i; for(i=0;i<ext_cnt;i++) ip->qualifiers[i]=cnvstr(ext[i],ext_len[i]); for(;i<MAX_QUALIFIERS;i++) ip->qualifiers[i]=0; } #endif if(ip){ add_atom(0,new_inst_atom(ip)); }else ; } if (clev > 0) syntax_error(15); /* if without endif */ }
/* * assembles an instruction and write the binary code to the segment */ BOOL write_instruction(Assembly* assembly, char* params[], int count, Segment* segment) { int type, size, opcode, i; /* instruction parts */ Value value; /* instruction parameter */ unsigned char* instruction; /* binary instruction */ int paramtype; /* parameter type */ if (parse_instruction(params[0], &opcode, &size, &type)) { switch(opcode) { case ADDRF: case ADDRL: case ADDRA: /* integer (sizeof pointer) parameter in file */ if (count != 2) error(linenr, "invalid number of parameters (need 1)"); paramtype = PARAM_INT; value = parse_value(params[1], INTEGER, PTR_SIZE); break; case CVF: error(linenr, "floating point conversion not supported"); case CVI: case CVP: case CVU: /* integer parameter in file */ if (count != 2) error(linenr, "invalid number of parameters (need 1)"); paramtype = PARAM_NONE; value = parse_value(params[1], INTEGER, 1); /* printf("INSTRUCTION: %s %s:, SIZE: %d, PARAMETER: %d\n", params[0], params[1], size, value.u); */ /* build last opcode byte, use value.u as temp variable */ if (value.u == 1) { value.u = TYPE_CHAR + (opcode == CVI?1:0); } else if (value.u == INT_SIZE) { value.u = TYPE_INT + (opcode == CVI?1:0); } else if (value.u == SHRT_SIZE) { value.u = TYPE_SHORT + (opcode == CVI?1:0); } else if (value.u == LNG_SIZE) { value.u = TYPE_LONG + (opcode == CVI?1:0); } else if (value.u == PTR_SIZE) { value.u = TYPE_POINTER + (opcode == CVI?1:0); } else { error(linenr, "invalid conversion"); } if (size == 1) { value.u |= ((TYPE_CHAR + (type == INTEGER?1:0))<<4); } else if (size == INT_SIZE) { value.u |= ((TYPE_INT + (type == INTEGER?1:0))<<4); } else if (size == SHRT_SIZE) { value.u |= ((TYPE_SHORT + (type == INTEGER?1:0))<<4); } else if (size == LNG_SIZE) { value.u |= ((TYPE_LONG + (type == INTEGER?1:0))<<4); } else if (size == PTR_SIZE) { value.u |= ((TYPE_POINTER + (type == INTEGER?1:0))<<4); } else { error(linenr, "invalid conversion"); } /* printf("OPCODE: 0x%04X, VALUE: 0x%04X, COMBINED: ", opcode, value); */ opcode = (opcode & 0xFF00) | (value.u & 0xFF); /* printf("0x%04X\n", opcode); */ break; case MOVESTACK: /* pseudo instruction for VARSTACK */ //opcode = VARSTACK; if (count != 2) error(linenr, "invalid number of parameters (need 1)"); value.i = get_label(assembly, params[1])->id; paramtype = PARAM_POINTER; break; case ARGSTACK: case VARSTACK: case ARG: /* integer parameter in file */ if (count != 2) error(linenr, "invalid number of parameters (need 1)"); paramtype = PARAM_INT; value = parse_value(params[1], INTEGER, INT_SIZE); break; case ADDRG: case EQ: case GE: case GT: case LE: case LT: case NE: /* pointer parameter in file */ if (count != 2) error(linenr, "invalid number of parameters (need 1)"); value.i = get_label(assembly, params[1])->id; paramtype = PARAM_POINTER; break; case CNST: /* constant parameter in file */ if (count != 2) error(linenr, "invalid number of parameters (need 1)"); paramtype = PARAM_CONST; value = parse_value(params[1], type, size); break; case SAVELP: case SAVEFP: case SAVEAP: case SAVESP: case SAVEVR: case SAVEEL: /* pseudo instructions! */ if (count != 1) error(linenr, "invalid number of parameters (need 0)"); opcode = (opcode & 0x00FF) | 0x0100; paramtype = PARAM_INT; value.i = 0; break; case BCOM: case CALL: case RET: case JUMP: case HALT: case SYSCALL: case NEG: case ADD: case BAND: case BOR: case BXOR: case DIV: case LSH: case MOD: case MUL: case RSH: case SUB: /* case LOADLP: case LOADFP: case LOADAP: case LOADSP: case LOADVR: case LOADEL: */ case DISCARD: case ASGN: case INDIR: /* case SAVESTATE: case NEWSTACK: */ /* no parameter */ if (count != 1) error(linenr, "invalid number of parameters (need 0)"); paramtype = PARAM_NONE; value.u = 0; break; /* case ASGN: case INDIR: /* depends on type */ /* paramtype = PARAM_INT; if (type == STRUCT) { if (count != 2) error(linenr, "invalid number of parameters (need 1)"); size = PTR_SIZE; value.u = parse_numeric(params[1]); } else { if (count != 1) error(linenr, "invalid number of parameters (need 0)"); value.u = 0; } break; */ /* case MARK: /* special instruction (debug) *//* if (count != 1) error(linenr, "invalid number of parameters (need 0)"); paramtype = PARAM_INT; value.u = 0xF0F0F0F0; break; */ } } else { printf("Instruction '%s' not recognized\n", params[0], opcode); error(linenr, "invalid instruction"); } /* force JUMP & CALL type to P4 */ if (opcode == JUMP || opcode == CALL) { size = PTR_SIZE; type = POINTER; } /* make sure it's big enough */ instruction = malloc(OPCSIZE + PTR_SIZE + size + INT_SIZE); /* create & write opcode */ if ((opcode & 0xFF00) == CV) { instruction[0] = opcode >> 8; instruction[1] = opcode & 0xFF; } else {
/* * start an editing session: process the EDIT/VIEW message * if view == 1, text will be viewed, else edited */ void message_edit __P4 (char *,text, int,msglen, char,view, char,builtin) { char tmpname[BUFSIZE], command_str[BUFSIZE], buf[BUFSIZE]; char *errdesc = "#warning: protocol error (message_edit, no %s)\n"; int tmpfd, i, childpid; unsigned int key; editsess *s; char *editor, *descr; char *args[4]; int waitforeditor; status(1); args[0] = "/bin/sh"; args[1] = "-c"; args[2] = command_str; args[3] = 0; if (view) { key = (unsigned int)-1; i = 0; } else { if (text[0] != 'M') { tty_printf(errdesc, "M"); free(text); return; } for (i = 1; i < msglen && isdigit(text[i]); i++) ; if (text[i++] != '\n' || i >= msglen) { tty_printf(errdesc, "\\n"); free(text); return; } key = strtoul(text + 1, NULL, 10); } descr = text + i; while (i < msglen && text[i] != '\n') i++; if (i >= msglen) { tty_printf(errdesc, "desc"); free(text); return; } text[i++] = '\0'; sprintf(tmpname, "/tmp/powwow.%u.%d%d", key, getpid(), abs(rand()) >> 8); if ((tmpfd = open(tmpname, O_WRONLY | O_CREAT, 0600)) < 0) { errmsg("create temp edit file"); free(text); return; } if (write(tmpfd, text + i, msglen - i) < msglen - i) { errmsg("write to temp edit file"); free(text); close(tmpfd); return; } close(tmpfd); s = (editsess*)malloc(sizeof(editsess)); if (!s) { errmsg("malloc"); return; } s->ctime = time((time_t*)NULL); s->oldsize = msglen - i; s->key = key; s->fd = (view || builtin) ? -1 : tcp_fd; /* MUME doesn't expect a reply. */ s->cancel = 0; s->descr = my_strdup(descr); s->file = my_strdup(tmpname); free(text); /* send a edit_start message (if wanted) */ if ((!edit_sess) && (*edit_start)) { error = 0; parse_instruction(edit_start, 0, 0, 1); history_done = 0; } if (view) { if (!(editor = getenv("POWWOWPAGER")) && !(editor = getenv("PAGER"))) editor = "more"; } else { if (!(editor = getenv("POWWOWEDITOR")) && !(editor = getenv("EDITOR"))) editor = "emacs"; } if (editor[0] == '&') { waitforeditor = 0; editor++; } else waitforeditor = 1; if (waitforeditor) { tty_quit(); /* ignore SIGINT since interrupting the child would interrupt us too, if we are in the same tty group */ sig_permanent(SIGINT, SIG_IGN); sig_permanent(SIGCHLD, SIG_DFL); } switch(childpid = fork()) { /* let's get schizophrenic */ case 0: sprintf(command_str, "%s %s", editor, s->file); sprintf(buf, "TITLE=%s", s->descr); putenv(buf); /* setenv("TITLE", s->descr, 1);*/ execvp((char *)args[0], (char **)args); syserr("execve"); break; case -1: errmsg("fork"); free(s->descr); free(s->file); free(s); return; } s->pid = childpid; if (waitforeditor) { while ((i = waitpid(childpid, (int*)NULL, 0)) == -1 && errno == EINTR) ; signal_start(); /* reset SIGINT and SIGCHLD handlers */ tty_start(); if (s->fd != -1) { tty_gotoxy(0, lines - 1); tty_putc('\n'); } if (i == -1) errmsg("waitpid"); else finish_edit(s); free(s->descr); free(s->file); if (i != -1 && !edit_sess && *edit_end) { error = 0; parse_instruction(edit_end, 0, 0, 1); history_done = 0; } free(s); } else { s->next = edit_sess; edit_sess = s; } }
/* * open another connection */ void tcp_open __P4 (char *,id, char *,initstring, char *,host, int,port) { int newtcp_fd, i; if (tcp_count+tcp_attachcount >= MAX_CONNECTS) { PRINTF("#too many open connections.\n"); return; } if (tcp_find(id)>=0) { PRINTF("#connection \"%s\" already open.\n", id); return; } /* find a free slot */ for (i=0; i<MAX_CONNECTS; i++) { if (!CONN_INDEX(i).id) break; } if (i == MAX_CONNECTS) { PRINTF("#internal error, connection table full :(\n"); return; } if (!(CONN_INDEX(i).host = my_strdup(host))) { errmsg("malloc"); return; } if (!(CONN_INDEX(i).id = my_strdup(id))) { errmsg("malloc"); free(CONN_INDEX(i).host); return; } /* dial the number by moving the right index in small circles */ if ((newtcp_fd = tcp_connect(host, port)) < 0) { free(CONN_INDEX(i).host); free(CONN_INDEX(i).id); CONN_INDEX(i).id = 0; return; } conn_table[newtcp_fd] = i; CONN_INDEX(i).flags = ACTIVE; CONN_INDEX(i).state = NORMAL; CONN_INDEX(i).port = port; CONN_INDEX(i).fd = newtcp_fd; if (tcp_max_fd < newtcp_fd) tcp_max_fd = newtcp_fd; if (conn_max_index <= i) conn_max_index = i+1; FD_SET(newtcp_fd, &fdset); /* add socket to select() set */ tcp_count++; if (opt_info && tcp_count) { PRINTF("#default connection is now \"%s\"\n", id); } tcp_set_main(tcp_fd = newtcp_fd); if (opt_sendsize) tcp_write_tty_size(); if (initstring) { parse_instruction(initstring, 0, 0, 1); history_done = 0; } }
void parse(void) { char *s,*line,*inst; char *ext[MAX_QUALIFIERS?MAX_QUALIFIERS:1]; char *op[MAX_OPERANDS]; int ext_len[MAX_QUALIFIERS?MAX_QUALIFIERS:1]; int op_len[MAX_OPERANDS]; int ext_cnt,op_cnt,inst_len; instruction *ip; while (line = read_next_line()) { if (!cond_state()) { /* skip source until ELSE or ENDIF */ int idx = -1; s = skip(line); if (labname = parse_labeldef(&s,1)) { if (*s == ':') s++; /* skip double-colon */ myfree(labname); s = skip(s); } else { if (inst = skip_identifier(s)) { inst = skip(inst); idx = check_directive(&inst); } } if (idx < 0) idx = check_directive(&s); if (idx >= 0) { if (directives[idx].func == handle_if) cond_skipif(); else if (directives[idx].func == handle_else) cond_else(); else if (directives[idx].func == handle_endif) cond_endif(); } continue; } s = skip(line); again: if (*s=='\0' || *line=='*' || *s==commentchar) continue; if (labname = parse_labeldef(&s,1)) { /* we have found a valid global or local label */ symbol *sym = new_labsym(0,labname); if (*s == ':') { /* double colon automatically declares label as exported */ sym->flags |= EXPORT; s++; } add_atom(0,new_label_atom(sym)); myfree(labname); s = skip(s); } else { /* there can still be a sym. in the 1st fld and an assignm. directive */ inst = s; labname = parse_symbol(&s); if (labname == NULL) { syntax_error(10); /* identifier expected */ continue; } s = skip(s); /* Now we have labname pointing to the first field in the line and s pointing to the second. Find out where the directive is. */ if (!ISEOL(s)) { #ifdef PARSE_CPU_LABEL if (PARSE_CPU_LABEL(labname,&s)) { myfree(labname); continue; } #endif if (handle_directive(s)) { myfree(labname); continue; } } /* directive or mnemonic must be in the first field */ myfree(labname); s = inst; } if (!strnicmp(s,".iif",4) || !(strnicmp(s,"iif",3))) { /* immediate conditional assembly: parse line after ',' when true */ s = skip(*s=='.'?s+4:s+3); if (do_cond(&s)) { s = skip(s); if (*s == ',') { s = skip(s+1); goto again; } else syntax_error(0); /* malformed immediate-if */ } continue; } /* check for directives */ s = parse_cpu_special(s); if (ISEOL(s)) continue; if (handle_directive(s)) continue; /* read mnemonic name */ inst = s; ext_cnt = 0; if (!ISIDSTART(*s)) { syntax_error(10); /* identifier expected */ continue; } #if MAX_QUALIFIERS==0 while (*s && !isspace((unsigned char)*s)) s++; inst_len = s - inst; #else s = parse_instruction(s,&inst_len,ext,ext_len,&ext_cnt); #endif if (!isspace((unsigned char)*s) && *s!='\0') syntax_error(2); /* no space before operands */ s = skip(s); if (execute_macro(inst,inst_len,ext,ext_len,ext_cnt,s)) continue; /* read operands, terminated by comma or blank (unless in parentheses) */ op_cnt = 0; while (!ISEOL(s) && op_cnt<MAX_OPERANDS) { op[op_cnt] = s; s = skip_operand(s); op_len[op_cnt] = oplen(s,op[op_cnt]); #if !ALLOW_EMPTY_OPS if (op_len[op_cnt] <= 0) syntax_error(5); /* missing operand */ else #endif op_cnt++; s = skip(s); if (*s != ',') break; else s = skip(s+1); } eol(s); ip = new_inst(inst,inst_len,op_cnt,op,op_len); #if MAX_QUALIFIERS>0 if (ip) { int i; for (i=0; i<ext_cnt; i++) ip->qualifiers[i] = cnvstr(ext[i],ext_len[i]); for(; i<MAX_QUALIFIERS; i++) ip->qualifiers[i] = NULL; } #endif if (ip) add_atom(0,new_inst_atom(ip)); } cond_check(); /* check for open conditional blocks */ }
int command_run(debugger_state_t *state, int argc, char **argv) { state->asic->stopped = 0; uint16_t instructions = -1; struct run_disassemble_state dstate; dstate.memory.read_byte = run_command_read_byte; dstate.memory.current = state->asic->cpu->registers.PC; dstate.state = state; int oldHalted = 0; int isFirstInstruction = 1; if ((argc == 2 && strcmp(argv[1], "--help") == 0) || argc > 2) { state->print(state, "run [instructions] - run a specified number of instructions\n" " If no number is specified, the emulator will run until interrupted (^C).\n"); return 0; } else if(argc == 2) { instructions = parse_expression_z80e(state, argv[1]); state->debugger->state = DEBUGGER_LONG_OPERATION; for (; instructions > 0; instructions--) { hook_on_before_execution(state->asic->hook, state->asic->cpu->registers.PC); if (!isFirstInstruction && state->asic->stopped) { state->asic->stopped = 0; break; } if (isFirstInstruction) { state->asic->stopped = 0; isFirstInstruction = 0; } if (state->debugger->flags.echo) { if (!state->asic->cpu->halted) { state->print(state, "0x%04X: ", state->asic->cpu->registers.PC); dstate.memory.current = state->asic->cpu->registers.PC; parse_instruction(&(dstate.memory), run_command_write, state->debugger->flags.knightos); state->print(state, "\n"); } } else { if (state->asic->cpu->halted && !oldHalted) { state->print(state, "CPU is halted\n"); } } if (state->debugger->flags.echo_reg) { print_state(&state->asic->cpu->registers); } oldHalted = state->asic->cpu->halted; int iff1 = state->asic->cpu->IFF1; int iff2 = state->asic->cpu->IFF2; if (state->debugger->flags.nointonstep) { state->asic->cpu->IFF1 = 0; state->asic->cpu->IFF2 = 0; } runloop_tick_cycles(state->asic->runloop, 1); if (state->debugger->flags.nointonstep) { state->asic->cpu->IFF1 = iff1; state->asic->cpu->IFF2 = iff2; } hook_on_after_execution(state->asic->hook, state->asic->cpu->registers.PC); if (state->asic->stopped) { state->asic->stopped = 0; break; } } state->debugger->state = DEBUGGER_ENABLED; return 0; } state->debugger->state = DEBUGGER_LONG_OPERATION_INTERRUPTABLE; while (1) { hook_on_before_execution(state->asic->hook, state->asic->cpu->registers.PC); if (!isFirstInstruction && state->asic->stopped) { state->asic->stopped = 0; break; } if (isFirstInstruction) { state->asic->stopped = 0; isFirstInstruction = 0; } if (state->debugger->flags.echo) { if (!state->asic->cpu->halted) { state->print(state, "0x%04X: ", state->asic->cpu->registers.PC); dstate.memory.current = state->asic->cpu->registers.PC; parse_instruction(&(dstate.memory), run_command_write, state->debugger->flags.knightos); state->print(state, "\n"); } } else { if (state->asic->cpu->halted && !oldHalted) { if (state->debugger->flags.auto_on) { if (!((ti_bw_lcd_t *)state->asic->cpu->devices[0x10].device)->display_on) { state->asic->cpu->halted = 0; state->print(state, "Turned on calculator via auto_on\n"); } } else { state->print(state, "CPU is halted\n"); } } } if (state->debugger->flags.echo_reg) { print_state(&state->asic->cpu->registers); } oldHalted = state->asic->cpu->halted; runloop_tick_cycles(state->asic->runloop, 1); hook_on_before_execution(state->asic->hook, state->asic->cpu->registers.PC); if (state->asic->stopped) { state->debugger->state = DEBUGGER_ENABLED; return 0; } } state->debugger->state = DEBUGGER_ENABLED; return 0; }
struct single *parse_if() { int current = current_token; token t1, t2, t3, t4, t5; struct single *s; s = malloc(sizeof(struct single)); if (s == NULL) { perror("No memory"); return NULL; } t1 = get_token(); t2 = get_token(); if (t1.type != T_O || t2.type != T_RLY) { free(s); current_token = current; return NULL; } s->type = I_IF; s->data.ifelse.c = parse_cond(); if (s->data.ifelse.c == NULL) { free(s); parse_error("expected condition"); return NULL; } t1 = get_token(); t2 = get_token(); t3 = get_token(); t4 = get_token(); t5 = get_token(); if (t1.type != T_QMARK || t2.type != T_SEP || t3.type != T_YA || t4.type != T_RLY || t5.type != T_SEP) { free(s); parse_error("wrong YA RLY syntax"); return NULL; } s->data.ifelse.t = parse_instruction(); if (s->data.ifelse.t == NULL) { free(s); parse_error("expected instruction"); return NULL; } t1 = get_token(); t2 = get_token(); if (t1.type == T_SEP && t2.type == T_OIC) { s->data.ifelse.e = NULL; return s; } t3 = get_token(); t4 = get_token(); if (t1.type != T_SEP || t2.type != T_NO || t3.type != T_WAI || t4.type != T_SEP) { free(s); parse_error("wrong NO WAI syntax"); return NULL; } s->data.ifelse.e = parse_instruction(); if (s->data.ifelse.e == NULL) { free(s); parse_error("expected instruction"); return NULL; } t1 = get_token(); t2 = get_token(); if (t1.type != T_SEP || t2.type != T_OIC) { free(s); parse_error("expected OIC"); return NULL; } return s; }
struct single *parse_loop() { int current = current_token; token t1, t2, t3, t4; struct single *s; s = malloc(sizeof(struct single)); if (s == NULL) { perror("No memory"); return NULL; } t1 = get_token(); t2 = get_token(); t3 = get_token(); t4 = get_token(); if (t1.type != T_IM || t2.type != T_IN || t3.type != T_YR || t4.type != T_LOOP) { free(s); current_token = current; return NULL; } s->type = I_LOOP; t1 = get_token(); if (t1.type != T_SEP) { free(s); parse_error("expected separator"); return NULL; } s->data.i = parse_instruction(); if (s->data.i == NULL) { free(s); parse_error("expected instruction"); return NULL; } t1 = get_token(); if (t1.type != T_SEP) { free(s); parse_error("expected separator"); return NULL; } t1 = get_token(); t2 = get_token(); t3 = get_token(); t4 = get_token(); if (t1.type != T_IM || t2.type != T_OUTTA || t3.type != T_YR || t4.type != T_LOOP) { free(s); parse_error("expected `IM OUTTA YR LOOP`"); return NULL; } return s; }