diff --git a/programs/bcc32/examples/hello.kex b/programs/bcc32/examples/hello.kex deleted file mode 100755 index a04da2be54..0000000000 Binary files a/programs/bcc32/examples/hello.kex and /dev/null differ diff --git a/programs/bcc32/t2fasm/Makefile b/programs/bcc32/t2fasm/Makefile new file mode 100755 index 0000000000..75807dc1ef --- /dev/null +++ b/programs/bcc32/t2fasm/Makefile @@ -0,0 +1,4 @@ +t2fasm: + g++ -c t2fasm.cpp + g++ -o t2fasm t2fasm.o + rm t2fasm.o diff --git a/programs/bcc32/t2fasm/t2fasm b/programs/bcc32/t2fasm/t2fasm new file mode 100755 index 0000000000..ed9c44cbf0 Binary files /dev/null and b/programs/bcc32/t2fasm/t2fasm differ diff --git a/programs/bcc32/t2fasm/t2fasm.cpp b/programs/bcc32/t2fasm/t2fasm.cpp new file mode 100755 index 0000000000..5edaccffa5 --- /dev/null +++ b/programs/bcc32/t2fasm/t2fasm.cpp @@ -0,0 +1,420 @@ +#include +#include +#include +#include +#include +using namespace std; + +char str[20000], *word[100]; +int wordlen[sizeof(word) / sizeof(word[0])]; + +char words_ignore[100][100] = { "?debug", + "if", + "ifdef", + "ifndef", + "endif", + "macro", + "endm", + "dgroup", + "assume", + "segment", + "ends", + "public", + "proc", + "endp", + "extrn", + "model", + "label", + "end", + ""}; + +#define WI_macro (words_ignore[5]) +#define WI_endm (words_ignore[6]) +#define WI_segment (words_ignore[9]) +#define WI_ends (words_ignore[10]) +#define WI_proc (words_ignore[12]) +#define WI_endp (words_ignore[13]) +#define WI_label (words_ignore[16]) +const char *WI_END = "END"; + +int nwords_ignore = -1; +char *words_ign_sort[sizeof(words_ignore) / sizeof(words_ignore[0])]; + +int strcmp1(const char *s0, int n0, const char *s1, int n1) +{ + while (n0 && n1) + { + n0--; n1--; + int c = (int)tolower(*s0) - (int)tolower(*s1); + if (c < 0) return -1; + if (c > 0) return 1; + if (!*(s0++) || !*(s1++)) return 0; + } + if (n0 && *s0) return 1; + if (n1 && *s1) return -1; + return 0; +} + +int strlen1(const char *s, int n) +{ + int i = 0; + while (i < n && s[i]) i++; + return i; +} + +char *strcpy1(char *r, const char *s, int n) +{ + char *r0 = r; + while (n-- && *s) *(r++) = *(s++); + *r = 0; + return r0; +} + +char *strchr1(char *s, int n, char c) +{ + while (n-- && *s) + { + if (*s == c) return s; + s++; + } + return 0; +} + +char *first_not_space(char *s) +{ + while (*s && isspace(*s)) s++; + return s; +} + +char get_word(char *s) +{ + int i = 0, k; + for (k = 0; k < sizeof(word) / sizeof(word[0]); k++) + { + s = first_not_space(s + i); + word[k] = s; + i = 0; + while (s[i] && !isspace(s[i]) && s[i] != ';' && s[i] != ',' && s[i] != ':') + { + i++; + } + if (i == 0) + { + if (s[i] != ',' && s[i] != ':') break; + i = 1; + } + wordlen[k] = i; + } + for (; k < sizeof(word) / sizeof(word[0]); k++) + { + word[k] = s; wordlen[k] = 0; + } + return s[i]; +} + +void build_words_ignore() +{ + int i, j; + nwords_ignore = 0; + while (words_ignore[nwords_ignore][0]) + { + words_ign_sort[nwords_ignore] = words_ignore[nwords_ignore]; + nwords_ignore++; + } + for (i = 0; i < nwords_ignore; i++) for (j = 0; j < i; j++) + { + if (strcmp1(words_ign_sort[j], -1, words_ign_sort[i], -1) > 0) + { + char *s = words_ign_sort[j]; + words_ign_sort[j] = words_ign_sort[i]; + words_ign_sort[i] = s; + } + } + words_ign_sort[nwords_ignore] = words_ignore[nwords_ignore]; +} + +int find_word_ign_sort(const char *s, int n) +{ + int i0, i1, i; + if (nwords_ignore < 0) build_words_ignore(); + i0 = -1; i1 = nwords_ignore; + while (i1 > i0 + 1) + { + i = (i0 + i1) / 2; + if (strcmp1(s, n, words_ign_sort[i], -1) > 0) i0 = i; + else i1 = i; + } + return i1; +} + +char *find_word_ignore(const char *s, int n) +{ + int i = find_word_ign_sort(s, n); + return (strcmp1(s, n, words_ign_sort[i], -1) == 0) ? words_ign_sort[i] : 0; +} + +char *add_word_ignore(const char *s, int n) +{ + int i = find_word_ign_sort(s, n), j; + if (strcmp1(s, n, words_ign_sort[i], -1) != 0) + { + if (s[0] && strlen1(s, n) < sizeof(words_ignore[0]) && + words_ignore[nwords_ignore+1] < words_ignore[0] + sizeof(words_ignore)) + { + strcpy1(words_ignore[nwords_ignore], s, n); + words_ignore[nwords_ignore+1][0] = 0; + for (j = nwords_ignore; j >= i; j--) words_ign_sort[j+1] = words_ign_sort[j]; + words_ign_sort[i] = words_ignore[nwords_ignore]; + nwords_ignore++; + words_ign_sort[nwords_ignore] = words_ignore[nwords_ignore]; + } + else return 0; + } + return words_ign_sort[i]; +} + +struct CSegment +{ + char name[100]; + int state; + string text; +}; + +int nsegment = 0, cursegment = 0, stack_segment[50], nstack_segment = 0; +CSegment segment[100]; + +void push_stack_segment() +{ + if (nstack_segment < sizeof(stack_segment) / sizeof(stack_segment[0])) + { + stack_segment[nstack_segment] = cursegment; + } + nstack_segment++; +} + +void pop_stack_segment() +{ + if (nstack_segment > 0) nstack_segment--; + if (nstack_segment < sizeof(stack_segment) / sizeof(stack_segment[0])) + { + cursegment = stack_segment[nstack_segment]; + } +} + +void newsegment() +{ + segment[nsegment].name[0] = 0; + segment[nsegment].state = 0; + segment[nsegment].text = ""; + cursegment = nsegment++; +} + +void tosegment(char *name, int nameL) +{ + int i; + cursegment = 0; + if (strlen1(name, nameL) >= sizeof(segment[0].name)) return; + for (i = 0; i < nsegment; i++) + { + if (strcmp1(name, nameL, segment[i].name, -1) == 0) + { + cursegment = i; + return; + } + } + if (nsegment >= sizeof(segment) / sizeof(segment[0])) return; + newsegment(); + strcpy1(segment[cursegment].name, name, nameL); +} + +void outsegment() +{ + if (segment[cursegment].state == 0) return; + fputs("\nsegment", stdout); + if (segment[cursegment].name[0]) + { + fputc(' ', stdout); + fputs(segment[cursegment].name, stdout); + } + fputc('\n', stdout); + fputs(segment[cursegment].text.c_str(), stdout); + fputs("endseg", stdout); + if (segment[cursegment].name[0]) + { + fputs(" ", stdout); + fputs(segment[cursegment].name, stdout); + } + fputc('\n', stdout); +} + +void transform_label(int in_define, bool label = false) +{ + if (in_define) + { + memmove(str + 8, word[0], wordlen[0]); + memcpy(str, "nextdef ", 8); + str[wordlen[0]+8] = '\n'; + str[wordlen[0]+9] = 0; + } + else if (label) + { + memmove(str, word[0], wordlen[0]); + str[wordlen[0]] = ':'; + str[wordlen[0]+1] = '\n'; + str[wordlen[0]+2] = 0; + } + segment[cursegment].state |= 4; +} + +int main() +{ + char *s; + int in_macro = 0, in_define = 0, i; + newsegment(); + for (;;) + { + i = sizeof(str) - 200; + if (!fgets(str, i, stdin)) break; + if ((s = strchr(str, '\n')) == NULL) + { + if (strlen(str) < i-1) strcat(str, "\n"); + else + { + while (fgets(str, sizeof(str), stdin)) + { + if (strchr(str, '\n')) break; + } + continue; + } + } + char* p; + while (p=strstr(str,"st(")) + { + p[2]=p[3]; + memmove(p+3,p+5,strlen(p+5)+1); + } + get_word(str); + if (word[1][0] == ':') transform_label(in_define, false); + else + { + if (word[0][0] == '.') continue; + if (strcmp1(word[0], wordlen[0], WI_macro, -1) == 0 || + strcmp1(word[1], wordlen[1], WI_macro, -1) == 0) + { + add_word_ignore(word[0], wordlen[0]); + in_macro++; + continue; + } + if (strcmp1(word[0], wordlen[0], WI_endm, -1) == 0) + { + if (in_macro > 0) in_macro--; + continue; + } + if (strcmp1(word[1], wordlen[1], WI_segment, -1) == 0) + { + push_stack_segment(); + add_word_ignore(word[0], wordlen[0]); + tosegment(word[0], wordlen[0]); + continue; + } + if (strcmp1(word[1], wordlen[1], WI_ends, -1) == 0) + { + pop_stack_segment(); + continue; + } + if (find_word_ignore(word[0], wordlen[0])) continue; + if (wordlen[0] == 0 || strcmp1(word[0], wordlen[0], "align", -1) == 0) + { + if (word[0][0] == 0) {str[0] = '\n'; str[1] = 0;} + } + else if (strcmp1(word[1], wordlen[1], WI_endp, -1) == 0) + { + if (in_define > 0) strcpy(str, (--in_define) ? "newdef\n" : "enddef\n"); + } + else if (strcmp1(word[1], wordlen[1], WI_proc, -1) == 0) + { + memmove(str + 8, word[0], wordlen[0]); + memcpy(str, (in_define++) ? "newdef " : "define ", 8); + str[wordlen[0]+8] = '\n'; + str[wordlen[0]+9] = 0; + segment[cursegment].state |= 4; + } + else if (strcmp1(word[1], wordlen[1], WI_label, -1) == 0) + { + transform_label(in_define, true); + } + else + { + for (i = 0; i <= 1; i++) + { + if (strcmp1(word[i], wordlen[i], "db", -1) == 0 && + wordlen[i+2] >= 3 && strcmp1(word[i+2], 3, "dup", 3) == 0) + { + if (word[i][0] == 'd') word[i][0] = 'r'; + else if (word[i][0] == 'D') word[i][0] = 'R'; + word[i+1][wordlen[i+1]] = '\n'; + word[i+1][wordlen[i+1]+1] = 0; + segment[cursegment].state |= 2; + break; + } + } + if (i > 1) + { + int word_shift = 0; + for (i = 1; i < sizeof(word) / sizeof(word[0]); i++) + { + word[i] += word_shift; + if (wordlen[i] >= 4 && word[i][0] != '[' && + word[i][wordlen[i]-1] == ']' && + (s = strchr1(word[i], wordlen[i], '[')) != 0) + { + *s = '+'; + memmove(word[i] + 1, word[i], strlen(word[i]) + 1); + word[i][0] = '['; + wordlen[i]++; + word_shift++; + } + else if (wordlen[i] >= 1 && !strchr1(word[i], wordlen[i], '[') && + strcmp1(word[i-1], wordlen[i-1], "ptr", -1) == 0) + { + memmove(word[i] + wordlen[i] + 2, word[i] + wordlen[i], + strlen(word[i] + wordlen[i]) + 1); + memmove(word[i] + 1, word[i], wordlen[i]); + word[i][0] = '['; word[i][wordlen[i] + 1] = ']'; + wordlen[i] += 2; + word_shift += 2; + } + else if (wordlen[i] >= 5 && word[i][wordlen[i]-1] == ')' && + strcmp1(word[i], wordlen[i], "st(", -1)) + { + memmove(word[i] + 2, word[i] + 3, wordlen[i] - 4); + memmove(word[i] + wordlen[i] - 2, word[i] + wordlen[i], + strlen(word[i] + wordlen[i]) + 1); + word_shift -= 2; + } + } + segment[cursegment].state |= 1; + } + } + } + if (in_macro) continue; + if ((s = strchr(str, ';')) != NULL) + { + s[0] = '\n'; s[1] = 0; + if (!first_not_space(str)[0]) continue; + } + segment[cursegment].text += str; + } + for (cursegment = 0; cursegment < nsegment; cursegment++) + { + if ((segment[cursegment].state & 3) != 2) outsegment(); + } + fputs("\nI_END:\n", stdout); + for (cursegment = 0; cursegment < nsegment; cursegment++) + { + if ((segment[cursegment].state & 3) == 2) outsegment(); + } + fputs("\nalign 0x10\nU_END:\n", stdout); + return 0; +} +