1 /*
2 * Short program to create a Robotron KC85/2..KC85/4 type header
3 *
4 *
5 * $Id: kc.c,v 1.1 2016-10-03 06:14:49 stefano Exp $
6 */
7
8 #include "appmake.h"
9 #include <string.h>
10 #include <ctype.h>
11
12
13
14 static char *binname = NULL;
15 static char *crtfile = NULL;
16 static char *outfile = NULL;
17 static char *blockname = NULL;
18 static int origin = -1;
19 static char help = 0;
20
21
22 /* Options that are available for this module */
23 option_t kc_options[] = {
24 { 'h', "help", "Display this help", OPT_BOOL, &help},
25 { 'b', "binfile", "Linked binary file", OPT_STR, &binname },
26 { 'c', "crt0file", "crt0 file used in linking", OPT_STR, &crtfile },
27 { 'o', "output", "Name of output file", OPT_STR, &outfile },
28 { 0 , "org", "Origin of the binary", OPT_INT, &origin },
29 { 0 , "blockname", "Name of the code block in tap file", OPT_STR, &blockname},
30 { 0, NULL, NULL, OPT_NONE, NULL }
31 };
32
33
34
35 /*
36 * Execution starts here
37 */
38
kc_exec(char * target)39 int kc_exec(char* target)
40 {
41 char filename[FILENAME_MAX + 1];
42 FILE* fpin;
43 FILE* fpout;
44 long pos;
45 int len;
46 int c, i;
47 int nflag;
48
49 if (help)
50 return -1;
51
52 if (binname == NULL) {
53 return -1;
54 }
55
56 if (outfile == NULL) {
57 strcpy(filename, binname);
58 } else {
59 strcpy(filename, outfile);
60 }
61
62 // strupr(filename);
63 // not available on all platforms
64
65 for (i = strlen(filename) - 1; i >= 0 && filename[i] != '/' && filename[i] != '\\'; i--)
66 filename[i] = toupper(filename[i]);
67
68 //
69
70 suffix_change(filename, ".KCC");
71
72 if (strcmp(binname, filename) == 0) {
73 exit_log(1,"Input and output file names must be different\n");
74 }
75
76 if (blockname == NULL)
77 blockname = zbasename(binname);
78
79 if (origin != -1) {
80 pos = origin;
81 } else {
82 if ((pos = get_org_addr(crtfile)) == -1) {
83 exit_log(1,"Could not find parameter ZORG (not z88dk compiled?)\n");
84 }
85 }
86
87 if ((fpin = fopen_bin(binname, crtfile)) == NULL) {
88 exit_log(1, "Can't open input file %s\n", binname);
89 }
90
91 if (fseek(fpin, 0, SEEK_END)) {
92 fclose(fpin);
93 exit_log(1, "Couldn't determine size of file\n");
94 fclose(fpin);
95 }
96
97 len = ftell(fpin);
98
99 fseek(fpin, 0L, SEEK_SET);
100
101 if ((fpout = fopen(filename, "wb")) == NULL) {
102 fclose(fpin);
103 exit_log(1,"Can't open output file\n");
104 }
105
106 /* deal with the filename */
107 nflag = 0;
108 for (i = 0; i < 8; i++) {
109 if (nflag)
110 writebyte(0, fpout);
111 else {
112 if (!isalnum(blockname[i])) {
113 writebyte(0, fpout);
114 nflag++;
115 } else {
116 writebyte(toupper(blockname[i]), fpout);
117 }
118 }
119 }
120
121 writebyte('K', fpout);
122 writebyte('C', fpout);
123 writebyte('C', fpout);
124
125 for (i = 0; i < 5; i++)
126 writebyte(0, fpout);
127
128 writebyte(3, fpout); /* 0x02 = load, 0x03 = autostart */
129
130 writeword(pos, fpout);
131 writeword(pos + len, fpout);
132 writeword(pos, fpout); /* start address */
133
134 for (i = 0; i < 105; i++)
135 writebyte(0, fpout);
136
137 for (i = 0; i < len; i++) {
138 c = getc(fpin);
139 writebyte(c, fpout);
140 }
141
142 // Pad the block out to 128 bytes
143 while( (i % 128) > 0) {
144 writebyte(0, fpout);
145 i++;
146 }
147
148 fclose(fpin);
149 fclose(fpout);
150
151 return 0;
152 }
153