view os9/makerom.c @ 6:9c2602e1d716

level2 rom done
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Thu, 05 Jul 2018 00:02:54 +0900
parents 3c736a81b886
children a6db579d8c11
line wrap: on
line source

/* makerom.c 
   build ROM image file os9.rom from module list
*/

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/stat.h>

int IOBASE = 0xe000;
int IOSIZE = 0x100;
char * outfile ;

typedef struct os9module {
   int size;
   int location;
   int ioflag;
   unsigned char *mod;
   char *name;
   struct os9module *next;
} *MPTR ; 

struct os9module *
readOS9module(char *filename) 
{
  FILE *fp = fopen(filename,"rb");
  if (fp==0) {
    fprintf(stderr,"cannot read %s\n",filename);
    exit(1);
  }
  struct stat st;
  fstat(fileno(fp),&st);
  int size = st.st_size;
  struct os9module *m = malloc(size + sizeof(struct os9module));
  m->size = size;
  m->next = 0;
  m->ioflag = 0;
  m->mod = (unsigned char*)m + sizeof(struct os9module);
  fread(m->mod , size, 1, fp);
  m->name = (char*) (m->mod + (m->mod[4]*256 + m->mod[5]) );
  fclose(fp);
  return m;
}

void
fputword(unsigned short x, FILE *fp)
{
   fputc((x>>8)&0xff,fp);
   fputc(x&0xff,fp);
}

void printOs9Str(char *p)
{
   while((*p & 0x80)==0) {
      putchar(*p);
      p++;
   }
   putchar(*p & 0x7f);
}

// calcurate position from the botton
// avoid v09 IO map on 0xe000-0xe800
// os9p1 have to be last and at 0xf800
int findLocation(MPTR m, int loc) {
   if (m==0) return loc;
   int top = findLocation(m->next, loc) - m->size;
   if (m->next==0) top = 0xf800;  // OS9p1
   if (!(( top+m->size < IOBASE )  || ( IOBASE+IOSIZE < top)) ) {
      top = IOBASE-m->size-1;
      m->ioflag = 1;
      // printf("*");
   }
   m->location = top;
   // printf("mod ");
   // printOs9Str(m->name);
   // printf(" \t: 0x%x - 0x%x\n",top, top + m->size);
   return top;
}

int
main(int ac, char *av[])
{
 int vectable = 0;
 struct os9module *m = 0, root ;
 root.size = 0;
 root.mod = 0;
 m = &root;

 for(int i = 1 ; i<ac ; i++ ) {
    if (*av[i]=='-') {
        if (av[i][1] =='i') {
            IOBASE = strtol(av[i],(char**)0,0);
            i += 1;
        } else if (av[i][1] =='o') {
            outfile = av[i+1];
            i += 1;
        } else {
            return 1;
        }
        continue;
    }
    struct os9module *cur;
    cur = readOS9module(av[i]);
    m->next = cur;
    m = cur;
 }

 FILE *romfile;
 unsigned pos;
 if (outfile==0) return 1;

 romfile=fopen(outfile,"wb");
 if(!romfile) {
  fprintf(stderr,"Cannot create file %s\n",av[1]);
  exit(1);
 }

 
 int start = findLocation(root.next,0);
 start = start&0xf800;
 printf("\n\n");

 pos = start;
 for(struct os9module *cur = root.next; cur ; cur = cur->next ) {
    // last module have to os9p1
    if ( cur->next == 0 ) { //   cur->size && (cur->name[0]=='O' && cur->name[1]=='S' && cur->name[2]== -71)) {
       for(; pos < 0xf800 ; pos++) {   // os9p1 begins at 0xf800
          fputc(0xff,romfile);
       }
    }
    printf("mod ");
    printOs9Str(cur->name);
    fwrite(cur->mod, cur->size, 1, romfile);
    printf(" \t: 0x%x - 0x%x\n",pos, pos + cur->size);
    // printf(" \t: 0x%x - 0x%x : 0x%lx \n",pos, pos + cur->size, ftell(romfile)+start);
    pos = pos+cur->size;
    if (cur->ioflag) {
       for(; pos < IOBASE + IOSIZE; pos++) {
          fputc(0xff,romfile);
       }
       printf("*");
    } 
 }
 printf("os9 end %x\n",pos);
 vectable  = 0x10000 - 2*7;
 for( ; pos<vectable; pos++) fputc(0xff,romfile);
 printf("vectbl %x\n",pos);
 fputword(0xF82d,romfile);
 fputword(0xF831,romfile);
 fputword(0xF835,romfile);
 fputword(0xF839,romfile);
 fputword(0xF83d,romfile);
 fputword(0xF841,romfile);
 fputword(0xF876,romfile);
 
 printf("boot rom from 0x%lx\n",0x10000-ftell(romfile)); 
 fclose(romfile);
 return 0;
}