added 'uniconverter' to convert various speccy assembler files to text
[urasm.git] / uniconverter / src / cvttasm / tasm.c
blob6db8776218486773b3211362e155f66448ccb8aa
1 #include "tasm.h"
3 #include <ctype.h>
4 #include <string.h>
7 static const char *token[] = {
8 "A", "ADC ", "ADD ", "AF'", "AF", "AND ", "B", "BC", "BIT ", "C", "CALL ", "CCF", "CP ", "CPD", "CPDR", "CPI",
9 "CPIR", "CPL", "D", "DAA", "DE", "DEC ", "DEFB ", "DEFM ", "DEFS ", "DEFW ", "DI", "PHASE ", "DJNZ ", "E", "EI", "UNPHASE ",
10 "EQU ", "EX ", "EXX", "H", "HALT", "HL", "I", "IM ", "IN ", "INC ", "IND", "INDR", "INI", "INIR", "IX", "IY",
11 "JP ", "JR ", "L", "LD ", "LDD", "LDDR", "LDI", "LDIR", "M", "NC", "NEG", "NOP", "NV", "NZ", "OR ", "ORG ",
12 "OTDR", "OTIR", "OUT ", "OUTD", "OUTI", "P", "PE", "PO", "POP ", "PUSH ", "R", "RES ", "RET", "RETI", "RETN", "RL ",
13 "RLA", "RLC ", "RLCA", "RLD", "RR ", "RRA", "RRC ", "RRCA", "RRD", "RST ", "SBC ", "SCF", "SET ", "SLA ", "SP", "SRA ",
14 "SRL ", "SUB ", "V", "XOR ", "Z", "INCLUDE ", "INCBIN ", "SLI ", "INF", "LX", "HX", "LY", "HY", "DB ", "DM ", "DS ",
15 "DW ", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?"
19 #define GETBYTE(_dst) do { \
20 if (--buflen < 0) { free(buf); return -1; } \
21 (_dst) = *from++; \
22 } while (0)
25 #define PUTCH(_ch) do { \
26 uint8_t _xch = (uint8_t)(_ch); \
27 if (fwrite(&_xch, 1, 1, fo) != 1) { free(buf); return -1; } \
28 } while (0)
31 static int extract (FILE *fo, FILE *fi) {
32 int buflen;
33 uint8_t *buf;
34 const uint8_t *from;
35 int isTasm4;
37 if ((buf = loadWholeFile(fi, &buflen)) == NULL) return -1;
38 if ((buflen -= sizeof(HOBHeader)) < 1) { free(buf); return -1; }
40 isTasm4 = (((const HOBHeader *)buf)->start <= 4096);
41 from = buf+sizeof(HOBHeader);
42 for (;;) {
43 uint8_t len;
45 GETBYTE(len);
46 if (len == 0xFF) break;
47 for (int i = 0; i < len; ++i) {
48 if (buflen < 1) { free(buf); return -1; }
49 if (*from < 0x20) {
50 if (isTasm4 || (*from == 0x0A && i != len-1)) {
51 if (!isTasm4 || (isTasm4 && *from == 0x01)) {
52 ++from; --buflen;
53 ++i;
54 if (buflen < 1) { free(buf); return -1; }
56 for (int j = 0; j < *from; j++) PUTCH(0x20);
57 } else {
58 PUTCH(*from);
60 } else if (*from < 0x80) {
61 PUTCH(*from);
62 } else {
63 const char *ptr;
65 if (!isTasm4) {
66 ptr = token[*from-0x80];
67 } else {
68 switch (*from) {
69 case 0x97://"DEFM "
70 ptr = "DEFMAC ";
71 break;
72 case 0x9B://"PHASE "
73 ptr = "DISPLAY ";
74 break;
75 case 0x9F://"UNPHASE "
76 ptr = "ENDMAC ";
77 break;
78 default:
79 ptr = token[*from-0x80];
80 break;
83 while (*ptr) PUTCH(*ptr++);
85 ++from; --buflen;
86 if (buflen < 1) break;
88 PUTCH('\n');
89 if (buflen < 1 || *from != len) break;
90 ++from; --buflen;
91 if (buflen < 1) break;
93 return 0;
97 static const int detect (FILE *fi, const char *fname, const HOBHeader *hdr) {
98 if (!(hdr->type == 'A' && (hdr->start == 39221)) &&
99 !(hdr->type == 'A' && (hdr->start == 40872)) &&
100 !(hdr->type == 'A' && (hdr->start <= 4096))) return 0;
101 return 1;
105 ////////////////////////////////////////////////////////////////////////////////
106 static CvtMethods mtlist;
109 CvtMethods *cvt_tasm (void) {
110 mtlist.name = "TASM assembler";
111 mtlist.fmtname = "tasm";
112 mtlist.extract = extract;
113 mtlist.detect = detect;
114 return &mtlist;