uniconverter: xas
[urasm.git] / uniconverter / src / cvtxas / xas.c
blobb27072fdb03ddcc4708e03a97ade3af6fb643b48
1 #include "xas.h"
3 #include <ctype.h>
4 #include <string.h>
7 static const char *opcodes[] = {
8 "LDIR", "LDDR", "LDI", "LDD", "CPIR", "CPDR", "CPI", "CPD", "INIR", "INDR", "INI", "IND", "OUTI", "OTIR", "OUTD", "OTDR",
9 "RETI", "RETN", "NEG", "RLD", "RRD", "PUSH", "POP", "ADD", "SUB", "ADC", "SBC", "AND", "OR", "XOR", "CP", "INC",
10 "DEC", "BIT", "RES", "SET", "RLC", "RRC", "RL", "RR", "SLA", "SRA", "SLI", "SRL", "LD", "EX", "IN", "OUT",
11 "IM", "RST", "DJNZ", "JP", "JR", "CALL", "RET", "EXX", "CPL", "DAA", "RLCA", "RRCA", "RLA", "RRA", "NOP", "HALT",
12 "DI", "EI", "SCF", "CCF", "ORG", "ENT", "EQU", "WORK", "DB", "DW", "DM", "DS", "!ASSM", "!CONT", "LTEXT", "LCODE",
13 "BC", "DE", "HL", "IX", "IY", "SP", "AF", "(C)", "B", "C", "D", "E", "H", "L", "(HL)", "A",
14 "(BC)", "(DE)", "HX", "LX", "HY", "LY", "I", "R", "NZ", "Z", "NC", "PO", "PE", "P", "M", "!ON",
15 "!OFF", "(SP)", "AF'", "USEL", "IFNZ", "IFZ", "MAKE" "?", "?", "?", "?", "?", "?", "?", "?", "?"
19 static uint8_t cyr (uint8_t b) {
20 // OEM code page
21 static const uint8_t cyr1[] = {'ä', 'ö', 'é', 'ê', 'ì', 'ð', 'õ', 'æ', 'ã', 'þ', 'ù', 'ø', 'ü', 'à', 'ñ', 'ÿ'};
22 static const uint8_t cyr2[] = {'û', 'ý', 'â', 'ç'};
24 if (b >= 0x10 && b <= 0x1f) return cyr1[b-0x10];
25 if (b >= 0x7b && b <= 0x7e) return cyr2[b-0x7b];
26 return b;
30 static uint8_t toLower (uint8_t b) {
31 // convert all UPPERCASE letters to lowercase
32 if (b >= 'A' && b <= 'Z') return b-'A'+'a';
33 return b;
38 static uint8_t transform (uint8_t b) {
39 b = cyr(b);
40 b = toLower(b);
41 return b;
46 #define GETBYTE(_dst) do { \
47 if (--buflen < 0) { free(buf); return -1; } \
48 (_dst) = *p++; \
49 } while (0)
52 #define PUTCH(_ch) do { \
53 uint8_t _xch = (uint8_t)(_ch); \
54 if (fwrite(&_xch, 1, 1, fo) != 1) { free(buf); return -1; } \
55 } while (0)
58 static int extract (FILE *fo, FILE *fi) {
59 int buflen;
60 uint8_t *buf;
61 const uint8_t *p;
62 const char *from;
63 int needComma;
65 if ((buf = loadWholeFile(fi, &buflen)) == NULL) return -1;
66 if ((buflen -= sizeof(HOBHeader)) < 1) { free(buf); return -1; }
67 if ((buflen -= 29+2+1+1+1+1+1) < 1) { free(buf); return -1; }
69 p = buf+sizeof(HOBHeader)+29+2+1+1+1+1+1;
70 while (buflen > 0 && *p) {
71 uint8_t b;
73 GETBYTE(b);
74 // process the label
75 while (b < 0x80) {
76 if (b == 0x0d || b == 0x0c || b == 0x09) {
77 // EOL
78 PUTCH('\n');
79 goto NEXT_LINE;
81 if (b == ';') {
82 // it's comment;
83 while (b != 0x0d && b != 0x0c && b != 0x09) {
84 PUTCH(cyr(b));
85 if (buflen < 1) break;
86 GETBYTE(b);
88 PUTCH('\n');
89 goto NEXT_LINE;
91 PUTCH(toLower(b));
92 if (buflen < 1) goto NEXT_LINE;
93 GETBYTE(b);
95 // command
96 //PUTCH('\t');
97 //PUTCH('\t');
98 PUTCH(' ');
99 PUTCH(' ');
100 from = opcodes[b-0x80];
101 while (*from) PUTCH(*from++);
102 //PUTCH('\t');
103 PUTCH(' ');
104 needComma = 0;
105 // loop foreach token
106 while (buflen > 0) {
107 GETBYTE(b);
108 if (b == 0x0d || b == 0x0c || b == 0x09) {
109 // EOL
110 PUTCH('\n');
111 goto NEXT_LINE;
114 if (b == ';') {
115 //PUTCH('\t');
116 PUTCH(' ');
117 while (b != 0x0d && b != 0x0c && b != 0x09) {
118 PUTCH(cyr(b));
119 if (buflen < 1) goto NEXT_LINE;
120 GETBYTE(b);
122 PUTCH('\n');
123 goto NEXT_LINE;
126 if (b >= 0x80) {
127 if (needComma) PUTCH(',');
128 from = opcodes[b-0x80];
129 while (*from) PUTCH(*from++);
130 needComma = 1;
131 continue;
134 if (b == '(') {
135 if (needComma) PUTCH(',');
136 PUTCH('(');
137 GETBYTE(b);
138 while (b != ')') {
139 if (b >= 0x80) {
140 from = opcodes[b-0x80];
141 while (*from) PUTCH(*from++);
142 } else {
143 PUTCH(toLower(b));
145 GETBYTE(b);
147 PUTCH(')');
148 needComma = 1;
149 continue;
152 if (b == '"') {
153 if (needComma) PUTCH(',');
154 PUTCH('"');
155 // special case """
156 if (buflen > 1 && p[0] == '"' && p[1] == '"') {
157 p += 2; buflen -= 2;
158 PUTCH('\\');
159 PUTCH('"');
160 continue;
162 GETBYTE(b);
163 while (b != '"') {
164 PUTCH(cyr(b));
165 GETBYTE(b);
167 PUTCH('"');
168 needComma = 1;
169 continue;
172 if (needComma) PUTCH(',');
173 while (b < 0x80 && b != '(' && b != ';' && b != 0x0d && b != 0x0c && b != 0x09) {
174 PUTCH(toLower(b));
175 if (buflen < 1) goto NEXT_LINE1;
176 GETBYTE(b);
178 needComma = 1;
179 --p; ++buflen;
181 NEXT_LINE1:;
182 PUTCH('\n');
183 NEXT_LINE:;
185 free(buf);
186 return 0;
190 static const int detect (FILE *fi, const char *fname, const HOBHeader *hdr) {
191 if ((hdr->type != 'X' && hdr->type != 'x') ||
192 (hdr->type1 != 'A' && hdr->type1 != 'a') ||
193 hdr->type2 != 'S') return 0;
194 return 1;
198 ////////////////////////////////////////////////////////////////////////////////
199 static CvtMethods mtlist;
202 CvtMethods *cvt_xas (void) {
203 mtlist.name = "XAS assembler";
204 mtlist.fmtname = "xas";
205 mtlist.extract = extract;
206 mtlist.detect = detect;
207 return &mtlist;