source: Thomson/tools/bastok/bastok.cpp

Last change on this file was 63, checked in by pulkomandy, 5 years ago

bastok: tool to convert a BASIC tokenized file to ASCII.

File size: 3.4 KB
Line 
1#include <map>
2#include <vector>
3#include <stdint.h>
4
5#include <arpa/inet.h>
6
7struct __attribute__((packed)) BAS_Data {
8        uint8_t type;
9        uint16_t length;
10        std::vector<uint8_t> data;
11};
12
13bool BAS_ReadChunk(FILE* in, BAS_Data& out) {
14        // Read the chunk header
15        int value = fread(&out, 3, 1, in);
16        if (value == 0)
17                return false;
18
19        // 6809 is little endian, take that into account...
20        out.length = ntohs(out.length);
21
22        // Resize the data member to the proper size and read the data to it.
23        out.data.reserve(out.length);
24        fread(&out.data[0], out.length, 1, in);
25
26        return true;
27};
28
29struct __attribute__((packed)) BAS_Line {
30        uint16_t offset;
31        uint16_t number;
32        uint8_t data[];
33};
34
35void BAStoASCII(BAS_Data& data)
36{
37        std::map<uint8_t, const char*> Opcodes;
38        std::map<uint8_t, const char*> Functions;
39
40        // FLOW CONTROL
41        Opcodes[0x80] = "END";
42        Opcodes[0x81] = "FOR";
43        Opcodes[0x82] = "NEXT";
44        Opcodes[0x83] = "DATA";
45        Opcodes[0x84] = "DIM";
46        Opcodes[0x85] = "READ";
47        //
48        Opcodes[0x87] = "GO";
49        //
50        Opcodes[0x89] = "IF";
51        Opcodes[0x8A] = "RESTORE";
52        Opcodes[0x8B] = "RETURN";
53        //
54        Opcodes[0x93] = "DEFINT";
55        // CURSOR
56        Opcodes[0x9C] = "LOCATE";
57        Opcodes[0x9D] = "CLS";
58        // MACHINE
59        Opcodes[0xA2] = "EXEC";
60        // DISPLAY
61        Opcodes[0xA4] = "COLOR";
62        Opcodes[0xA5] = "LINE";
63        Opcodes[0xA6] = "BOX";
64        //
65        Opcodes[0xA8] = "ATTRB";
66        Opcodes[0xA9] = "DEF"; // FIXME DEFGR$
67        Opcodes[0xAA] = "POKE";
68        Opcodes[0xAB] = "PRINT";
69        //
70        Opcodes[0xAE] = "CLEAR";
71
72        // SOUND
73        Opcodes[0xB9] = "PLAY";
74
75        // SUB-CODES
76        Opcodes[0xBB] = "TO";
77        Opcodes[0xBC] = "SUB";
78        //
79        Opcodes[0xBF] = "USING";
80        //
81        Opcodes[0xC4] = "THEN";
82        //
83        Opcodes[0xC6] = "STEP";
84
85        // OPERATORS
86        Opcodes[0xC7] = "+";
87        Opcodes[0xC8] = "-";
88        Opcodes[0xC9] = "*";
89        Opcodes[0xCA] = "/";
90        //
91        Opcodes[0xCC] = "AND";
92        Opcodes[0xCD] = "OR";
93        //
94        Opcodes[0xD3] = ">";
95        Opcodes[0xD4] = "=";
96        Opcodes[0xD5] = "<";
97
98
99        Functions[0x81] = "INT";
100        Functions[0x82] = "ABS";
101        Functions[0x8B] = "LEN";
102        Functions[0x8E] = "ASC";
103        Functions[0x8F] = "CHR$";
104        Functions[0x99] = "GR$";
105        Functions[0x9A] = "LEFT$";
106        Functions[0x9C] = "MID$";
107        Functions[0x9F] = "RND";
108        Functions[0xA0] = "INKEY$";
109        Functions[0xA1] = "INPUT$";
110        Functions[0xA4] = "SCREEN";
111
112        /* ################################ */
113
114        BAS_Line* currentLine;
115        currentLine = (BAS_Line*)&data.data[0];
116
117        bool func = false;
118        while(currentLine->offset) {
119                // Endianness fixup
120                currentLine->offset = ntohs(currentLine->offset);
121                currentLine->number = ntohs(currentLine->number);
122
123                printf("%d ", currentLine->number);
124               
125                for (int i = 0; currentLine->data[i]; i++) {
126                        uint8_t c = currentLine->data[i];
127                        if (c < 128 && isprint(c))
128                                putchar(c);
129                        else if (c == 0xFF) {
130                                func = true;
131                                continue;
132                        } else if ((!func) && (Opcodes.find(c) != Opcodes.end()))
133                                printf("\x1B[31m%s\x1B[0m", Opcodes[c]);
134                        else if (func && (Functions.find(c) != Functions.end()))
135                                printf("\x1B[32m%s\x1B[0m", Functions[c]);
136                        else {
137                                printf("\n*** UNKNOWN %s %x ***\n", func?"FUNCTION":"OPCODE", c);
138                                for (int k = 0; currentLine->data[k]; k++)
139                                        printf("%02X ", currentLine->data[k]);
140                                puts("");
141                                exit(EXIT_FAILURE);
142                        }
143                        func = false;
144                }
145                currentLine = (BAS_Line*)&data.data[currentLine->offset - 0x25A4];
146                puts("");
147        }
148}
149
150int main(int argc, char* argv[])
151{
152        if (argc < 2)
153        {
154                fprintf(stderr, "%s file.bas\n", argv[0]);
155                return 1;
156        }
157
158        FILE* in;
159        BAS_Data h;
160
161        in = fopen(argv[1], "rb");
162
163        while(BAS_ReadChunk(in, h))
164        {
165                BAStoASCII(h);
166        };
167
168}
Note: See TracBrowser for help on using the repository browser.