📄 io.c
字号:
#include <stdlib.h>#include <stdio.h>#include <string.h>#include <ctype.h>#include <stdarg.h>#include "io.h"#include "op.h" extern int Active; /* SKIP LISTS are used to implement the symbol table */ char *CopyS(char *S) { char *NewS; if (S == 0) return 0; NewS = Allocate(strlen(S) + 1); strcpy(NewS, S); return NewS;} int CompS(char *A, char *B) { if (A == 0) return (B == 0)? 0: +1; if (B == 0) return -1; for (; *A != '\0'; A++, B++) { int Diff = tolower(*A) - tolower(*B); if (Diff < 0) return -1; if (Diff > 0) return +1; } return (*B == '\0')? 0: -1;} static int Random(void) { static byte B = 0, X = 0; register int L = 0, D; while (1) { if (X == 0) X = 4, B = rand()&0xff; D = B&3, B >>= 2, X--; if (D) return L; L++; }} #define MAX_BREADTH 16Symbol NIL;static Symbol Path[MAX_BREADTH];static int Breadth; static Symbol Form(int B, char *Name) { Symbol N = (Symbol)malloc(sizeof *N + B*sizeof(Symbol)); if (N == 0) fprintf(stderr, "Out of memory.\n"), exit(1); N->Name = CopyS(Name), N->Defined = N->Global = N->Variable = N->Address = N->Map = 0; return N;} #include <sys/types.h>#include <sys/timeb.h> void SymInit(void) { struct timeb T; int K; ftime(&T); srand((unsigned int)(T.time ^ T.millitm)&0xffff); NIL = Form(MAX_BREADTH - 1, 0); for (K = 0; K < MAX_BREADTH; K++) NIL->Next[K] = NIL; Breadth = 0;} int Next, Value;int Line, StartLine; Symbol LookUp(char *Name) { int K, B; Symbol P, Q; if (!Active) return 0; for (K = Breadth, P = NIL; K >= 0; K--) { Q = P->Next[K]; while (CompS(Q->Name, Name) < 0) P = Q, Q = Q->Next[K]; Path[K] = P; } if (CompS(Q->Name, Name) == 0) return Q; K = Random(); if (K > Breadth) K = ++Breadth, Path[K] = NIL; Q = Form(K, Name); for (; K >= 0; K--) Q->Next[K] = Path[K]->Next[K], Path[K]->Next[K] = Q; return Q;}#define LINE_MAX 200char Text[LINE_MAX]; static char *U; #define INCLUDE_MAX 5struct { word Path; long Loc; int Next, Line;} IS[INCLUDE_MAX], *ISP;static FILE *InF; FILE *OutF;char **FileTab; long Files;int StartF, CurF;static int FileMax; void FileInit(void) { ISP = IS - 1, FileTab = 0, Files = 0, FileMax = 0;} static byte ERRORS = 0;char InSeg = 0;void ERROR(const char *Format, ...) { va_list AP; if (InSeg) printf("%s: [%d] ", FileTab[StartF], StartLine); va_start(AP, Format); vprintf(Format, AP); putchar('\n'); va_end(AP); if (++ERRORS >= 24) printf("Too many errors. Aborting.\n"), exit(1);} void FATAL(const char *Format, ...) { va_list AP; if (InSeg) printf("%s: [%d] ", FileTab[StartF], StartLine); va_start(AP, Format); vprintf(Format, AP); putchar('\n'); va_end(AP); exit(1);} void CHECK(void) { if (ERRORS > 0) printf("Errors present. Assembly stopped.\n"), exit(1);} byte GetB(FILE *FP) { int A; A = fgetc(FP); if (A == EOF) FATAL("Unexpected EOF."); return A&0xff;} word GetW(FILE *FP) { int A, B; A = fgetc(FP); if (A == EOF) FATAL("Unexpected EOF."); B = fgetc(FP); if (B == EOF) FATAL("Unexpected EOF."); return (A&0xff) << 8 | B&0xff;} unsigned long GetL(FILE *FP) { int A, B, C, D; A = fgetc(FP); if (A == EOF) FATAL("Unexpected EOF."); B = fgetc(FP); if (B == EOF) FATAL("Unexpected EOF."); C = fgetc(FP); if (C == EOF) FATAL("Unexpected EOF."); D = fgetc(FP); if (D == EOF) FATAL("Unexpected EOF."); return (A&0xff) << 24 | (B&0xff) << 16 | (C&0xff) << 8 | D&0xff;} void PutB(byte B, FILE *FP) { fputc(B, FP); } void PutW(word W, FILE *FP) { char A = (W >> 8)&0xff, B = W&0xff; fputc(A, FP), fputc(B, FP);} void PutL(unsigned long L, FILE *FP) { char A = (L >> 24)&0xff, B = (L >> 16)&0xff, C = (L >> 8)&0xff, D = L&0xff; fputc(A, FP), fputc(B, FP), fputc(C, FP), fputc(D, FP);} void *Allocate(unsigned Size) { void *X; if (Size == 0) return 0; X = malloc(Size); if (X == 0) FATAL("Out of memory."); return X;} void OpenF(char *Name) { if (!Active) return; if (ISP >= IS + INCLUDE_MAX - 1) FATAL("Too many nested include files."); if (ISP >= IS) { ISP->Loc = ftell(InF); if (ISP->Loc == -1L) FATAL("Could not save %s's position.", FileTab[CurF]); fclose(InF); ISP->Next = Next, ISP->Line = Line, ISP->Path = CurF; } if (Files >= FileMax) { FileMax += 4; FileTab = (char **)realloc(FileTab, FileMax * sizeof *FileTab); if (FileTab == 0) FATAL("Out of memory."); } ISP++, CurF = Files, FileTab[Files++] = CopyS(Name); StartLine = Line = 1; InF = fopen(Name, "r"); if (InF == 0) FATAL("Cannot open %s", Name); Next = fgetc(InF);} #define SEG_MAX 0x20struct Segment SegTab[SEG_MAX], *SegP;unsigned long LOC; #define GAP_MAX 0x100struct Gap GapTab[GAP_MAX], *GapP; struct AddrCard AddrTab[TYPES] = { { 0, 0xffff, 1 }, /* CODE */ { 0, 0xffff, 0 }, /* XDATA */ { 0, 0xff, 0 }, /* DATA */ { 0x80, 0xff, 0 }, /* SFR */ { 0, 0xff, 0 } /* BIT */};static struct AddrCard *AdP; Symbol Sym; static Symbol BTab[10], FTab[10];static Symbol MakeLabel(void) { static unsigned long LAB = 0L; static char Buf[10]; sprintf(Buf, "#%x", LAB++); return LookUp(Buf);} void SegInit(void) { int I, D; for (SegP = SegTab, AdP = AddrTab, I = 0; I < TYPES; AdP++, I++, SegP++) { if (SegP >= SegTab + SEG_MAX) FATAL("Too many segments."); SegP->Type = I, SegP->Rel; SegP->Base = 0, SegP->Size = 0, SegP->Loc = ftell(OutF); } AdP = AddrTab; InSeg = 1; SegP->Type = 0, SegP->Rel = 1, SegP->Line = StartLine, SegP->File = StartF, SegP->Base = 0, SegP->Size = 0, SegP->Loc = ftell(OutF); LOC = 0; for (D = 0; D < 10; D++) BTab[0] = FTab[0] = 0; GapP = GapTab;} void StartSeg(byte Type, byte Rel, word Base) { int D; if (!Active) return; if (SegP >= SegTab + SEG_MAX) FATAL("Too many segments."); if (Type > sizeof AddrTab/sizeof *AddrTab) FATAL("Undefined segment type."); AdP = AddrTab + Type; if (!Rel && (Base < AdP->Lo || Base > AdP->Hi)) FATAL("Address %u out of range", Base); InSeg = 1; SegP->Type = Type, SegP->Rel = Rel, SegP->Line = StartLine, SegP->File = StartF, SegP->Base = Base, SegP->Size = 0, SegP->Loc = ftell(OutF); LOC = 0; for (D = 0; D < 10; D++) BTab[0] = FTab[0] = 0;} void EndSeg(void) { int D; if (!Active) return; for (D = 0; D < 10; D++) if (FTab[D] != 0) ERROR("Undefined label %d", D); SegP->Size = (word)LOC; if (SegP->Size > 0) SegP++; InSeg = 0;} void Space(word Rel) { unsigned long Addr; if (!Active) return; if (AdP->ReadOnly) { if (GapP >= GapTab + GAP_MAX) FATAL("Too many gaps."); GapP->Seg = SegP, GapP->Offset = LOC, GapP->Size = Rel; GapP++; } LOC += Rel; Addr = SegP->Base + LOC; if (!SegP->Rel && Addr > AdP->Hi + 1) FATAL("Address %u out of range", Addr);} void PByte(byte B) { unsigned long Addr; if (!Active) return; if (!AdP->ReadOnly) FATAL("Attempting to write to a non-code segment."); LOC++; Addr = SegP->Base + LOC; if (!SegP->Rel && Addr > AdP->Hi + 1) FATAL("Address %u out of range", Addr); fputc(B, OutF);} void PString(char *S) { if (!Active) return; for (; *S != '\0'; S++) PByte(*S);} static void Get(void) { int Ch; if (Next == EOF) { while (Next == EOF && ISP > IS) { fclose(InF); ISP--; Next = ISP->Next, Line = ISP->Line, CurF = ISP->Path; InF = fopen(FileTab[CurF], "r"); if (InF == 0) FATAL("Cannot reopen %s", FileTab[CurF]); if (fseek(InF, ISP->Loc, SEEK_SET) != 0) { fclose(InF); FATAL("Could not restore %s's position.", FileTab[CurF]); } } if (Next == EOF) fclose(InF), Next = 0; *U++ = ' '; } else { if (Next == '\n') Line++; *U++ = Next; Next = fgetc(InF); }} typedef struct { char *Name; Lexical Tag; int Value;} Card;static Card Reserved[] = { { "ds", RB, 0 }, { "rb", RB, 0 }, { "rw", RW, 0 }, { "byte", DB, 0 }, { "word", DW, 0 }, { "db", DB, 0 }, { "dw", DW, 0 }, { "seg", SEG, 0 }, { "end", END, 0 }, { "org", ORG, 0 }, { "at", ORG, 0 }, { "equ", EQU, 0 }, { "set", SET, 0 }, { "include", INCLUDE, 0 }, { "global", GLOBAL, 0 }, { "public", GLOBAL, 0 }, { "extern", EXTERN, 0 }, { "if", IF, 0 }, { "else", ELSE, 0 }, { "high", HIGH, 0 }, { "low", LOW, 0 }, { "by", BY, 0 }, { "code", TYPE, CODE }, { "xdata", TYPE, XDATA }, { "bit", TYPE, BIT }, { "sfr", TYPE, SFR }, { "data", TYPE, DATA }, { "a", REGISTER, ACC }, { "ab", REGISTER, AB }, { "c", REGISTER, CY }, { "dptr", REGISTER, DPTR }, { "pc", REGISTER, PC }, { "r0", REGISTER, R0 }, { "r1", REGISTER, R1 }, { "r2", REGISTER, R2 }, { "r3", REGISTER, R3 }, { "r4", REGISTER, R4 }, { "r5", REGISTER, R5 }, { "r6", REGISTER, R6 }, { "r7", REGISTER, R7 }}; #define ELEMENTS(Arr) (sizeof(Arr)/sizeof(Arr[0])) static Lexical FindKey(char *Name) { Code *CP; Card *C; static Card *EndR = Reserved + ELEMENTS(Reserved); for (CP = CodeTab; CP->Name != 0; CP++) if (CompS(Name, CP->Name) == 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -