home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
drdobbs
/
1991
/
07
/
coff.asc
< prev
next >
Wrap
Text File
|
1991-06-11
|
15KB
|
481 lines
_A COFF FILE LOADER FOR THE 34010_
by Don Morgan
[LISTING ONE]
#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <io.h>
#include <conio.h>
#include <string.h>
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include "coff.h"
struct main_header *m_hdr;
struct opt_header *opt;
struct sect_header section;
void main(int argc, char **argv)
{
/**************** PART A *****************/
int module, size, header, sect, j;
unsigned long result;
int bss_done = FALSE;
unsigned char *receive_buffer;
char tmp_buf[100];
int data, i;
if(argc != 2) {
printf("\nno file given!");
exit(-1);
}
module = open(argv[1], O_BINARY|O_RDONLY);
if(module == -1){
perror("\nopen failed!");
exit(-1);
}
/**************************/
/*read coff file into buffer*/
size = filelength(module);
file_buffer = (char *)malloc(size);
if(file_buffer == NULL) {
perror("\nnot enough memory!");
exit (-1);
}
if((result = (long)read(module, file_buffer, size)) <= 0) {
perror("\ncan't find file!\n");
exit(-1);
}
close(module);
/************ PART B *************/
/*set up 34010 for loading*/
/**************************/
/*it is the users responsibility to set up the cntrl register*/
/*please note that some of the register settings, such as the following*/
/*are application dependent, this code is included only to show an*/
/*example of low level setup for the 34010*/
gsp_poke(cntrl, 0x4); /*sets cas before ras refresh*/
/**************************/
/*set up 34010 to restart correctly after loading program*/
put_hstctl(hlt | cf | incr | incw | nmim | nmi_flg);
data = get_hstctl();
if(data != (hlt | cf | incr | incw | nmim | nmi_flg)) {
printf("\nerror writing to hstctl!");
exit(-1);
}
/************ PART C *************/
/**************************/
/*get contents of main header*/
m_hdr = (struct main_header *) file_buffer;
/*see if the file has a magic number*/
if(m_hdr->magic_num !=FILE_MAGIC) {
printf("\nnot a standard coff .out file!");
exit(-1);
}
/*check to see whether there is an optional header*/
if((m_hdr->opt_head != OPT_XST)){
printf("file is not fully linked!");
exit(-1);
}
/*get contents of optional header*/
opt = (struct opt_header *) &file_buffer[OPT_OFST];
/*see if the optional header has a magic number*/
if(opt->magic_num !=OPT_MAGIC) {
printf("\nnon standard file!");
exit(-1);
}
/*************************************************/
/*begin searching for and loading section headers find bss section first! */
i = FIRST_HDR;
for (j=0;((j<m_hdr->num_sects) && !bss_done) ;j++){
strcpy(tmp_buf,&file_buffer[i]);
if(!bss_done) {
if(!(strcmp(tmp_buf, ".bss"))) {
strcpy(section.name, tmp_buf);
header = i;
get_sect(header);
bss_done = TRUE;
}
}
i += SEC_OFST;
}
/*now load the other sections*/
i = FIRST_HDR;
for (j=0; j<m_hdr->num_sects;j++){
strcpy(tmp_buf,&file_buffer[i]);
if(strcmp(tmp_buf, ".bss")) {
strcpy(section.name, tmp_buf);
header = i;
get_sect(header);
}
i += SEC_OFST;
}
/*release memory for file buffer*/
free(file_buffer);
/************ PART D *************/
/*set up reset and interrupt vectors for the 34010 */
/*usually, both the nmi and halt bits are set and then released */
/*this code may differ depending upon the desires of the programmer */
gsp_poke(intenb,0x0); /*no interrupts*/
gsp_poke(nmi_vect, opt->entry_point);
gsp_poke(nmi_vect+0x10, opt->entry_point >> 0x10);
gsp_poke(reset,opt->entry_point);
gsp_poke(reset+0x10,opt->entry_point >> 0x10);
put_hstctl(hlt | incr | nmi_flg | incw | nmim);
/*toggle the halt bit and go*/
data = get_hstctl();
data &= ~hlt;
put_hstctl( data );
}
/*********** PART E *************/
void get_sect(header)
int header;
{
struct sect_header * ptr = (struct sect_header *)&file_buffer[header];
load(ptr);
}
void load(ptr)
struct sect_header *ptr;
{
/*here the flags are checked to determine whether the section is to be loaded or copied or ignored*/
if((ptr->sect_size) && !(ptr->flags & STYP_DSECT) &&
!(ptr->flags & STYP_NOLOAD)) {
if(!(strcmp(ptr->name,".cinit"))
&& (ptr->flags & STYP_COPY))
put_data(ptr);
else
if(((ptr->flags & STYP_TEXT)
|| (ptr->flags & STYP_DATA)
|| (!(strcmp(ptr->name,".cinit")
&& !(ptr->flags & STYP_COPY)))))
load_block(ptr);
}
}
void load_block(ptr)
struct sect_header *ptr;
{
int data, temporary, hldr, limit;
long i, j, file_pointer;
file_pointer = ptr->raw_data;
/*set the host interface up to point at the correct address*/
#if MM
*(gsp:>hstadrl) = ptr->virt_addr;
*(gsp:>hstadrh) = ptr->virt_addr >> 0x10;
#else
outpw(io_hstadrl, (unsigned int)ptr->virt_addr);
outpw(io_hstadrh, (unsigned int)ptr->virt_addr >> 0x10);
#endif
limit = (ptr->sect_size/0x10)-1;
j=0;
/*write each word to host interface*/
for(i=0; i<=limit; i++){
/*get the data from the file buffer and get it in the correct order before writing to the host interface*/
data = (file_buffer[file_pointer+j++]&0xff);
data += ((file_buffer[file_pointer+j++]&0xff)*0x100);
#if MM
*(gsp:>hstdata) = data;
#else
outpw(io_hstdata,data);
#endif
}
/*compare data*/
/*point at the correct address*/
#if MM
*(gsp:>hstadrl) = ptr->virt_addr;
*(gsp:>hstadrh) = ptr->virt_addr >> 0x10;
#else
outpw(io_hstadrl, (unsigned int)ptr->virt_addr);
outpw(io_hstadrh, (unsigned int)ptr->virt_addr>> 0x10);
#endif
limit = (ptr->sect_size/0x10)-1;
j=0;
for(i=0; i<=limit; i++){
/*get the data*/
data = (file_buffer[file_pointer+j++]&0xff);
data += ((file_buffer[file_pointer+j++]&0xff)*0x100);
#if MM
hldr = *(gsp:>hstdata);
#else
hldr = inpw(io_hstdata);
#endif
if(hldr != data)
printf("\ncompare error!");
}
}
void put_data(ptr)
struct sect_header *ptr;
{
int data, temporary, hldr, limit, num_words, num;
long i, j, reloc_address, file_pointer;
struct init_table * init;
file_pointer = ptr->raw_data;
do{
init = (struct init_table *)&file_buffer[file_pointer];
reloc_address = init->ptr_to_var;
file_pointer += 6;
/*point at relocation address*/
#if MM
*(gsp:>hstadrl) = reloc_address;
*(gsp:>hstadrh) = reloc_address >> 0x10;
#else
outpw(io_hstadrl, (unsigned int)reloc_address);
outpw(io_hstadrh, (unsigned int)reloc_address >> 0x10);
#endif
/*determine the amount of data to transfer and do it*/
num_words = init->num_words;
limit = --num_words;
j=0;
for(i=0; i<=limit; i++){
data = (file_buffer[file_pointer+j++]&0xff);
data += ((file_buffer[file_pointer+j++]&0xff)*0x100);
#if MM
*(gsp:>hstdata) = data;
#else
outpw(io_hstdata,data);
#endif
}
/*now, do a data compare*/
#if MM
*(gsp:>hstadrl) = reloc_address;
*(gsp:>hstadrh) = reloc_address >> 0x10;
#else
outpw(io_hstadrl, (unsigned int)reloc_address);
outpw(io_hstadrh, (unsigned int)reloc_address >> 0x10);
#endif
num_words = init->num_words;
limit = --num_words;
j=0;
for(i=0; i<=limit; i++){
data = (file_buffer[file_pointer+j++]&0xff);
data += ((file_buffer[file_pointer+j++]&0xff)*0x100);
#if MM
hldr = *(gsp:>hstdata);
#else
hldr = inpw(io_hstdata);
#endif
if(hldr != data)
printf("\ndata compare error!");
}
file_pointer += j;
}while(((int)file_buffer[file_pointer]) != 0x0);
}
/*set up the hstctl*/
void put_hstctl(unsigned int value)
{
#if MM
*(gsp:>hstctl) = value;
#else
outpw(io_hstctl,value);
#endif
}
/*get current Hstclt setting*/
unsigned int get_hstctl()
{
int value;
#if MM
value = *(gsp:>hstctl);
#else
value = inpw(io_hstctl);
#endif
return value;
}
/*set host interface to point at correct address*/
void set_addr(unsigned long address)
{
#if MM
*(gsp:>hstadrl) = address;
*(gsp:>hstadrh) = address >> 0x10;
#else
outpw(io_hstadrl,(unsigned int)address);
outpw(io_hstadrh,(unsigned int)address >> 0x10);
#endif
}
void gsp_poke(unsigned long address, unsigned long value)
{
set_addr(address);
#if MM
*(gsp:>hstdata) = value;
#else
outpw(io_hstdata,(unsigned int)value);
#endif
}
unsigned int gsp_peek(unsigned long address)
{
int value;
set_addr(address);
#if MM
value = *(gsp:>hstdata);
#else
value = inpw(io_hstdata);
#endif
return value;
}
[LISTING TWO]
#define FALSE 0
#define TRUE 0x1
#define MM TRUE
/*physical addresses of memory mapped host interface*/
#if MM
_segment gsp = 0xc700;
int _based(void) *hstctl = (int _based(void)*)0xe00;
int _based(void) *hstdata = (int _based(void)*)0xf00;
int _based(void) *hstadrh = (int _based(void)*)0xc00;
int _based(void) *hstadrl = (int _based(void)*)0xd00;
#else
/*io mapped addresses of host interface*/
io_hstctl = 0;
io_hstdata = 0;
io_hstadrh = 0;
io_hstadrl = 0;
#endif
#define FILE_MAGIC 0x90
#define OPT_MAGIC 0x108
#define OPT_XST 0x1c
#define OPT_OFST 0x14
#define SEC_OFST 0x28
#define FIRST_HDR 0x30
#define cf 0x4000
#define hlt 0x8000
#define nmi_flg 0x100
#define nmim 0x200
#define incw 0x800
#define incr 0x1000
/*definitions*/
/*file header flags*/
#define F_RELFLG 0x1 /*relocation information stripped*/
#define F_EXEC 0x2 /*file is relocateable*/
#define F_LNNO 0x4 /*line numbers stripped*/
#define F_LSYMS 0x10 /*local symbos stripped*/
#define F_QR32WR 0x40 /*34010 byte ordering*/
/*section header flags*/
#define STYP_REG 0x0 /*regular section*/
#define STYP_DSECT 0x1 /*dummy section*/
#define STYP_NOLOAD 0x2 /*noload section*/
#define STYP_GROUP 0x4 /*grouped section*/
#define STYP_PAD 0x8 /*padding section*/
#define STYP_COPY 0x10 /*copy section, important for .cinit*/
#define STYP_TEXT 0x20 /*executable code*/
#define STYP_DATA 0x40 /*initialized data*/
#define STYP_BSS 0x80 /*uninitialized data*/
#define STYP_ALIGN 0x100 /*aligned on cache boundary*/
/*******************************************************/
/*interrupt vector:*/
#define reset 0xffffffe0
#define nmi_vect 0xfffffee0
/*******************************************************/
/*i/o registers:*/
#define refcnt 0xc00001f0
#define dpyadr 0xc00001e0
#define vcount 0xc00001d0
#define hcount 0xc00001c0
#define dpytap 0xc00001b0
#define pmask 0xc0000160
#define psize 0xc0000150
#define convdp 0xc0000140
#define convsp 0xc0000130
#define intpend 0xc0000120
#define intenb 0xc0000110
#define hstctlh 0xc0000100
#define hstctll 0xc00000f0
#define hst_adrh 0xc00000d0
#define hst_adrl 0xc00000e0
#define hst_data 0xc00000c0
#define cntrl 0xc00000b0
#define dpyint 0xc00000a0
#define dpystrt 0xc0000090
#define dpyctl 0xc0000080
#define vtotal 0xc0000070
#define vsblnk 0xc0000060
#define veblnk 0xc0000050
#define vesync 0xc0000040
#define htotal 0xc0000030
#define hsblnk 0xc0000020
#define heblnk 0xc0000010
#define hesync 0xc0000000
#define dac_wr 0xc7800
#define ppl_rd 0xc7000
/*header structures*/
struct main_header {
unsigned short int magic_num;
unsigned short int num_sects;
long int date_stamp;
long int sym_table;
long int entries;
unsigned short int opt_head;
unsigned short int flags;
};
struct opt_header {
short int magic_num;
short int version;
unsigned long code_size;
unsigned long init_size;
unsigned long uninit_size;
unsigned long entry_point;
unsigned long start_text;
unsigned long start_data;
};
struct sect_header {
unsigned char name[8];
unsigned long phys_addr;
unsigned long virt_addr;
unsigned long sect_size;
unsigned long raw_data;
unsigned long reloc;
unsigned long num_entries;
unsigned short int reloc_entries;
unsigned short int line_entries;
unsigned short int flags;
unsigned char ch1;
unsigned char page;
};
struct init_table {
int num_words;
long ptr_to_var;
};
/*video pointer*/
char far *vid_mem;
/*variable declarations*/
int len, text_ptr, debug, coff_debug, fake;
unsigned char *file_buffer;
/*function prototypes*/
long getint(int, int);
void load(struct sect_header *);
void load_block(struct sect_header *);
void put_data(struct sect_header *);
void put_hstctl(unsigned int);
unsigned int get_hstctl(void);
void set_addr(unsigned long int);
void gsp_poke(unsigned long int, unsigned long int);
unsigned int gsp_peek(unsigned long int);
void get_sect(int);