📄 picasm.c
字号:
add_local_symtab(); break; case KW_ENDLOCAL: if(local_level == 0) { error(1, "ENDLOCAL without LOCAL"); continue; } apply_patches(*local_patch_list_ptr); remove_local_symtab(); break; case KW_IF: if(sym != NULL) error(0, "Label not allowed with IF"); val = get_expression(); if(token_type != TOK_NEWLINE && token_type != TOK_EOF) error(0, "Extraneous characters after a valid source line"); if(val == 0) { write_listing_line(0); t=if_else_skip(); if(t == -1) fatal_error("Conditional not terminated"); else if(t == 1) error(0, "Label not allowed with %s", (token_type == KW_ELSE ? "ELSE" : "ENDIF")); if(token_type == KW_ELSE) cond_nest_count++; get_token(); goto line_end2; } else cond_nest_count++; break; case KW_ELSE: if(sym != NULL) error(0, "Label not allowed with %s", "ELSE"); if(current_file == NULL || cond_nest_count <= current_file->cond_nest_count) error(0, "ELSE without IF"); write_listing_line(0); t = if_else_skip(); if(t == -1) fatal_error("Conditional not terminated"); else if(t == 1) error(0, "Label not allowed with %s", (token_type == KW_ELSE ? "ELSE" : "ENDIF")); if(token_type == KW_ELSE) error(0, "Multiple ELSE statements with one IF"); cond_nest_count--; get_token(); goto line_end2; case KW_ENDIF: if(sym != NULL) error(0, "Label not allowed with %s", "ENDIF"); if(current_file == NULL || cond_nest_count <= current_file->cond_nest_count) error(0, "ENDIF without IF"); cond_nest_count--; break; case KW_ORG: if(pic_type == NULL) fatal_error("PIC device type not set"); org_val = -1; if((t = org_mode()) != O_NONE) { get_token(); O_Mode = (org_mode_t)t; switch(O_Mode) { case O_PROGRAM: case O_NONE: /* shut up GCC warning, cannot really happen here */ org_val = prog_location; break; case O_REGFILE: org_val = reg_location; break; case O_EDATA: org_val = edata_location; break; } if(org_val < 0) { error(0, "ORG value not set"); O_Mode = O_NONE; } break; } val = get_expression(); if(expr_error) continue; if(val < 0 || val >= prog_mem_size) { error(1, "ORG value out of range"); continue; } org_val = val; O_Mode = O_NONE; if(token_type == TOK_COMMA) { get_token(); if((t = org_mode()) == O_NONE) { error(0, "Invalid ORG mode"); } else { O_Mode = (org_mode_t)t; switch(O_Mode) { case O_PROGRAM: case O_NONE: /* shut up GCC warning, cannot really happen here */ prog_location = org_val; break; case O_REGFILE: reg_location = org_val; break; case O_EDATA: edata_location = org_val; break; } } get_token(); } list_loc = org_val; list_flags = LIST_LOC; break; case KW_DS: val = get_expression(); if(expr_error) continue; if(O_Mode == O_NONE) { O_Mode = O_REGFILE; if(org_val < 0) { error(0, "ORG value not set"); reg_location = 0; } else reg_location = org_val; } if(O_Mode != O_REGFILE) error(0, "ORG mode conflict"); else { if(reg_location >= reg_file_limit) fatal_error("Register file address out of range"); list_loc = reg_location; list_flags = LIST_LOC; reg_location += val; } break; case KW_EDATA: if(pic_type == NULL) fatal_error("PIC device type not set"); if(pic_type->eeprom_size == 0) { error(1, "PIC%s does not have data EEPROM", pic_type->name); continue; } for(;;) { if(token_type == TOK_STRCONST) { for(cp = token_string; *cp != '\0'; cp++) gen_edata((int)((unsigned char)(*cp))); get_token(); } else { val = get_expression(); if(expr_error) break; if(val < 0 || val > 0xff) { error(0, "Data EEPROM byte out of range"); } else gen_edata(val); } if(token_type != TOK_COMMA) break; get_token(); } break; case KW_CONFIG: if(pic_type == NULL) fatal_error("PIC device type not set"); if(config_fuses != INVALID_CONFIG) { error(1, "Multiple CONFIG definitions"); continue; } parse_config(); list_flags = LIST_PTR; list_ptr = &config_fuses; list_len = 1; break; /* Device type */ case KW_DEVICE: if(token_type != TOK_IDENTIFIER && token_type != TOK_STRCONST) { error(1, "DEVICE requires a device type"); continue; } cp = token_string; if(strncasecmp(token_string, "PIC", 3) == 0) cp += 3; for(pic = pic_types; pic->name != NULL; pic++) { if(strcasecmp(pic->name, cp) == 0) break; } if(pic->name == NULL) fatal_error("Invalid PIC device type"); get_token(); if(pic_type == pic) break; if(pic_type != NULL) { error(1, "Duplicate DEVICE setting"); continue; } pic_type = pic; prog_mem_size = pic_type->progmem_size; reg_file_limit = pic_type->regfile_limit; sprintf(symname, "__%s", pic_type->name); sym = add_symbol(symname, SYMTAB_GLOBAL); sym->type = SYM_DEFINED; sym->v.value = 1; break; /* PIC ID */ case KW_PICID: if(pic_type == NULL) fatal_error("PIC device type not set"); if(pic_id[0] != INVALID_ID) { error(1, "Multiple ID definitions"); continue; } /* * should check if ID is really allowed for all PIC types. * Microchip 1994 databook specfically says that ID is not * implemented on PIC16C6x/74... but 1995/96 databook * has different information about that... */ for(t = 0;;) { val = get_expression(); if(expr_error) continue; if(val < 0 || val > 0x3fff) error(0, "PIC ID value out of range"); else { if(t >= 4) { error(1, "PIC ID too long (max 4 bytes)"); continue; } pic_id[t] = (pic_instr_t)val; } t++; if(token_type != TOK_COMMA) break; get_token(); } if(t > 0) { list_flags = LIST_PTR; list_len = t; list_ptr = pic_id; while(t < 4) pic_id[t++] = 0x3fff; } break; /* mnemonics */ default: switch(pic_type->instr_set) { case PIC12BIT: t = assemble_12bit_mnemonic(op); break; case PIC14BIT: default: t = assemble_14bit_mnemonic(op); break; } if(t != OK) continue; break; }line_end: write_listing_line(0);line_end2: if(token_type == TOK_EOF) continue; if(token_type != TOK_NEWLINE) { error(0, "Extraneous characters after a valid source line"); skip_eol(); } get_token(); } /* while(token_type != TOK_EOF) */ /* * Close all open source files * (only really necessary if END has been used) */ while(current_file != NULL) end_include(); if(local_level > 0) error(0, "LOCAL not terminated with ENDLOCAL"); apply_patches(global_patch_list);}/* * main program */intmain(int argc, char *argv[]){ static char in_filename[256], out_filename[256], list_filename[256]; static int out_format = IHX8M; static int listing = 0, symdump = 0; char *p; time_t ti; struct tm *tm; pic_type = NULL; out_filename[0] = '\0'; list_filename[0] = '\0'; warnlevel = 0; while(argc > 1 && argv[1][0] == '-') { switch(argv[1][1]) { case 'o': /* output file name */ if(argv[1][2] != '\0') strcpy(out_filename, &argv[1][2]); else { if(argc < 3) { fputs("-o option requires a file name\n", stderr); exit(EXIT_FAILURE); } strcpy(out_filename, argv[2]); argc--; argv++; } break; case 'i': case 'I': /* output hex format (ihx8m/ihx16) */ if(strcasecmp(&argv[1][1], "ihx8m") == 0) out_format = IHX8M; else if(strcasecmp(&argv[1][1], "ihx16") == 0) out_format = IHX16; else goto usage; break; case 'p': case 'P': /* PIC type */ if(!((argv[1][2] == 'i' || argv[1][2] == 'I') && (argv[1][3] == 'c' || argv[1][3] == 'C'))) goto usage; for(pic_type = pic_types; pic_type->name != NULL; pic_type++) { if(strcasecmp(pic_type->name, &argv[1][4]) == 0) break; } if(pic_type->name == NULL) { fprintf(stderr, "Invalid device type '%s'\n", &argv[1][1]); exit(EXIT_FAILURE); } prog_mem_size = pic_type->progmem_size; reg_file_limit = pic_type->regfile_limit; break; case 'l': /* listing/list filename */ listing = 1; if(argv[1][2] != '\0') strcpy(list_filename, &argv[1][2]); break; case 's': symdump = 1; break; case 'w': /* warning mode (gives some more warnings) */ if(argv[1][2] != '\0') { warnlevel = atoi(&argv[1][2]); } else { warnlevel = 1; } break; case 'v': /* version info */ fprintf(stderr, "12/14-bit PIC assembler " VERSION " -- Copyright 1995-1998 by Timo Rossi\n"); break; case '-': /* end of option list */ case '\0': argc--; argv++; goto opt_done; default: goto usage; } argc--; argv++; }opt_done: if(argc != 2) {usage: fputs("Usage: picasm [-o<objname>] [-l<listfile>] [-s] [-ihx8m/ihx16]\n" " [-pic<device>] [-w[n]] <filename>\n", stderr); exit(EXIT_FAILURE); } strncpy(in_filename, argv[1], sizeof(in_filename)-1); if(strchr(in_filename, '.') == NULL) strcat(in_filename, ".asm"); if(out_filename[0] == '\0') { strcpy(out_filename, in_filename); if((p = strrchr(out_filename, '.')) != NULL) *p = '\0'; } if(strchr(out_filename, '.') == NULL) strcat(out_filename, ".hex"); init_assembler(); list_fp = NULL; if(listing) { if(list_filename[0] == '\0') { strcpy(list_filename, in_filename); if((p = strrchr(list_filename, '.')) != NULL) *p = '\0'; strcat(list_filename, ".lst"); } if((list_fp = fopen(list_filename, "w")) == NULL) fatal_error("Can't create listing file '%s'", list_filename); ti = time(NULL); tm = localtime(&ti); fprintf(list_fp, "** 12/14-bit PIC assembler " VERSION "\n"); fprintf(list_fp, "** %s assembled %s\n", in_filename, asctime(tm)); } assembler(in_filename); if(errors == 0) { if(code_generated) write_output(out_filename, out_format); else fputs("No code generated\n", stderr); } else fprintf(stderr, "%d error%s found\n", errors, errors == 1 ? "" : "s"); if(warnings != 0) fprintf(stderr, "%d warning%s\n", warnings, warnings == 1 ? "" : "s"); if(list_fp) { if(symdump) dump_symtab(list_fp); fclose(list_fp); } return EXIT_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -