home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1991 / 07 / coff.asc < prev    next >
Text File  |  1991-06-11  |  15KB  |  481 lines

  1. _A COFF FILE LOADER FOR THE 34010_
  2. by Don Morgan
  3.  
  4.  
  5.  
  6. [LISTING ONE]
  7.  
  8. #include <fcntl.h>
  9. #include <sys\types.h>
  10. #include <sys\stat.h>
  11. #include <io.h>
  12. #include <conio.h>
  13. #include <string.h>
  14. #include <stdio.h>
  15. #include <malloc.h>
  16. #include <stdlib.h>
  17. #include "coff.h"
  18.  
  19. struct main_header *m_hdr;
  20. struct opt_header *opt;
  21. struct sect_header section;
  22.  
  23. void main(int argc, char **argv)
  24. {
  25. /**************** PART A *****************/
  26.         int module, size, header, sect, j;
  27.         unsigned long result;
  28.         int bss_done = FALSE;
  29.         
  30.         unsigned char *receive_buffer;
  31.         char tmp_buf[100];
  32.         int data, i;
  33.         if(argc != 2) {
  34.                 printf("\nno file given!");
  35.                 exit(-1);
  36.                 }
  37.         module = open(argv[1], O_BINARY|O_RDONLY);
  38.         if(module == -1){
  39.                 perror("\nopen failed!");
  40.                 exit(-1);
  41.                               }
  42.         /**************************/
  43.         /*read coff file into buffer*/
  44.         size = filelength(module);
  45.         file_buffer = (char *)malloc(size);
  46.         if(file_buffer == NULL) {
  47.                 perror("\nnot enough memory!");
  48.                 exit (-1);
  49.                 }
  50.         if((result = (long)read(module, file_buffer, size)) <= 0) {
  51.                 perror("\ncan't find file!\n");
  52.                 exit(-1);
  53.                 }
  54.         close(module);
  55.  
  56. /************  PART B    *************/
  57. /*set up 34010 for loading*/
  58. /**************************/
  59. /*it is the users responsibility to set up the cntrl register*/
  60. /*please note that some of the register settings, such as the following*/
  61. /*are application dependent, this code is included only to show an*/
  62. /*example of low level setup for the 34010*/
  63.         gsp_poke(cntrl, 0x4);  /*sets cas before ras refresh*/
  64.         
  65. /**************************/
  66. /*set up 34010 to restart correctly after loading program*/
  67.         put_hstctl(hlt | cf | incr | incw | nmim | nmi_flg);
  68.         data = get_hstctl();
  69.         if(data != (hlt | cf | incr | incw | nmim | nmi_flg)) {
  70.                 printf("\nerror writing to hstctl!");
  71.                 exit(-1);
  72.                               }
  73.  
  74. /************ PART C  *************/
  75. /**************************/
  76. /*get contents of main header*/
  77.         m_hdr = (struct main_header *) file_buffer;
  78. /*see if the file has a magic number*/
  79.         if(m_hdr->magic_num !=FILE_MAGIC) {
  80.                 printf("\nnot a standard coff .out file!");
  81.                 exit(-1);
  82.                 }
  83. /*check to see whether there is an optional header*/
  84.         if((m_hdr->opt_head != OPT_XST)){ 
  85.                 printf("file is not fully linked!");
  86.                 exit(-1);
  87.                 }
  88. /*get contents of optional header*/
  89.         opt = (struct opt_header *) &file_buffer[OPT_OFST];
  90. /*see if the optional header has a magic number*/
  91.         if(opt->magic_num !=OPT_MAGIC) {
  92.                 printf("\nnon standard file!");
  93.                 exit(-1);
  94.                 }
  95.                 
  96. /*************************************************/ 
  97. /*begin searching for and loading section headers find bss section first! */ 
  98.        i = FIRST_HDR;
  99.        for (j=0;((j<m_hdr->num_sects) && !bss_done) ;j++){
  100.                strcpy(tmp_buf,&file_buffer[i]);
  101.                if(!bss_done) {
  102.                        if(!(strcmp(tmp_buf, ".bss"))) {
  103.                                strcpy(section.name, tmp_buf);
  104.                                header = i;
  105.                                get_sect(header);
  106.                                bss_done =     TRUE;
  107.                                }
  108.                        }
  109.                i += SEC_OFST;
  110.                }
  111.        /*now load the other sections*/                
  112.        i = FIRST_HDR;
  113.        for (j=0; j<m_hdr->num_sects;j++){
  114.                strcpy(tmp_buf,&file_buffer[i]);
  115.                if(strcmp(tmp_buf, ".bss")) {
  116.                        strcpy(section.name, tmp_buf);
  117.                        header = i;
  118.                        get_sect(header);
  119.                        }
  120.                i += SEC_OFST;
  121.                }
  122.  
  123.          /*release memory for file buffer*/
  124.        free(file_buffer);
  125.      
  126. /************ PART D *************/
  127. /*set up reset and interrupt vectors for the 34010                 */
  128. /*usually, both the nmi and halt bits are set and then released    */
  129. /*this code may differ depending upon the desires of the programmer */
  130.      gsp_poke(intenb,0x0);  /*no interrupts*/
  131.      gsp_poke(nmi_vect, opt->entry_point);
  132.      gsp_poke(nmi_vect+0x10, opt->entry_point >> 0x10);
  133.      gsp_poke(reset,opt->entry_point);
  134.      gsp_poke(reset+0x10,opt->entry_point >> 0x10);
  135.      put_hstctl(hlt | incr | nmi_flg | incw | nmim);
  136.                   /*toggle the halt bit and go*/
  137.      data = get_hstctl();
  138.      data &= ~hlt;
  139.      put_hstctl( data );
  140. }
  141.  
  142. /*********** PART E *************/
  143. void get_sect(header)
  144. int header;
  145. {
  146.      struct sect_header * ptr = (struct sect_header *)&file_buffer[header];
  147.      load(ptr);
  148. }
  149. void load(ptr)
  150. struct sect_header *ptr;
  151. {
  152. /*here the flags are checked to determine whether the section is to be loaded or copied or ignored*/
  153.        if((ptr->sect_size) && !(ptr->flags & STYP_DSECT) &&
  154.                !(ptr->flags & STYP_NOLOAD)) {
  155.                        if(!(strcmp(ptr->name,".cinit")) 
  156.                                && (ptr->flags & STYP_COPY)) 
  157.                                        put_data(ptr);
  158.                        else
  159.                        if(((ptr->flags & STYP_TEXT)
  160.                                || (ptr->flags & STYP_DATA) 
  161.                                        || (!(strcmp(ptr->name,".cinit") 
  162.                                           && !(ptr->flags &   STYP_COPY))))) 
  163.                                                        load_block(ptr);
  164.        }
  165. }      
  166. void load_block(ptr)
  167. struct sect_header *ptr;
  168. {      
  169.        int data, temporary, hldr, limit;
  170.        long i, j, file_pointer;
  171.        file_pointer = ptr->raw_data;
  172. /*set the host interface up to point at the correct address*/
  173. #if MM
  174.        *(gsp:>hstadrl) = ptr->virt_addr;
  175.        *(gsp:>hstadrh) = ptr->virt_addr >> 0x10;
  176. #else
  177.        outpw(io_hstadrl, (unsigned int)ptr->virt_addr);
  178.        outpw(io_hstadrh, (unsigned int)ptr->virt_addr >> 0x10);
  179. #endif
  180.        limit = (ptr->sect_size/0x10)-1;
  181.        j=0;
  182.        /*write each word to host interface*/
  183.        for(i=0; i<=limit; i++){
  184. /*get the data from the file buffer and get it in the correct order before writing to the host interface*/
  185.                  data = (file_buffer[file_pointer+j++]&0xff);
  186.            data += ((file_buffer[file_pointer+j++]&0xff)*0x100);
  187. #if MM
  188.            *(gsp:>hstdata) = data;
  189. #else
  190.            outpw(io_hstdata,data);
  191. #endif
  192.                  }
  193.        /*compare data*/
  194.       /*point at the correct address*/ 
  195. #if MM
  196.        *(gsp:>hstadrl) = ptr->virt_addr;
  197.        *(gsp:>hstadrh) = ptr->virt_addr >> 0x10;
  198. #else
  199.        outpw(io_hstadrl, (unsigned int)ptr->virt_addr);
  200.        outpw(io_hstadrh, (unsigned int)ptr->virt_addr>> 0x10);
  201. #endif
  202.        limit = (ptr->sect_size/0x10)-1;
  203.        j=0;
  204.        for(i=0; i<=limit; i++){
  205.                        /*get the data*/
  206.                  data = (file_buffer[file_pointer+j++]&0xff);
  207.            data += ((file_buffer[file_pointer+j++]&0xff)*0x100);
  208. #if MM
  209.            hldr = *(gsp:>hstdata);
  210. #else
  211.            hldr = inpw(io_hstdata);
  212. #endif
  213.            if(hldr != data)
  214.                  printf("\ncompare error!");
  215.            }
  216. }
  217. void put_data(ptr)
  218. struct sect_header *ptr;
  219. {
  220.        int data, temporary, hldr, limit, num_words, num;
  221.        long i, j, reloc_address, file_pointer;
  222.        struct init_table * init;
  223.        file_pointer = ptr->raw_data;
  224.        do{
  225.      init = (struct init_table *)&file_buffer[file_pointer];
  226.                  reloc_address = init->ptr_to_var;
  227.            file_pointer += 6;
  228.  
  229. /*point at relocation address*/
  230. #if MM
  231.            *(gsp:>hstadrl) = reloc_address;
  232.            *(gsp:>hstadrh) = reloc_address >> 0x10;
  233. #else
  234.            outpw(io_hstadrl, (unsigned int)reloc_address);
  235.            outpw(io_hstadrh, (unsigned int)reloc_address >> 0x10);
  236. #endif
  237.  
  238. /*determine the amount of data to transfer and do it*/     
  239.            num_words = init->num_words;
  240.            limit = --num_words;
  241.            j=0;
  242.            for(i=0; i<=limit; i++){
  243.                  data = (file_buffer[file_pointer+j++]&0xff);
  244.                  data += ((file_buffer[file_pointer+j++]&0xff)*0x100);
  245. #if MM
  246.               *(gsp:>hstdata) = data;
  247. #else
  248.               outpw(io_hstdata,data);
  249. #endif
  250.               }
  251.                /*now, do a data compare*/
  252. #if MM
  253.            *(gsp:>hstadrl) = reloc_address;
  254.            *(gsp:>hstadrh) = reloc_address >> 0x10;
  255. #else
  256.            outpw(io_hstadrl, (unsigned int)reloc_address);
  257.            outpw(io_hstadrh, (unsigned int)reloc_address >> 0x10);
  258. #endif
  259.            num_words = init->num_words;
  260.            limit = --num_words;
  261.            j=0;
  262.            for(i=0; i<=limit; i++){
  263.                  data = (file_buffer[file_pointer+j++]&0xff);
  264.               data += ((file_buffer[file_pointer+j++]&0xff)*0x100);
  265. #if MM
  266.               hldr = *(gsp:>hstdata);
  267. #else
  268.               hldr = inpw(io_hstdata);
  269. #endif
  270.               if(hldr != data)
  271.                         printf("\ndata compare error!");
  272.               }
  273.        file_pointer += j;     
  274.      }while(((int)file_buffer[file_pointer]) != 0x0);
  275. }
  276. /*set up the hstctl*/
  277. void put_hstctl(unsigned int value)
  278. {
  279. #if MM
  280.        *(gsp:>hstctl) = value;
  281. #else
  282.        outpw(io_hstctl,value);
  283. #endif
  284. }
  285. /*get current Hstclt setting*/
  286. unsigned int get_hstctl()
  287. {
  288.        int value;
  289. #if MM
  290.        value = *(gsp:>hstctl);
  291. #else
  292.        value = inpw(io_hstctl);
  293. #endif
  294.        return value;
  295. }
  296. /*set host interface to point at correct address*/
  297. void set_addr(unsigned long address)
  298. {
  299. #if MM
  300.        *(gsp:>hstadrl) = address;
  301.        *(gsp:>hstadrh) = address >> 0x10;
  302. #else
  303.        outpw(io_hstadrl,(unsigned int)address);
  304.        outpw(io_hstadrh,(unsigned int)address >> 0x10);
  305. #endif
  306. }
  307. void gsp_poke(unsigned long address, unsigned long value)
  308. {
  309.        set_addr(address);
  310. #if MM
  311.        *(gsp:>hstdata) = value;
  312. #else
  313.        outpw(io_hstdata,(unsigned int)value);
  314. #endif
  315. }
  316. unsigned int gsp_peek(unsigned long address)
  317. {
  318.        int value;
  319.        
  320.        set_addr(address);
  321. #if MM
  322.        value = *(gsp:>hstdata);
  323. #else
  324.        value = inpw(io_hstdata);
  325. #endif
  326.        return value;
  327. }
  328.   
  329.   
  330.  
  331.  
  332. [LISTING TWO]
  333.  
  334. #define FALSE 0
  335. #define TRUE 0x1
  336.  
  337. #define MM TRUE
  338.  
  339. /*physical addresses of memory mapped host interface*/
  340. #if MM
  341. _segment gsp = 0xc700;
  342. int _based(void) *hstctl = (int _based(void)*)0xe00;
  343. int _based(void) *hstdata = (int _based(void)*)0xf00;
  344. int _based(void) *hstadrh = (int _based(void)*)0xc00;
  345. int _based(void) *hstadrl = (int _based(void)*)0xd00;
  346. #else
  347. /*io mapped addresses of host interface*/
  348. io_hstctl = 0;
  349. io_hstdata = 0;
  350. io_hstadrh = 0;
  351. io_hstadrl = 0;
  352. #endif
  353.  
  354. #define FILE_MAGIC 0x90
  355. #define OPT_MAGIC 0x108
  356. #define OPT_XST 0x1c
  357. #define OPT_OFST 0x14
  358. #define SEC_OFST 0x28
  359. #define FIRST_HDR 0x30
  360.  
  361. #define cf 0x4000
  362. #define hlt 0x8000
  363. #define nmi_flg 0x100
  364. #define nmim 0x200
  365. #define incw 0x800
  366. #define incr 0x1000
  367.  
  368. /*definitions*/
  369. /*file header flags*/
  370. #define F_RELFLG 0x1               /*relocation information stripped*/
  371. #define F_EXEC 0x2                 /*file is relocateable*/
  372. #define F_LNNO 0x4                 /*line numbers stripped*/
  373. #define F_LSYMS 0x10               /*local symbos stripped*/
  374. #define F_QR32WR 0x40              /*34010 byte ordering*/
  375.  
  376. /*section header flags*/
  377. #define STYP_REG 0x0               /*regular section*/
  378. #define STYP_DSECT 0x1             /*dummy section*/
  379. #define STYP_NOLOAD 0x2            /*noload section*/
  380. #define STYP_GROUP 0x4             /*grouped section*/
  381. #define STYP_PAD 0x8               /*padding section*/
  382. #define STYP_COPY 0x10             /*copy section, important for .cinit*/
  383. #define STYP_TEXT 0x20             /*executable code*/
  384. #define STYP_DATA 0x40             /*initialized data*/
  385. #define STYP_BSS 0x80              /*uninitialized data*/
  386. #define STYP_ALIGN 0x100           /*aligned on cache boundary*/
  387.  
  388. /*******************************************************/
  389. /*interrupt vector:*/
  390. #define reset          0xffffffe0
  391. #define nmi_vect       0xfffffee0
  392. /*******************************************************/
  393. /*i/o registers:*/
  394. #define refcnt         0xc00001f0
  395. #define dpyadr         0xc00001e0
  396. #define vcount         0xc00001d0
  397. #define hcount         0xc00001c0
  398. #define dpytap         0xc00001b0
  399. #define pmask          0xc0000160
  400. #define psize          0xc0000150
  401. #define convdp         0xc0000140
  402. #define convsp         0xc0000130
  403. #define intpend        0xc0000120
  404. #define intenb         0xc0000110
  405. #define hstctlh        0xc0000100
  406. #define hstctll        0xc00000f0
  407. #define hst_adrh       0xc00000d0
  408. #define hst_adrl       0xc00000e0
  409. #define hst_data       0xc00000c0
  410. #define cntrl          0xc00000b0
  411. #define dpyint         0xc00000a0
  412. #define dpystrt        0xc0000090
  413. #define dpyctl         0xc0000080
  414. #define vtotal         0xc0000070
  415. #define vsblnk         0xc0000060
  416. #define veblnk         0xc0000050
  417. #define vesync         0xc0000040
  418. #define htotal         0xc0000030
  419. #define hsblnk         0xc0000020
  420. #define heblnk         0xc0000010
  421. #define hesync         0xc0000000
  422. #define dac_wr         0xc7800
  423. #define ppl_rd         0xc7000
  424.  
  425. /*header structures*/
  426. struct main_header {
  427.      unsigned short int magic_num;
  428.      unsigned short int num_sects;
  429.      long int date_stamp;
  430.      long int sym_table;
  431.      long int entries;
  432.      unsigned short int opt_head;
  433.      unsigned short int flags;
  434.      };
  435. struct opt_header {
  436.      short int magic_num;
  437.      short int version;
  438.      unsigned long code_size;
  439.      unsigned long init_size;
  440.      unsigned long uninit_size;
  441.      unsigned long entry_point;
  442.      unsigned long start_text;
  443.      unsigned long start_data;
  444.      };
  445. struct sect_header {
  446.      unsigned char name[8];
  447.      unsigned long phys_addr;
  448.      unsigned long virt_addr;
  449.      unsigned long sect_size;
  450.      unsigned long raw_data;
  451.      unsigned long reloc;
  452.      unsigned long num_entries;
  453.      unsigned short int reloc_entries;
  454.      unsigned short int line_entries;
  455.      unsigned short int flags;
  456.      unsigned char ch1;
  457.      unsigned char page;
  458.      };
  459. struct init_table {
  460.      int num_words;
  461.      long ptr_to_var;
  462.      };
  463. /*video pointer*/
  464. char far *vid_mem;
  465. /*variable declarations*/
  466. int len, text_ptr, debug, coff_debug, fake;
  467. unsigned char *file_buffer;
  468. /*function prototypes*/
  469. long getint(int, int);
  470. void load(struct sect_header *);
  471. void load_block(struct sect_header *);
  472. void put_data(struct sect_header *);
  473. void put_hstctl(unsigned int);
  474. unsigned int get_hstctl(void);
  475. void set_addr(unsigned long int);
  476. void gsp_poke(unsigned long int, unsigned long int);
  477. unsigned int gsp_peek(unsigned long int);
  478. void get_sect(int);
  479.   
  480.  
  481.