Version bump for last commit; now at v2.0.23.
[rmac] / 68kgen.c
1 //
2 // RMAC - Reboot's Macro Assembler for all Atari computers
3 // 68KGEN.C - Tool to Generate 68000 Opcode Table
4 // Copyright (C) 199x Landon Dyer, 2011-2020 Reboot and Friends
5 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
6 // Source utilised with the kind permission of Landon Dyer
7 //
8
9 #include <stdio.h>
10 #include <ctype.h>
11 #include <stdlib.h>
12
13
14 #define EOS     '\0'
15
16 int kwnum = 1;                  /* current op# for kwgen output */
17 FILE * kfp;                             /* keyword file */
18 int lineno = 0;
19
20 // Function prototypes
21 void error(char *, char *);
22 void procln(int, char **);
23
24
25 int main(int argc, char ** argv)
26 {
27         char * namv[256];
28         char * s;
29         int namcnt;
30         char ln[256];
31
32         if ((argc == 2) && ((kfp = fopen(argv[1], "w")) == NULL))
33                 error("Cannot create: %s", argv[1]);
34
35         while (fgets(ln, 256, stdin) != NULL)
36         {
37                 lineno++;                       /* bump line# */
38
39                 if (*ln == '#')         /* ignore comments */
40                         continue;
41
42                 /*
43                  *  Tokenize line (like the way "argc, argv" works)
44                  *  and pass it to the parser.
45                  */
46                 namcnt = 0;
47                 s = ln;
48
49                 while (*s)
50                 {
51                         if (isspace(*s))
52                                 ++s;
53                         else
54                         {
55                                 namv[namcnt++] = s;
56
57                                 while (*s && !isspace(*s))
58                                         s++;
59
60                                 if (isspace(*s))
61                                         *s++ = EOS;
62                         }
63                 }
64
65                 if (namcnt)
66                         procln(namcnt, namv);
67         }
68
69         return 0;
70 }
71
72
73 //
74 // Parse line
75 //
76 void procln(int namc, char ** namv)
77 {
78         int i, j;
79
80         // alias for previous entry
81         if (namc == 1)
82         {
83                 fprintf(kfp, "%s\t%d\n", namv[0], kwnum - 1 + 1000);
84                 return;
85         }
86
87         if (namc < 5)
88         {
89                 fprintf(stderr, "%d: missing fields\n", lineno);
90                 exit(1);
91         }
92
93         // output keyword name
94         if (*namv[0] != '-')
95                 fprintf(kfp, "%s\t%d\n", namv[0], kwnum + 1000);
96
97         printf("/*%4d %-6s*/  {", kwnum, namv[0]);
98
99         if (*namv[1] == '!')
100                 printf("CGSPECIAL");
101         else for(char * s=namv[1], i=0; *s; s++)
102                 printf("%sSIZ%c", (i++ ? "|" : ""), *s);
103
104         printf(", %s, %s, ", namv[2], namv[3]);
105
106         // enforce little fascist percent signs
107         if (*namv[4] == '%')
108         {
109                 for(i=1, j=0; i<17; i++)
110                 {
111                         j <<= 1;
112
113                         if (namv[4][i] == '1' || isupper(namv[4][i]))
114                                 j++;
115                 }
116
117                 printf("0x%04x, ", j);
118         }
119         else
120                 printf("%s, ", namv[4]);
121
122         if (namc == 7 && *namv[6] == '+')
123                 printf("%d, ", kwnum + 1);
124         else
125                 printf("0, ");
126
127         printf("%s},\n", namv[5]);
128
129         kwnum++;
130 }
131
132
133 void error(char * s, char * s1)
134 {
135         fprintf(stderr, s, s1);
136         fprintf(stderr, "\n");
137         exit(1);
138 }
139