/* return the size or -1 if error */intget_image_size(constchar*filename){intfd,size;fd=open(filename,O_RDONLY|O_BINARY);if(fd<0)return-1;size=lseek(fd,0,SEEK_END);close(fd);returnsize;}/* return the size or -1 if error */
/* return the amount read, just like fread. 0 may mean error or eof */intfread_targphys(target_phys_addr_tdst_addr,size_tnbytes,FILE*f){uint8_tbuf[4096];target_phys_addr_tdst_begin=dst_addr;size_twant,did;while(nbytes){want=nbytes>sizeof(buf)?sizeof(buf):nbytes;did=fread(buf,1,want,f);if(did!=want)break;cpu_physical_memory_write_rom(dst_addr,buf,did);dst_addr+=did;nbytes-=did;}returndst_addr-dst_begin;}/* returns 0 on error, 1 if ok */intfread_targphys_ok(target_phys_addr_tdst_addr,size_tnbytes,FILE*f){returnfread_targphys(dst_addr,nbytes,f)==nbytes;}/* read()-like version */intread_targphys(intfd,target_phys_addr_tdst_addr,size_tnbytes){uint8_tbuf[4096];target_phys_addr_tdst_begin=dst_addr;size_twant,did;while(nbytes){want=nbytes>sizeof(buf)?sizeof(buf):nbytes;did=read(fd,buf,want);if(did!=want)break;cpu_physical_memory_write_rom(dst_addr,buf,did);dst_addr+=did;nbytes-=did;}returndst_addr-dst_begin;}/* return the size or -1 if error */intload_image_targphys(constchar*filename,target_phys_addr_taddr,intmax_sz){FILE*f;size_tgot;f=fopen(filename,"rb");if(!f)return-1;got=fread_targphys(addr,max_sz,f);if(ferror(f)){fclose(f);return-1;}fclose(f);returngot;}voidpstrcpy_targphys(target_phys_addr_tdest,intbuf_size,constchar*source){staticconstuint8_tnul_byte=0;constchar*nulp;if(buf_size<=0)return;nulp=memchr(source,0,buf_size);if(nulp){cpu_physical_memory_write_rom(dest,(uint8_t*)source,(nulp-source)+1);}else{cpu_physical_memory_write_rom(dest,(uint8_t*)source,buf_size-1);cpu_physical_memory_write_rom(dest,&nul_byte,1);}}
/* A.OUT loader */structexec{uint32_ta_info;/* Use macros N_MAGIC, etc for access */uint32_ta_text;/* length of text, in bytes */uint32_ta_data;/* length of data, in bytes */uint32_ta_bss;/* length of uninitialized data area, in bytes */uint32_ta_syms;/* length of symbol table data in file, in bytes */uint32_ta_entry;/* start address */uint32_ta_trsize;/* length of relocation info for text, in bytes */uint32_ta_drsize;/* length of relocation info for data, in bytes */};#ifdefBSWAP_NEEDEDstaticvoidbswap_ahdr(structexec*e){bswap32s(&e->a_info);bswap32s(&e->a_text);bswap32s(&e->a_data);bswap32s(&e->a_bss);bswap32s(&e->a_syms);bswap32s(&e->a_entry);bswap32s(&e->a_trsize);bswap32s(&e->a_drsize);}#else#definebswap_ahdr(x)do{}while(0)#endif#defineN_MAGIC(exec)((exec).a_info&0xffff)#defineOMAGIC0407#defineNMAGIC0410#defineZMAGIC0413#defineQMAGIC0314#define_N_HDROFF(x)(1024-sizeof(structexec))#defineN_TXTOFF(x)\(N_MAGIC(x)==ZMAGIC?_N_HDROFF((x))+sizeof(structexec):\(N_MAGIC(x)==QMAGIC?0:sizeof(structexec)))#defineN_TXTADDR(x)(N_MAGIC(x)==QMAGIC?TARGET_PAGE_SIZE:0)#defineN_DATOFF(x)(N_TXTOFF(x)+(x).a_text)#define_N_SEGMENT_ROUND(x)(((x)+TARGET_PAGE_SIZE-1)&~(TARGET_PAGE_SIZE-1))#define_N_TXTENDADDR(x)(N_TXTADDR(x)+(x).a_text)#defineN_DATADDR(x)\(N_MAGIC(x)==OMAGIC?(_N_TXTENDADDR(x))\:(_N_SEGMENT_ROUND(_N_TXTENDADDR(x))))