Mercurial > hg > Members > kono > os9 > sbc09
annotate os9/makerom.c @ 178:4d83154d2a78
add - {} some builtin in TL/1
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 15 Apr 2019 09:43:28 +0900 |
parents | ef5959682d03 |
children |
rev | line source |
---|---|
0 | 1 /* makerom.c |
2 build ROM image file os9.rom from module list | |
11 | 3 |
4 Shinji KONO Fri Jul 6 13:31:52 JST 2018 | |
5 | |
0 | 6 */ |
7 | |
8 #include <stdio.h> | |
9 #include <stdlib.h> | |
10 #include <strings.h> | |
151 | 11 #include <string.h> |
0 | 12 #include <sys/stat.h> |
13 | |
11 | 14 // #define DEBUG 1 |
15 | |
16 /* | |
17 * Level1 | |
18 * os9p1 should be 0xf800 | |
19 * it searches ram from the beginning | |
20 * rom modules are searched from just after the end of RAM | |
21 * | |
22 * Level2 | |
23 * Coco 512kb memory space | |
24 * last 8k is a ROM (can be switched?) ( block 0x3f ) | |
25 * os9p1 search module on 0x0d00~0x1e00 at block 0x3f | |
26 * | |
27 * 8k block ( offset 0xc000 ) | |
28 * | |
29 * 0xe000 - 0xccff 0xff | |
12
111e5defb8ab
boot is called, rti failed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
11
diff
changeset
|
30 * 0xed00 - 0xfeff os9 modules, os9p1 should be the last |
11 | 31 * MMU doesnot touch below |
32 * 0xff80 - 0xffdf IO port ( ACIA, clock, pdisk, MMU ) | |
33 * 0xffd0 - 0xffef boot code | |
34 * 0xfff0 - 0xffff intr vector | |
35 * ... next few blocks as extended ROM | |
84 | 36 * lv2 6809 memory check routine destroys 0x200 on page 0x40 |
37 * sta >-$6000,x | |
38 * avoid 0x200 | |
11 | 39 * |
40 */ | |
41 | |
7
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
6
diff
changeset
|
42 int level = 1; |
6 | 43 int IOBASE = 0xe000; |
44 int IOSIZE = 0x100; | |
45 char * outfile ; | |
0 | 46 |
12
111e5defb8ab
boot is called, rti failed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
11
diff
changeset
|
47 #define LV2START 0xffd0 // our own small boot for mmu |
17 | 48 #define LV2ROMEND 0xff80 |
9 | 49 |
8 | 50 // #define DEBUG |
51 | |
0 | 52 typedef struct os9module { |
53 int size; | |
34 | 54 int entry; |
0 | 55 int location; |
56 int ioflag; | |
57 unsigned char *mod; | |
58 char *name; | |
59 struct os9module *next; | |
60 } *MPTR ; | |
61 | |
33 | 62 unsigned short vec[8]; |
63 | |
0 | 64 struct os9module * |
65 readOS9module(char *filename) | |
66 { | |
67 FILE *fp = fopen(filename,"rb"); | |
68 if (fp==0) { | |
69 fprintf(stderr,"cannot read %s\n",filename); | |
70 exit(1); | |
71 } | |
72 struct stat st; | |
73 fstat(fileno(fp),&st); | |
74 int size = st.st_size; | |
75 struct os9module *m = malloc(size + sizeof(struct os9module)); | |
76 m->size = size; | |
77 m->next = 0; | |
78 m->ioflag = 0; | |
79 m->mod = (unsigned char*)m + sizeof(struct os9module); | |
80 fread(m->mod , size, 1, fp); | |
81 m->name = (char*) (m->mod + (m->mod[4]*256 + m->mod[5]) ); | |
34 | 82 m->entry = m->mod[9]*256 + m->mod[10] ; |
0 | 83 fclose(fp); |
84 return m; | |
85 } | |
86 | |
87 void | |
88 fputword(unsigned short x, FILE *fp) | |
89 { | |
90 fputc((x>>8)&0xff,fp); | |
91 fputc(x&0xff,fp); | |
92 } | |
93 | |
94 void printOs9Str(char *p) | |
95 { | |
34 | 96 char *q = p; |
0 | 97 while((*p & 0x80)==0) { |
98 putchar(*p); | |
99 p++; | |
100 } | |
101 putchar(*p & 0x7f); | |
34 | 102 while(p<q+8) { |
103 putchar(' '); p++; | |
104 } | |
0 | 105 } |
106 | |
10 | 107 unsigned short |
108 getword(unsigned char *ptr) | |
109 { | |
110 return (ptr[0]<<8)+ptr[1]; | |
111 } | |
112 | |
12
111e5defb8ab
boot is called, rti failed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
11
diff
changeset
|
113 void rewrite_vector(MPTR m,int size, unsigned char *adr,int count) |
10 | 114 { |
115 // vector is a offset from $F100 (possibly os9p1 module address) | |
12
111e5defb8ab
boot is called, rti failed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
11
diff
changeset
|
116 int offset = -size-0xf100; |
10 | 117 for(int i=0;i<count;i++) { |
118 int vec = getword(adr); | |
12
111e5defb8ab
boot is called, rti failed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
11
diff
changeset
|
119 vec += offset; |
10 | 120 adr[0] = vec>>8; |
121 adr[1] = vec&0xff; | |
122 adr += 2; | |
123 } | |
124 } | |
125 | |
33 | 126 int search_vector(MPTR m) { |
127 unsigned char v[] = { 0x6E, 0x9F, 0x00, 0x2C, 0x6E}; | |
128 for( unsigned char *p = m->mod ; p < m->mod + m->size; p++ ) { | |
129 int i=0; | |
130 for(; i< sizeof(v); i++) { | |
131 if (p[i]!=v[i]) break; | |
132 } | |
133 if (i==sizeof(v)) | |
134 return p - m->mod; | |
135 } | |
136 return 0; | |
137 } | |
138 | |
1 | 139 // calcurate position from the botton |
140 // avoid v09 IO map on 0xe000-0xe800 | |
141 // os9p1 have to be last and at 0xf800 | |
0 | 142 int findLocation(MPTR m, int loc) { |
143 if (m==0) return loc; | |
144 int top = findLocation(m->next, loc) - m->size; | |
7
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
6
diff
changeset
|
145 if (m->next==0) { |
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
6
diff
changeset
|
146 if (level == 1) |
33 | 147 if (m->size > 0xff80-0xf800 ) { |
148 top = 0x10000-(m->size+0x80); | |
149 } else { | |
150 top = 0xf800; // OS9p1 | |
151 } | |
10 | 152 else { |
33 | 153 #if 0 |
154 // old level2 kernel has vector at the bottom | |
17 | 155 top = 0x10000-(m->size+0x80); |
12
111e5defb8ab
boot is called, rti failed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
11
diff
changeset
|
156 rewrite_vector(m,m->size,m->mod+getword(m->mod+2),7); |
33 | 157 #else |
158 top = 0xf000; // level2 OS9p1 starts here | |
159 // and theses area are RAM /REGISTER STACK/ | |
160 #endif | |
10 | 161 } |
7
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
6
diff
changeset
|
162 } |
8 | 163 if (level==1 && !(( top+m->size < IOBASE ) || ( IOBASE+IOSIZE < top)) ) { |
0 | 164 top = IOBASE-m->size-1; |
165 m->ioflag = 1; | |
8 | 166 #ifdef DEBUG |
167 printf("*"); | |
168 #endif | |
11 | 169 } else if (level==2 && 0xed00 > top) { |
170 m->ioflag = 1; | |
0 | 171 } |
172 m->location = top; | |
8 | 173 #ifdef DEBUG |
174 printf("mod "); | |
175 printOs9Str(m->name); | |
176 printf(" \t: 0x%x - 0x%x\n",top, top + m->size); | |
177 #endif | |
0 | 178 return top; |
179 } | |
180 | |
181 int | |
182 main(int ac, char *av[]) | |
183 { | |
184 int vectable = 0; | |
185 struct os9module *m = 0, root ; | |
186 root.size = 0; | |
187 root.mod = 0; | |
188 m = &root; | |
189 | |
6 | 190 for(int i = 1 ; i<ac ; i++ ) { |
191 if (*av[i]=='-') { | |
7
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
6
diff
changeset
|
192 if (av[i][1] =='2') { // for level 2 |
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
6
diff
changeset
|
193 level = 2; |
12
111e5defb8ab
boot is called, rti failed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
11
diff
changeset
|
194 IOBASE = LV2ROMEND; |
6 | 195 } else if (av[i][1] =='o') { |
196 outfile = av[i+1]; | |
197 i += 1; | |
198 } else { | |
199 return 1; | |
200 } | |
201 continue; | |
202 } | |
0 | 203 struct os9module *cur; |
204 cur = readOS9module(av[i]); | |
205 m->next = cur; | |
206 m = cur; | |
207 } | |
208 | |
209 FILE *romfile; | |
210 unsigned pos; | |
6 | 211 if (outfile==0) return 1; |
0 | 212 |
6 | 213 romfile=fopen(outfile,"wb"); |
0 | 214 if(!romfile) { |
215 fprintf(stderr,"Cannot create file %s\n",av[1]); | |
216 exit(1); | |
217 } | |
218 | |
219 | |
220 int start = findLocation(root.next,0); | |
221 start = start&0xf800; | |
222 printf("\n\n"); | |
223 | |
11 | 224 if (level==2) { |
225 for(int i=0; i<0xd00; i++) fputc(0xff,romfile); | |
226 pos = 0xed00; | |
227 } else { | |
228 pos = start; | |
229 } | |
33 | 230 int ofs = 0; |
8 | 231 struct os9module *os9p1 = 0; |
0 | 232 for(struct os9module *cur = root.next; cur ; cur = cur->next ) { |
11 | 233 if ( level==2 && cur->ioflag ==1) continue; |
6 | 234 // last module have to os9p1 |
7
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
6
diff
changeset
|
235 if ( cur->next == 0 ) { |
8 | 236 os9p1 = cur; |
7
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
6
diff
changeset
|
237 if ( level==1 ) { |
33 | 238 if (os9p1->size > 0x07f0) { |
239 ofs = (os9p1->size+0xf)&0xfff0; | |
240 ofs -= 0x07f0; | |
241 } | |
242 for(; pos < 0xf800-ofs ; pos++) { // os9p1 begins at 0xf800 | |
7
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
6
diff
changeset
|
243 fputc(0xff,romfile); |
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
6
diff
changeset
|
244 } |
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
6
diff
changeset
|
245 } else { |
33 | 246 #if 0 |
17 | 247 int pend = 0x10000-( cur->size +0x80); |
248 for(; pos < pend ; pos++) { // os9p1 ends 0xff7f | |
7
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
6
diff
changeset
|
249 fputc(0xff,romfile); |
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
6
diff
changeset
|
250 } |
33 | 251 #endif |
252 for(; pos < 0xf000 ; pos++) { // level2 os9p1 start from 0xf000 | |
253 fputc(0xff,romfile); | |
254 } | |
7
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
6
diff
changeset
|
255 } |
0 | 256 } |
257 printf("mod "); | |
258 printOs9Str(cur->name); | |
33 | 259 cur->location = pos; |
0 | 260 fwrite(cur->mod, cur->size, 1, romfile); |
34 | 261 printf(" \t: 0x%x - 0x%x size 0x%04x entry 0x%x\n",pos, pos + cur->size-1,cur->size,cur->entry+cur->location); |
8 | 262 #ifdef DEBUG |
263 printf(" \t: 0x%x \n",cur->location); | |
264 printf(" \t: 0x%x - 0x%x : 0x%lx \n",pos, pos + cur->size, ftell(romfile)+start); | |
265 #endif | |
0 | 266 pos = pos+cur->size; |
11 | 267 if (level==1 && cur->ioflag) { |
7
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
6
diff
changeset
|
268 if (level==1) { |
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
6
diff
changeset
|
269 for(; pos < IOBASE + IOSIZE; pos++) { |
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
6
diff
changeset
|
270 fputc(0xff,romfile); |
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
6
diff
changeset
|
271 } |
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
6
diff
changeset
|
272 printf("*"); |
8 | 273 } |
0 | 274 } |
275 } | |
276 printf("os9 end %x\n",pos); | |
7
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
6
diff
changeset
|
277 if (level==1) { |
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
6
diff
changeset
|
278 vectable = 0x10000 - 2*7; |
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
6
diff
changeset
|
279 for( ; pos<vectable; pos++) fputc(0xff,romfile); |
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
6
diff
changeset
|
280 printf("vectbl %x\n",pos); |
33 | 281 if (1) { |
282 int vecofs = search_vector(os9p1); | |
283 if (vecofs==0) { | |
284 printf("can't find vector\n"); | |
285 } | |
34 | 286 static int perm[] = {0,1,5,4,2,3}; |
33 | 287 for(int i=0;i<6;i++) { |
34 | 288 fputword(os9p1->location +vecofs+perm[i]*4,romfile); |
33 | 289 } |
290 int entry_ofs = (m->mod[9]<<8) + m->mod[10]; | |
291 fputword( os9p1->location + entry_ofs ,romfile); | |
292 // printf("os9p1 location ofs %0x\n", os9p1->location); | |
293 // printf("vector ofs %0x\n", vecofs); | |
294 // printf("reset ofs %0x\n", entry_ofs); | |
295 } else { | |
296 fputword(0xF82d-ofs,romfile); | |
297 fputword(0xF831-ofs,romfile); | |
298 fputword(0xF835-ofs,romfile); | |
299 fputword(0xF839-ofs,romfile); | |
300 fputword(0xF83d-ofs,romfile); | |
301 fputword(0xF841-ofs,romfile); | |
302 fputword(0xF876-ofs,romfile); | |
303 } | |
7
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
6
diff
changeset
|
304 } else { |
8 | 305 char vector[] = "level2/vector"; |
306 FILE *fp = fopen(vector,"rb"); | |
307 if (fp==0) { | |
308 fprintf(stderr,"cannot read %s\n",vector); | |
309 exit(1); | |
310 } | |
9 | 311 for( ; pos<LV2START; pos++) fputc(0xff,romfile); |
7
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
6
diff
changeset
|
312 printf("vectbl %x\n",pos); |
8 | 313 for( ; pos<0xfff0; pos++) fputc(fgetc(fp),romfile); |
314 #ifdef DEBUG | |
315 printf("os9entry %x\n",os9p1->location); | |
316 #endif | |
317 printf("os9entry %x\n",os9p1->location+getword(os9p1->mod+9)); | |
318 | |
319 fputword(os9p1->location+getword(os9p1->mod+9),romfile); // os9p1 entry point | |
11 | 320 unsigned short vec = os9p1->location+os9p1->size - 18; |
8 | 321 fputword(vec,romfile); |
322 fputword(vec+3,romfile); | |
323 fputword(vec+6,romfile); | |
324 | |
325 fputword(vec+9,romfile); | |
326 fputword(vec+12,romfile); | |
327 fputword(vec+15,romfile); | |
9 | 328 fputword(LV2START,romfile); |
11 | 329 |
330 pos = 0x10000; | |
15 | 331 int bootsize = 2; |
332 for(struct os9module *cur = root.next; cur ; cur = cur->next ) { | |
333 if ( cur->ioflag ==0) continue; | |
334 bootsize += cur->size; | |
335 } | |
84 | 336 bootsize += 0x300-2; // to avoid 0x200 bombing |
15 | 337 fputc(bootsize>>8,romfile); |
338 fputc(bootsize&0xff,romfile); | |
339 pos += 2; | |
84 | 340 for( int i = 0; i<0x300-2; i++) fputc(0xff,romfile); |
11 | 341 for(struct os9module *cur = root.next; cur ; cur = cur->next ) { |
342 if ( cur->ioflag ==0) continue; | |
33 | 343 cur->location = pos; |
11 | 344 printf("mod "); |
345 printOs9Str(cur->name); | |
346 fwrite(cur->mod, cur->size, 1, romfile); | |
34 | 347 printf(" \t: 0x%x - 0x%x size 0x%04x entry 0x%x\n",pos, pos + cur->size-1, cur->size, cur->entry+cur->location); |
11 | 348 #ifdef DEBUG |
349 printf(" \t: 0x%x \n",cur->location); | |
350 printf(" \t: 0x%x - 0x%x : 0x%lx \n",pos, pos + cur->size, ftell(romfile)+start); | |
351 #endif | |
15 | 352 pos += cur->size; |
11 | 353 } |
30 | 354 while(pos++ & 0xff) fputc(0xff,romfile); |
7
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
6
diff
changeset
|
355 } |
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
6
diff
changeset
|
356 if (level==1) |
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
6
diff
changeset
|
357 printf("boot rom from 0x%lx\n",0x10000-ftell(romfile)); |
30 | 358 else { |
359 long size; | |
360 printf("boot rom from 0xc000 size 0x%lx\n",(size=ftell(romfile))); | |
361 if (size > 0x4d00 + 0x2000) { | |
362 printf(" was too big. make it less than 0x6d00\n"); | |
363 } | |
364 } | |
0 | 365 fclose(romfile); |
366 return 0; | |
367 } | |
11 | 368 |
369 |