view os9/makerom.c @ 7:a6db579d8c11

level 2 rom preparing...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Thu, 05 Jul 2018 02:00:14 +0900
parents 9c2602e1d716
children 96a067cf4c4f
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 level = 1;
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) {
       if (level == 1)
          top = 0xf800;  // OS9p1
       else
          top = 0x10000-(m->size+0x80);
   }
   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] =='2') {  // for level 2
            level = 2;
            IOBASE = 0xff00;
        } 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 ) {
        if ( level==1 ) { 
           for(; pos < 0xf800 ; pos++) {   // os9p1 begins at 0xf800
              fputc(0xff,romfile);
           }
        } else {
           int pend = 0x10000-( cur->size +0x80);
           for(; pos < pend ; pos++) {      // os9p1 ends 0xff7f
              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-1);
    // printf(" \t: 0x%x - 0x%x : 0x%lx \n",pos, pos + cur->size, ftell(romfile)+start);
    pos = pos+cur->size;
    if (cur->ioflag) {
       if (level==1) {
           for(; pos < IOBASE + IOSIZE; pos++) {
              fputc(0xff,romfile);
           }
           printf("*");
       } else {
           for(; pos < IOBASE + IOSIZE - 2*7 ; pos++) {
              fputc(0xff,romfile);
           }
       }
    } 
 }
 printf("os9 end %x\n",pos);
 if (level==1) {
     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);
 } else {
     vectable  = 0x10000 - 2*6;
     for( ; pos<vectable; pos++) fputc(0xff,romfile);
     printf("vectbl %x\n",pos);
     fputword(0xff6e,romfile);
     fputword(0xff71,romfile);
     fputword(0xff74,romfile);
     fputword(0xff7a,romfile);
     fputword(0xff7d,romfile);
     fputword(0xff7d,romfile);
 }
 if (level==1) 
     printf("boot rom from 0x%lx\n",0x10000-ftell(romfile)); 
 else
     printf("boot rom from 0x%lx\n",512*1024-ftell(romfile)); 
 fclose(romfile);
 return 0;
}