diff options
author | Robert de Bath <rdebath@poboxes.com> | 1998-02-01 11:26:21 +0100 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2013-10-23 23:40:14 +0200 |
commit | 48f0b3eb836162d41622cedc1eb5f5168168fb8e (patch) | |
tree | c53156383d4682a0a296f6611575dbc1d64d1881 /bootblocks | |
parent | 48798bf2eb93ec3b99720ac2e16093441156653d (diff) | |
download | dev86-48f0b3eb836162d41622cedc1eb5f5168168fb8e.tar.gz |
Import Dev86src-0.13.5.tar.gzv0.13.5
Diffstat (limited to 'bootblocks')
-rw-r--r-- | bootblocks/Makefile | 14 | ||||
-rw-r--r-- | bootblocks/bzimage.c | 197 | ||||
-rw-r--r-- | bootblocks/fs.c | 81 | ||||
-rw-r--r-- | bootblocks/fs_dos.c (renamed from bootblocks/dosfs.c) | 291 | ||||
-rw-r--r-- | bootblocks/fs_min.c | 31 | ||||
-rw-r--r-- | bootblocks/fs_tar.c | 156 | ||||
-rw-r--r-- | bootblocks/i86_funcs.c | 1 | ||||
-rw-r--r-- | bootblocks/makeboot.c | 348 | ||||
-rw-r--r-- | bootblocks/mbr.s | 5 | ||||
-rw-r--r-- | bootblocks/monitor.c | 85 | ||||
-rw-r--r-- | bootblocks/msdos.s | 48 | ||||
-rw-r--r-- | bootblocks/nofs.c | 55 | ||||
-rw-r--r-- | bootblocks/readfs.h | 27 | ||||
-rw-r--r-- | bootblocks/relocate.c | 27 | ||||
-rw-r--r-- | bootblocks/standalone.c | 1 | ||||
-rw-r--r-- | bootblocks/sysboot.s | 4 | ||||
-rw-r--r-- | bootblocks/tarboot.s | 4 | ||||
-rw-r--r-- | bootblocks/trk_buf.c | 275 | ||||
-rw-r--r-- | bootblocks/unix.c | 137 |
19 files changed, 1446 insertions, 341 deletions
diff --git a/bootblocks/Makefile b/bootblocks/Makefile index 3f572be..f01c725 100644 --- a/bootblocks/Makefile +++ b/bootblocks/Makefile @@ -22,10 +22,14 @@ SSRC=sysboot.s \ encap: $(SSRC:s=v) $(CSRC:c=v) minixhd.v bin: $(SSRC:s=bin) $(CSRC:c=bin) minixhd.bin -MOBJ=monitor.o i86_funcs.o relocate.o help.o bzimage.o dosfs.o nofs.o -MSRC=monitor.c i86_funcs.c relocate.c help.c bzimage.c dosfs.c nofs.c +MOBJ=monitor.o i86_funcs.o relocate.o help.o bzimage.o trk_buf.o unix.o \ + fs.o fs_tar.o fs_min.o fs_dos.o +MSRC=monitor.c i86_funcs.c relocate.c help.c bzimage.c trk_buf.c unix.c \ + fs.c fs_tar.c fs_min.c fs_dos.c MINC=i86_funcs.h readfs.h +BOOTBLOCKS=sysboot.v noboot.v skip.v msdos.v tarboot.v minix.v minixhd.v + EXTRAS=minix.h elf_info.c elf_info.h standalone.c li86.s install: @@ -37,7 +41,7 @@ $(MOBJ): $(MINC) version.h monitor: $(MSRC) $(MINC) @rm -f $(MOBJ) - make 'CFLAGS=-ansi' monitor.out + make 'CFLAGS=-ansi -H0x8000' monitor.out mv monitor.out monitor @rm -f $(MOBJ) @@ -47,10 +51,10 @@ minix.s: minix.c minixhd.s: minix.c $(BCC) -Mf -DDOTS -DHARDDISK $(MDEFS) -S minix.c -o minixhd.s -makeboot: makeboot.c sysboot.v noboot.v skip.v msdos.v tarboot.v +makeboot: makeboot.c $(BOOTBLOCKS) $(HOSTCC) $(HOSTCCFLAGS) -o makeboot makeboot.c -makeboot.com: makeboot.c sysboot.v noboot.v skip.v msdos.v tarboot.v +makeboot.com: makeboot.c $(BOOTBLOCKS) $(BCC) -Md -o makeboot.com makeboot.c version.h: diff --git a/bootblocks/bzimage.c b/bootblocks/bzimage.c index 2e7c835..baf027b 100644 --- a/bootblocks/bzimage.c +++ b/bootblocks/bzimage.c @@ -4,6 +4,7 @@ */ #include <stdio.h> +#include <dos.h> #include "i86_funcs.h" #include "readfs.h" @@ -13,9 +14,18 @@ char * append_line = 0; /* A preset append line value */ static char * initrd_name = 0; /* Name of init_ramdisk to load */ static int vga_mode = -1; /* SVGA_MODE = normal */ +static int is_zimage = 0; +static int image_length; /* Length of image in sectors */ +static long image_size; /* Length of image file in bytes */ + static char * read_cmdfile(); static char * input_cmd(); +#define ZIMAGE_LOAD_SEG 0x1000 /* Segment that zImage data is loaded */ +#define COMMAND_LINE_POS 0x4000 /* Offset in segment 0x9000 of command line */ + +int has_command_line = 0; + cmd_bzimage(ptr) char * ptr; { @@ -58,12 +68,13 @@ char * command_line; printf("Loading %s\n", fname); - if( read_block(buffer) < 0 || check_magics(buffer) < 0 ) + if( read_block(buffer) < 0 || check_magics(fname, buffer) < 0 ) { - printf("File %s isn't a bzImage.\n", fname); + printf("Cannot execute file %s\n", fname); return -1; } +#ifndef __ELKS__ if( boot_mem_top < 0x9500 ) { printf("There must be 640k of boot memory to load Linux\n"); @@ -74,7 +85,7 @@ char * command_line; * I expect we could lookup the size in the gzip header but * this is probably close enough (3*the size of the bzimage) */ - len = file_length() * 3 / 1024; + len = (image_size=file_length()) * 3 / 1024; if( main_mem_top < len ) { printf("This kernel needs at least %ld.%ldM of main memory\n", @@ -83,12 +94,29 @@ char * command_line; } if( main_mem_top < 3072 ) printf("RTFM warning: Linux really needs at least 4MB of memory.\n"); +#endif - low_sects = buffer[497] + 1; /* setup sects + boot sector */ + low_sects = buffer[497] + 1; /* setup sects + boot sector */ + image_length = (file_length()+511)/512 - low_sects; address = 0x900; +#ifndef __ELKS__ + if( is_zimage ) + { + relocator(8); /* Need space in low memory */ + + if( image_length > (__get_cs()>>5) - ZIMAGE_LOAD_SEG/32 ) + { + printf("This zImage file is too large, maximum is %ld bytes\n", + ((__get_cs()>>5) - ZIMAGE_LOAD_SEG/32 + low_sects)*512L ); + return -1; + } + } +#endif + /* load the blocks */ rewind_file(); + reset_crc(); for(len = file_length(); len>0; len-=1024) { int v; @@ -109,6 +137,7 @@ char * command_line; return -1; } + if( len > 1024 ) addcrc(buffer, 1024); else addcrc(buffer, (int)len); for(v=0; v<1024; v+=512) { if( putsect(buffer+v, address) < 0 ) @@ -119,10 +148,15 @@ char * command_line; if( low_sects ) { low_sects--; - if( low_sects == 0 ) address = 0x1000; + if( low_sects == 0 ) + { + if( is_zimage ) address = ZIMAGE_LOAD_SEG/16; + else address = 0x1000; + } } } } + display_crc(); /* Yesss, loaded! */ printf("Loaded, "); fflush(stdout); @@ -135,6 +169,14 @@ char * command_line; if( load_initrd(address) < 0 ) return -1; + check_crc(); + + if( is_zimage ) + { + printf("Sorry, zImage's don't seem to be working at the moment.\n"); + if( !keep_going() ) return -1; + } + printf("Starting ...\n"); if( x86 < 3 ) @@ -156,9 +198,39 @@ char * command_line; if( !keep_going() ) return -1; } - /* Patch setup to deactivate safety switch */ +#ifdef __ELKS__ + printf("Cannot start.\n"); + return -1; +#endif + __set_es(0x9000); - __poke_es(0x210, 0xFF); + + /* Save pointer to command line */ + if( has_command_line ) + { + __doke_es(0x0020, 0xA33F); + __doke_es(0x0022, COMMAND_LINE_POS); + } + +#if ZIMAGE_LOAD_SEG != 0x1000 + if( is_zimage ) + { +#if ZIMAGE_LOAD_SEG != 0x100 + /* Tell setup that we've loaded the kernel somewhere */ + __poke_es(0x20C, ZIMAGE_LOAD_SEG); +#else + /* Tell setup it's a bzImage _even_ tho it's a _zImage_ because we have + * actually loaded it where it's supposed to end up! + */ + __poke_es(0x211, __peek_es(0x211)|1); + + __poke_es(0x210, 0xFF); /* Patch setup to deactivate safety switch */ +#endif + } +#endif + + if( !is_zimage ) + __poke_es(0x210, 0xFF); /* Patch setup to deactivate safety switch */ /* Set SVGA_MODE if not 'normal' */ if( vga_mode != -1 ) __doke_es(506, vga_mode); @@ -178,6 +250,8 @@ char * command_line; mov ax,$9000 mov bx,$4000-12 ! Fix this to use boot_mem_top mov es,ax + mov fs,ax + mov gs,ax mov ds,ax mov ss,ax mov sp,bx @@ -186,51 +260,63 @@ char * command_line; } } -check_magics(buffer) +check_magics(fname, buffer) +char * fname; char * buffer; { + is_zimage = 0; + /* Boot sector magic number */ - if( *(unsigned short*)(buffer+510) != 0xAA55 ) return -1; + if( *(unsigned short*)(buffer+510) != 0xAA55 || /* Setup start */ - if( memcmp(buffer+0x202, "HdrS", 4) != 0 ) return -1; + memcmp(buffer+0x202, "HdrS", 4) != 0 || /* Setup version */ - if( *(unsigned short*)(buffer+0x206) < 0x200 ) return -1; - - /* Check load flags for bzImage */ - if( (buffer[0x211] & 1) == 0 ) return -1; + *(unsigned short*)(buffer+0x206) < 0x200 ) + { + printf("File %s is not a linux Image file\n", fname); + return -1; + } - /* Code 32 start address */ - if( *(unsigned long*)(buffer+0x214) != 0x100000 ) return -1; + /* Code 32 start address for zImage */ + if( *(unsigned long*)(buffer+0x214) == 0x1000 ) + { + printf("File %s is a zImage file\n", fname); + is_zimage = 1; + return 0; + } + else + /* Code 32 start address bzImage */ + if( *(unsigned long*)(buffer+0x214) != 0x100000 ) + { + printf("File %s is not a bzImage file\n", fname); + return -1; + } + printf("File %s is a bzImage file\n", fname); return 0; } +#ifndef __ELKS__ putsect(buffer, address) char * buffer; unsigned int address; { int rv, tc=3; + /* In real mode memory, just put it directly */ + if( address < 0xA00 ) + { + __movedata(__get_ds(), buffer, address*16, 0, 512); + return 0; + } + retry: tc--; #if 1 if( x86_emu ) - { -static unsigned int last_address = 0; - if( address <= last_address ) - printf("Problem %d<=%d\n", address, last_address); - if( address < 0xA00 ) - { - int i; - __set_es(address*16); - for(i=0; i<512; i++) - __poke_es(i, buffer[i]); - } - else - printf("In EMU can't write to 0x%x\n", address); - return 0; - } + return 0; /* In an EMU we can't write to high mem but + we'll pretend we can for debuggering */ #endif if( (rv=ext_put(buffer, address, 512)) != 0 ) { @@ -261,6 +347,7 @@ static unsigned int last_address = 0; } return 0; } +#endif static char * read_cmdfile(iname, extno) @@ -353,6 +440,8 @@ static char * image_str = "BOOT_IMAGE="; char * free_app = 0; char * free_dfl = 0; + has_command_line = 0; + if( append == 0 ) append = free_app = read_cmdfile(image, 2); @@ -447,11 +536,18 @@ static char * image_str = "BOOT_IMAGE="; len = 2048; } +#ifdef __ELKS__ + fprintf(stderr, "Command line: '%s'\n", ptr+1); +#else +/* __set_es(0x9000); __doke_es(0x0020, 0xA33F); - __doke_es(0x0022, 0x4000); + __doke_es(0x0022, COMMAND_LINE_POS); +*/ - __movedata(__get_ds(), (unsigned)ptr+1, 0x9000, 0x4000, len); + __movedata(__get_ds(), (unsigned)ptr+1, 0x9000, COMMAND_LINE_POS, len); + has_command_line = 1; +#endif free(ptr); @@ -555,3 +651,38 @@ unsigned int k_top; return 0; } + +check_crc() +{ + char buffer[512]; + int low_sects; + unsigned int address = 0x900; + long len; + + if( !is_zimage ) return; + + reset_crc(); + + __movedata(address*16, 0, __get_ds(), buffer, 512); + low_sects = buffer[497] + 1; /* setup sects + boot sector */ + + for(len=image_size; len>0; len-=512) + { + if( address >= 0xA00 ) return; + __movedata(address*16, 0, __get_ds(), buffer, 512); + + if( len > 512 ) addcrc(buffer, 512); else addcrc(buffer, (int)len); + + address += 2; + if( low_sects ) + { + low_sects--; + if( low_sects == 0 ) + { + if( is_zimage ) address = ZIMAGE_LOAD_SEG/16; + else address = 0x1000; + } + } + } + display_crc(); +} diff --git a/bootblocks/fs.c b/bootblocks/fs.c new file mode 100644 index 0000000..64a3783 --- /dev/null +++ b/bootblocks/fs.c @@ -0,0 +1,81 @@ + +#ifdef __ELKS__ +#include <stdio.h> +#endif +#include "readfs.h" + +int fs_type = 0; + +open_file(fname) +char * fname; +{ +#ifdef __ELKS__ + fprintf(stderr, "Open file %s\n", fname); +#endif + if( fs_type ) close_file(); + + if( tar_open_file(fname) >= 0 ) { fs_type = 1; return 0; } + if( min_open_file(fname) >= 0 ) { fs_type = 2; return 0; } + if( dos_open_file(fname) >= 0 ) { fs_type = 3; return 0; } + return -1; +} + +rewind_file() +{ +#ifdef __ELKS__ + fprintf(stderr, "Rewind file (%d)\n", fs_type); +#endif + switch(fs_type) + { + case 1: return tar_rewind_file(); + case 2: return min_rewind_file(); + case 3: return dos_rewind_file(); + } + return -1; +} + +close_file() +{ + int rv; +#ifdef __ELKS__ + fprintf(stderr, "Close file (%d)\n", fs_type); +#endif + switch(fs_type) + { + case 1: rv = tar_close_file(); break; + case 2: rv = min_close_file(); break; + case 3: rv = dos_close_file(); break; + } + fs_type = 0; + return -1; +} + +long +file_length() +{ +#ifdef __ELKS__ + fprintf(stderr, "File length (%d)\n", fs_type); +#endif + switch(fs_type) + { + case 1: return tar_file_length(); + case 2: return min_file_length(); + case 3: return dos_file_length(); + } + return -1; +} + +read_block(buffer) +char * buffer; +{ +#ifdef __ELKS__ + fprintf(stderr, "read block into (%d) (%d)\n", buffer, fs_type); +#endif + switch(fs_type) + { + case 1: return tar_read_block(buffer); + case 2: return min_read_block(buffer); + case 3: return dos_read_block(buffer); + } + return -1; +} diff --git a/bootblocks/dosfs.c b/bootblocks/fs_dos.c index b9a2c04..d2ca5eb 100644 --- a/bootblocks/dosfs.c +++ b/bootblocks/fs_dos.c @@ -1,10 +1,11 @@ -#ifdef __STANDALONE__ - +#include <stdio.h> #include <ctype.h> #include <malloc.h> #include "readfs.h" +#define DONT_BUFFER_FAT + #define DOS_SECT(P) get_uint(P,0x0B) #define DOS_CLUST(P) get_byte(P,0x0D) #define DOS_RESV(P) get_uint(P,0x0E) @@ -25,23 +26,16 @@ #define get_uint(P,Off) *((unsigned short*)((char*)(P)+(Off))) #define get_long(P,Off) *((long*)((char*)(P)+(Off))) -static int alloc_trackbuf(); -static char * read_sector(); static int read_bootblock(); - -int disk_drive = 0; - -static int track_number = -1; -static char * track_buffer = 0; -static int track_len = 0; -static int disk_spt = -1; -static int disk_heads = 2; - static int dir_nentry, dir_sect; -static int dos_clust0, dos_spc; +static int dos_clust0, dos_spc, dos_fatpos; +static int last_serial = 0; +#ifdef BUFFER_FAT static char * fat_buf = 0; +#endif +static struct filestatus { char fname[12]; unsigned short first_cluster; @@ -51,7 +45,7 @@ struct filestatus { } cur_file = { "", 0, 0, 0 }; -open_file(fname) +dos_open_file(fname) char * fname; { extern union REGS __argr; @@ -60,7 +54,11 @@ char * fname; int i; int dodir = 0; - if(strcmp(fname, ".") == 0) dodir = 1; + /* Get the superblock */ + if( read_bootblock() < 0 ) return -1; + + if(strcmp(fname, ".") == 0) + dodir = 1; else { /* Convert the name to MSDOS directory format */ @@ -83,22 +81,13 @@ char * fname; /* Already opened ? Then just rewind it */ if( cur_file.first_cluster && strcmp(cur_file.fname, conv_name) == 0 ) - return rewind_file(); + return dos_rewind_file(); } memset(&cur_file, '\0', sizeof(cur_file)); - /* Get the superblock */ +#ifdef BUFFER_FAT s = read_sector(0); - if( s == 0 ) return -1; - - /* Collect important data */ - dir_sect = DOS_RESV(s) + DOS_NFAT(s)*DOS_FATLEN(s); - dir_nentry = DOS_NROOT(s); - - dos_spc = DOS_CLUST(s); - if( dos_spc < 1 ) dos_spc = 1; - dos_clust0 = dir_sect + (dir_nentry+15)/16 - 2*dos_spc; if( !dodir ) { @@ -119,6 +108,7 @@ char * fname; } } } +#endif /* Scan the root directory for the file */ for(i=0; i<dir_nentry; i++) @@ -129,6 +119,9 @@ char * fname; if( dodir ) { char dtime[20]; + char lbuf[90]; + *lbuf = 0; + sprintf(dtime, " %02d/%02d/%04d %02d:%02d", (get_uint(d,24)&0x1F), ((get_uint(d,24)>>5)&0xF), @@ -149,6 +142,7 @@ char * fname; printf("%-11.11s <LBL> %s\n", d, dtime); break; } + if( more_strn(lbuf, sizeof(lbuf)) < 0 ) break; } else if( memcmp(d, conv_name, 11) == 0 && (d[11]&0x18) == 0 ) { /* Name matches and is normal file */ @@ -159,6 +153,12 @@ char * fname; cur_file.cur_cluster = cur_file.first_cluster; cur_file.sector_no = 0; +#ifdef __ELKS__ + fprintf(stderr, "Opened first cluster %d, len %ld\n", + cur_file.first_cluster, + cur_file.file_length + ); +#endif return 0; } @@ -166,7 +166,7 @@ char * fname; return -1; } -rewind_file() +dos_rewind_file() { /* Is there an opened file ? */ if( cur_file.fname[0] == 0 ) return -1; @@ -176,22 +176,20 @@ rewind_file() return 0; } -close_file() +dos_close_file() { +#ifdef BUFFER_FAT if( fat_buf ) free(fat_buf); - if( track_buffer ) free(track_buffer); - memset(&cur_file, '\0', sizeof(cur_file)); fat_buf = 0; - track_buffer = 0; - track_len = 0; - track_number = -1; - disk_spt = -1; - disk_heads = 2; +#endif + memset(&cur_file, '\0', sizeof(cur_file)); + + reset_disk(); return 0; } long -file_length() +dos_file_length() { /* Is there an opened file ? */ if( cur_file.fname[0] == 0 ) return -1; @@ -199,17 +197,30 @@ file_length() return cur_file.file_length; } -read_block(buffer) +dos_read_block(buffer) char * buffer; { int s; char * ptr; /* Is there an opened file ? */ - if( cur_file.fname[0] == 0 ) return -1; + if( cur_file.fname[0] == 0 ) + { +#ifdef __ELKS__ + fprintf(stderr, "File is not currently open!\n"); +#endif + return -1; + } /* Are we before the EOF ? NB: FAT12 ONLY! */ - if( cur_file.cur_cluster >= 0xFF0 || cur_file.cur_cluster < 2 ) return -1; + if( cur_file.cur_cluster >= 0xFF0 || cur_file.cur_cluster < 2 ) + { +#ifdef __ELKS__ + fprintf(stderr, "Hit end of file; cluster 0x%03x\n", + cur_file.cur_cluster); +#endif + return -1; + } for(s=0; s<2; s++) { @@ -234,16 +245,30 @@ char * buffer; if( cur_file.sector_no % dos_spc == 0 ) { int odd = (cur_file.cur_cluster&1); - unsigned int val; + unsigned int val, val2; val = cur_file.cur_cluster + (cur_file.cur_cluster>>1); - val = get_uint(fat_buf, val); +#ifdef BUFFER_FAT + val2 = get_uint(fat_buf, val); +#else + ptr = read_sector(dos_fatpos+(val/512)); + if( ptr == 0 ) return -1; + if( val%512 == 511 ) + { + val2 = (ptr[511]&0xFF); + ptr = read_sector(dos_fatpos+(val/512)+1); + if( ptr == 0 ) return -1; + val2 |= (ptr[0]<<8); + } + else + val2 = get_uint(ptr, (val%512)); +#endif - if( odd ) val>>=4; + if( odd ) val2>>=4; - val &= 0xFFF; + val2 &= 0xFFF; - cur_file.cur_cluster = val; + cur_file.cur_cluster = val2; } buffer += 512; @@ -252,167 +277,41 @@ char * buffer; return 0; } -static char * read_sector(sectno) -int sectno; -{ - int track_no, track_off, track_start, linsect; - if( disk_spt == -1 && read_bootblock() < 0 ) return 0; - - track_no = sectno / track_len; - track_off= sectno % track_len; - - if( track_no != track_number ) - { - track_number = -1; - track_start = track_no * track_len; - - for(linsect=0; linsect<track_len; linsect++) - { - if( raw_read(disk_drive, track_start+linsect, - track_buffer+linsect*512) <0 ) - return 0; - } - if( raw_read(disk_drive, 0, 0) <0 ) - return 0; - - track_number = track_no; - } - return track_buffer + 512*track_off; -} - -static int raw_read(drive, linsect, buffer) -int drive, linsect; -char * buffer; -{ -static char * pend_buf = 0, *buf_start = 0; -static int pend_s, pend_h, pend_c, pend_len = 0; - - int phy_s = linsect%disk_spt; - int phy_h = linsect/disk_spt%disk_heads; - int phy_c = linsect/disk_spt/disk_heads; - int tries = 5; - int rv = 0; - - if( buffer != pend_buf || - pend_s+pend_len != phy_s || - pend_h != phy_h || - pend_c != phy_c ) - { - if( buf_start ) do - { - rv = phy_read(drive, pend_c, pend_h, pend_s+1, pend_len, buf_start); - tries--; - if( rv ) printf("Error in phy_read(%d,%d,%d,%d,%d,%d);\n", - drive, pend_c, pend_h, pend_s+1, pend_len, buf_start); - } - while(rv && tries > 0); - - pend_c = phy_c; - pend_h = phy_h; - pend_s = phy_s; - pend_len = 0; - pend_buf = buf_start = buffer; - } - - pend_len++; - pend_buf += 512; - - return rv; -} - static int read_bootblock() { - char * sptr; - int rv, media_byte = 0; - if( alloc_trackbuf(2) ) return -1; - - disk_spt = 2; - sptr = read_sector(1); - disk_spt = -1; - if( sptr == 0 ) return -1; - media_byte = *(unsigned char*)sptr; - - /* Valid media byte ? */ - if( (media_byte & 0xF0) != 0xF0 ) return -1; - disk_spt = 2; - sptr = read_sector(0); - disk_spt = -1; - if( sptr == 0 ) return -1; - - if( DOS_MEDIA(sptr) != media_byte ) return -1; - if( DOS_SPT(sptr) > 63 ) return -1; - if( DOS_SECT(sptr) != 512 ) return -1; - - disk_spt = DOS_SPT(sptr); - disk_heads = DOS_HEADS(sptr); - - rv = alloc_trackbuf(disk_spt*disk_heads); /* Cylinder buffer */ - if( rv < 0 ) rv = alloc_trackbuf(disk_spt); /* Track buffer */ - if( rv < 0 ) rv = alloc_trackbuf(disk_spt/2); /* 1/2 Track buffer */ - if( rv < 0 ) rv = alloc_trackbuf(2); /* Block buffer */ - if( rv < 0 ) disk_spt = -1; - return rv; -} + char * sptr; + int rv, media_byte = 0; -static int alloc_trackbuf(sectors) -int sectors; -{ - char * new_track; - int seg_start, seg_end; - if( sectors <= track_len ) return 0; + sptr = read_sector(1); + if( sptr == 0 ) return -1; + media_byte = *(unsigned char*)sptr; + + /* Valid media byte ? */ + if( (media_byte & 0xF0) != 0xF0 ) return -1; + sptr = read_sector(0); + if( sptr == 0 ) return -1; - if( track_buffer ) free(track_buffer); - track_buffer = 0; - track_len = 0; - track_number = -1; + if( DOS_MEDIA(sptr) != media_byte ) return -1; + if( DOS_SPT(sptr) > 63 ) return -1; + if( DOS_SECT(sptr) != 512 ) return -1; - if( sectors < 1 || sectors > 63 ) /* WTF! */ return -1; + if( last_serial != DOS4_SERIAL(sptr) ) dos_close_file(); + last_serial = DOS4_SERIAL(sptr); - new_track = malloc(sectors*512); - if( new_track == 0 ) return -1; + /* Collect important data */ + dir_sect = DOS_RESV(sptr) + DOS_NFAT(sptr)*DOS_FATLEN(sptr); + dir_nentry = DOS_NROOT(sptr); - seg_start = __get_ds() + (unsigned int)new_track / 16; - seg_end = __get_ds() + (unsigned int)(new_track+sectors*512-1) / 16; + dos_fatpos = DOS_RESV(sptr); + dos_spc = DOS_CLUST(sptr); + if( dos_spc < 1 ) dos_spc = 1; + dos_clust0 = dir_sect + (dir_nentry+15)/16 - 2*dos_spc; - if( (seg_start&0xF000) != (seg_end&0xF000) ) /* Bugger */ + if( disk_cyls == 0 ) { - int rv = alloc_trackbuf(sectors); - free(new_track); - return rv; + disk_spt = DOS_SPT(sptr); + disk_heads = DOS_HEADS(sptr); } - track_len = sectors; - track_buffer = new_track; return 0; } - -#endif - -#if defined(__MSDOS__) || defined(__STANDALONE__) -phy_read(drive, cyl, head, sect, length, buffer) -{ -#asm - push bp - mov bp,sp - - push ds - pop es - - mov dl,[bp+2+_phy_read.drive] - mov ch,[bp+2+_phy_read.cyl] - mov dh,[bp+2+_phy_read.head] - mov cl,[bp+2+_phy_read.sect] - mov al,[bp+2+_phy_read.length] - mov bx,[bp+2+_phy_read.buffer] - - mov ah,#$02 - int $13 - jc read_err - mov ax,#0 -read_err: - - pop bp -#endasm -} -#endif - diff --git a/bootblocks/fs_min.c b/bootblocks/fs_min.c new file mode 100644 index 0000000..78a5fc9 --- /dev/null +++ b/bootblocks/fs_min.c @@ -0,0 +1,31 @@ + +#include "readfs.h" + +min_open_file(fname) +char * fname; +{ + return -1; +} + +min_rewind_file() +{ + return -1; +} + +min_close_file() +{ + return -1; +} + +long +min_file_length() +{ + return -1; +} + +min_read_block(buffer) +char * buffer; +{ + return -1; +} + diff --git a/bootblocks/fs_tar.c b/bootblocks/fs_tar.c new file mode 100644 index 0000000..278c8c1 --- /dev/null +++ b/bootblocks/fs_tar.c @@ -0,0 +1,156 @@ + +#ifdef __ELKS__ +#include <stdio.h> +#endif + +#include <dos.h> +#include "readfs.h" + +#define HEADER_SIZE 512 +#define NAME_SIZE 100 +#define BLOCK_BOUNDARY 20 + +typedef union { + char hdr_block[HEADER_SIZE]; + struct m { + char m_name[NAME_SIZE]; + char m_mode[8]; + char m_uid[8]; + char m_gid[8]; + char m_size[12]; + char m_time[12]; + char m_checksum[8]; + char m_linked; + char m_link[NAME_SIZE]; + } member; +} HEADER; + +#ifdef __STANDALONE__ +extern union REGS __argr; +#endif + +tar_open_file(fname) +char * fname; +{ + HEADER * sptr; + +#ifdef __STANDALONE__ + if( disk_drive != __argr.h.dl ) return -1; /* Only the one booted off */ + if( __argr.x.si < 9 || __argr.x.si > 63 ) return -1; /* SPT good */ +#endif + + sptr = read_sector(0); + + /* Boot sector a volume label ? */ + if( sptr->member.m_linked != 'V' ) return -1; + if( !valid_tar_checksum(sptr) ) return -1; + +#ifdef __STANDALONE__ + disk_spt = __argr.x.si; +#else + disk_spt = 18; /* Testing only */ +#endif + +#ifdef __ELKS__ + fprintf(stderr, "Got vaild tar header\n"); +#endif + + return -1; +} + +tar_rewind_file() +{ + return -1; +} + +tar_close_file() +{ + return -1; +} + +long +tar_file_length() +{ + return -1; +} + +tar_read_block(buffer) +char * buffer; +{ + return -1; +} + +long +tar_convert(str, type) +char str[]; +int type; +{ + register long ac = 0L; + register int i; + + for (i = 0; i < type; i++) + { + if (str[i] >= '0' && str[i] <= '7') + { + ac <<= 3; + ac += (long) (str[i] - '0'); + } + } + return ac; +} + +valid_tar_checksum(sptr) +HEADER * sptr; +{ + register char *ptr; + register int ac = 0; + + ptr = sptr->hdr_block; + while (ptr < sptr->hdr_block+sizeof(sptr->hdr_block)) + if( ptr < sptr->member.m_checksum || + ptr >= sptr->member.m_checksum+sizeof(sptr->member.m_checksum)) + ac += (*ptr++ & 0xFF); + else + ptr++, (ac += ' '); + + ac -= tar_convert(sptr->member.m_checksum, sizeof(sptr->member.m_checksum)); + return ac == 0; +} + +#if 0 + +#asm +!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +! +! These are the number of sectors per track that will be scanned for. +! For 3.5 inch floppies 36 is 2.88 Mb, 18 is 1.44Mb, 21 is 1.68Mb on +! a 1.44Mb floppy drive. 15 and 9 are for 5.25 inch floppies. + +disksizes: .byte 36,21,18,15,9 + +! It seems that there is no BIOS call to get the number of sectors. Guess +! 36 sectors if sector 36 can be read, 18 sectors if sector 18 can be read, +! 15 if sector 15 can be read. Otherwise guess 9. + +export _probe_sectors +_probe_sectors: + mov si,#disksizes ! table of sizes to try + +probe_loop: + lodsb + cbw ! extend to word + mov _disk_spt, ax + cmp al,#9 + je got_sectors ! if all else fails, try 9 + xchg ax, cx ! cx = track and sector + xor dx, dx ! drive 0, head 0 + mov bx,#probe_buf ! address after setup (es = cs) + mov ax,#0x0201 ! service 2, 1 sector + int 0x13 + jc probe_loop ! try next value +got_sectors: + + ret +#endasm + +#endif diff --git a/bootblocks/i86_funcs.c b/bootblocks/i86_funcs.c index c17a158..b9ea180 100644 --- a/bootblocks/i86_funcs.c +++ b/bootblocks/i86_funcs.c @@ -1,6 +1,7 @@ #include <stdio.h> #include <errno.h> +#include <dos.h> #include "i86_funcs.h" int x86 = 0; /* CPU major number */ diff --git a/bootblocks/makeboot.c b/bootblocks/makeboot.c index 4a036a6..b844ba8 100644 --- a/bootblocks/makeboot.c +++ b/bootblocks/makeboot.c @@ -8,6 +8,8 @@ #include "msdos.v" #include "skip.v" #include "tarboot.v" +#include "minix.v" +#include "minixhd.v" char buffer[1024]; @@ -16,20 +18,24 @@ char buffer[1024]; #define FS_DOS 2 /* Bootsector needs any DOS FS */ #define FS_TAR 3 /* Bootsector needs GNU-tar volume label */ #define FS_STAT 4 /* DOS bootsector is checked */ +#define FS_ZERO 5 /* Boot sector must be Zapped */ struct bblist { char * name; + char * desc; char * data; + int size; int fstype; - char * desc; } bblocks[] = { - { "tar", tarboot_data, FS_TAR, "Bootable GNU tar volume lable" }, - { "dosfs", msdos_data, FS_ADOS, "Boots file BOOTFILE.SYS from dosfs" }, - { "none", noboot_data, FS_DOS, "No OS bookblock, just message" }, - { "skip", skip_data, FS_DOS, "Bypasses floppy boot with message" }, - { "stat", 0, FS_STAT, "Display dosfs superblock" }, - { "copy", 0, FS_STAT, "Copy boot block to makeboot.sav" }, - { "Zap", 0, FS_NONE, "Clear boot block to NULs" }, +{ "tar", "Bootable GNU tar volume lable", tarboot_data, tarboot_size, FS_TAR}, +{ "dosfs","Boot file BOOTFILE.SYS from dosfs", msdos_data, msdos_size, FS_ADOS}, +{ "none", "No OS bootblock, just message", noboot_data, noboot_size, FS_DOS}, +{ "skip", "Bypasses floppy boot with message", skip_data, skip_size, FS_DOS}, +{ "minix","Minix floppy FS booter", minix_data, minix_size, FS_ZERO}, +{ "hdmin","Minix Hard disk FS booter", minixhd_data, minixhd_size, FS_ZERO}, +{ "stat", "Display dosfs superblock", 0, 0, FS_STAT}, +{ "copy", "Copy boot block to makeboot.sav", 0, 0, FS_STAT}, +{ "Zap", "Clear boot block to NULs", 0, 1024, FS_NONE}, 0 }; @@ -43,6 +49,9 @@ int disk_head = 256; /* Set to the correct values when an MSDOS disk is */ int disk_trck = 256; /* successfully identified */ int force = 0; +int write_zero = 1; /* Write sector 0 */ +int write_one = 0; /* Write sector 1 */ +int bs_offset = 0; /* Offset of _real_ bootsector for 2m floppies */ main(argc, argv) int argc; @@ -70,6 +79,9 @@ char ** argv; exit(1); read_sector(1, buffer+512); + write_zero = (ptr->size >= 512); + write_one = (ptr->size >= 1024); + switch(ptr->fstype) { case FS_NONE: /* override */ @@ -84,6 +96,9 @@ char ** argv; case FS_TAR: check_tar(); break; + case FS_ZERO: + check_zapped(); + break; default: fprintf(stderr, "Program error, unknown filesystem requirement\n"); @@ -114,11 +129,23 @@ char ** argv; if( ptr->data ) memcpy(buffer, ptr->data, 512); else - memset(buffer, '\0', 512); + { + memset(buffer, '\0', 1024); + write_one = 1; + } break; } - write_sector(0, buffer); + if( bs_offset ) + { + if( write_zero ) do_2m_write(); + /* Don't write 1 ever! */ + } + else + { + if( write_zero ) write_sector(0, buffer); + if( write_one ) write_sector(1, buffer+512); + } close_disk(); exit(0); } @@ -310,6 +337,22 @@ write_err: /**************************************************************************/ +check_zapped() +{ + int i; + for(i=0; i<512; i++) + if( buffer[i] ) + break; + + if( i != 512 ) + { + fprintf(stderr, "Boot block isn't empty, zap it first\n"); + if(!force) exit(1); + } +} + +/**************************************************************************/ + struct tar_head { char name[100]; char mode[8]; @@ -363,6 +406,9 @@ not_zapped: { fprintf(stderr, "TAR file checksum failed, this isn't a tar file.\n"); if(!force) exit(9); + + write_one = 1; + memset(buffer, '\0', 1024); } if( buff_tar.linkflag != 'V' ) { @@ -577,6 +623,28 @@ check_msdos() disk_head = dosflds[DOS_HEADS].value; if( disk_sect > 0 && disk_head > 0 ) disk_trck = dosflds[DOS_MAXSECT].value/disk_head/disk_sect; + +#ifndef __MSDOS__ + if( bs_offset == 0 && + memcmp(buffer+dosflds[DOS_SYSID].offset, "2M-STV0", 7) == 0) + { + printf("Floppy is in 2M format - reading 2nd boot block\n"); + bs_offset = dosflds[DOS_RESV].value + dosflds[DOS_FATLEN].value; + if( read_sector(bs_offset, buffer) != 0 ) + exit(1); + + decode_super(buffer); + if( dosflds[DOS_MEDIA].value < 0xF0 || + ( dosflds[DOS_MEDIA].value != (0xFF&buffer[512]) + && dosflds[DOS_RESV].value == 1 ) ) + { + printf("Bad 2nd boot block - reloading first\n"); + if( read_sector(0, buffer) != 0 ) + exit(1); + } + check_msdos(); + } +#endif return; } if(!force) exit(2); @@ -620,3 +688,263 @@ check_simpledos() } /**************************************************************************/ + +char boot_sector_2m_23_82[] = { +0xe9,0x7d,0x00,0x32,0x4d,0x2d,0x53,0x54,0x56,0x30,0x34,0x00,0x02,0x01,0x01,0x00, +0x02,0xe0,0x00,0xbc,0x0e,0xfa,0x0b,0x00,0x17,0x00,0x02,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x29,0x45,0xb8,0x25,0x51,0x4e,0x4f,0x20,0x4e,0x41, +0x4d,0x45,0x20,0x20,0x20,0x20,0x46,0x41,0x54,0x31,0x32,0x20,0x20,0x20,0x00,0x3f, +0x07,0x01,0x00,0x00,0x80,0x00,0x4c,0x00,0x61,0x00,0x79,0x00,0x13,0x46,0x01,0x02, +0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12, +0x13,0x40,0x03,0x07,0x81,0x04,0x04,0x8c,0x01,0x04,0x97,0x05,0x04,0xa2,0x02,0x04, +0xad,0x06,0x03,0xb3,0x03,0x04,0xbe,0x07,0x02,0x04,0x04,0x04,0x04,0x04,0x03,0x02, +0xfa,0x33,0xc0,0x8e,0xd0,0xbc,0x00,0x7c,0xb8,0xc0,0x07,0x50,0x05,0x20,0x00,0x50, +0x07,0x1f,0x33,0xf6,0x33,0xff,0xb9,0x00,0x01,0xfc,0xf3,0xa5,0x8b,0x1e,0x44,0x00, +0x8d,0x47,0x26,0x06,0x50,0xcb,0xfb,0xbe,0x1a,0x01,0xe8,0xd9,0x00,0xbb,0x78,0x00, +0x36,0xc5,0x37,0x1e,0x56,0x33,0xff,0x36,0x89,0x3f,0x36,0x8c,0x47,0x02,0xb9,0x0b, +0x00,0xf3,0xa4,0x06,0x1f,0xa0,0x18,0x00,0x88,0x45,0xf9,0x33,0xc0,0x8e,0xc0,0xbb, +0x00,0x7c,0x26,0x89,0x87,0xfe,0x01,0xb8,0x01,0x02,0x8b,0x0e,0x16,0x00,0x83,0xc1, +0x02,0x33,0xd2,0x83,0xf9,0x0a,0x72,0x1f,0x51,0xcd,0x13,0x59,0x36,0x8b,0x1e,0x13, +0x04,0x83,0xeb,0x05,0xb8,0x40,0x00,0xf7,0xe3,0x8e,0xc0,0x53,0x33,0xdb,0xb8,0x05, +0x02,0x41,0x33,0xd2,0xcd,0x13,0x5b,0x36,0x8f,0x06,0x78,0x00,0x36,0x8f,0x06,0x7a, +0x00,0x26,0x81,0x3e,0xfe,0x09,0x55,0xaa,0x75,0x60,0x36,0x89,0x1e,0x13,0x04,0x06, +0xb4,0x08,0xb3,0x00,0xb2,0x00,0xcd,0x13,0x8a,0xc3,0xb4,0x00,0x80,0xfa,0x02,0x72, +0x0c,0x50,0xb4,0x08,0xb3,0x00,0xb2,0x01,0xcd,0x13,0x58,0x8a,0xe3,0x07,0x26,0x8c, +0x06,0xfe,0x09,0x26,0xff,0x1e,0xfc,0x09,0xb8,0x01,0x02,0x33,0xd2,0x8e,0xc2,0xb9, +0x01,0x00,0xbb,0x00,0x80,0x50,0xcd,0x13,0x58,0xbb,0x00,0x7c,0x06,0x53,0x26,0x81, +0x7f,0x03,0x32,0x4d,0x75,0x04,0xb2,0x80,0xcd,0x13,0x26,0x81,0x3e,0xfe,0x7d,0x55, +0xaa,0x75,0x03,0x33,0xd2,0xcb,0x22,0xd2,0x74,0xec,0xbe,0x2f,0x01,0xe8,0x06,0x00, +0xb4,0x00,0xcd,0x16,0xcd,0x19,0x03,0x36,0x44,0x00,0xfc,0xac,0x22,0xc0,0x74,0x09, +0xb4,0x0e,0xbb,0x07,0x00,0xcd,0x10,0xeb,0xf1,0xc3,0x0d,0x0a,0x32,0x4d,0x20,0x53, +0x75,0x70,0x65,0x72,0x42,0x4f,0x4f,0x54,0x20,0x32,0x2e,0x30,0x0d,0x0a,0x00,0x0d, +0x0a,0xad,0x4e,0x6f,0x20,0x62,0x6f,0x74,0x61,0x62,0x6c,0x65,0x21,0x0d,0x0a,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x4d,0x61,0x64,0x65,0x20,0x69,0x6e,0x20,0x53,0x70,0x61,0x69,0x6e,0x00,0x55,0xaa +}; + +char boot_sector_2m_22_82[] = { +0xe9,0x6e,0x00,0x32,0x4d,0x2d,0x53,0x54,0x56,0x30,0x38,0x00,0x02,0x01,0x01,0x00, +0x02,0xe0,0x00,0x18,0x0e,0xfa,0x0b,0x00,0x16,0x00,0x02,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x29,0xcc,0x9b,0xe1,0xd4,0x4e,0x4f,0x20,0x4e,0x41, +0x4d,0x45,0x20,0x20,0x20,0x20,0x46,0x41,0x54,0x31,0x32,0x20,0x20,0x20,0x00,0x04, +0x07,0x00,0x00,0x00,0x71,0x00,0x4c,0x00,0x61,0x00,0x66,0x00,0x13,0x46,0x01,0x02, +0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12, +0x13,0x0b,0x28,0x03,0x01,0x02,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03, +0x03,0xfa,0x33,0xc0,0x8e,0xd0,0xbc,0x00,0x7c,0xb8,0xc0,0x07,0x50,0x05,0x20,0x00, +0x50,0x07,0x1f,0x33,0xf6,0x33,0xff,0xb9,0x00,0x01,0xfc,0xf3,0xa5,0x8b,0x1e,0x44, +0x00,0x8d,0x47,0x26,0x06,0x50,0xcb,0xfb,0xbe,0x1a,0x01,0xe8,0xd9,0x00,0xbb,0x78, +0x00,0x36,0xc5,0x37,0x1e,0x56,0x33,0xff,0x36,0x89,0x3f,0x36,0x8c,0x47,0x02,0xb9, +0x0b,0x00,0xf3,0xa4,0x06,0x1f,0xa0,0x18,0x00,0x88,0x45,0xf9,0x33,0xc0,0x8e,0xc0, +0xbb,0x00,0x7c,0x26,0x89,0x87,0xfe,0x01,0xb8,0x01,0x02,0x8b,0x0e,0x16,0x00,0x83, +0xc1,0x02,0x33,0xd2,0x83,0xf9,0x0a,0x72,0x1f,0x51,0xcd,0x13,0x59,0x36,0x8b,0x1e, +0x13,0x04,0x83,0xeb,0x05,0xb8,0x40,0x00,0xf7,0xe3,0x8e,0xc0,0x53,0x33,0xdb,0xb8, +0x05,0x02,0x41,0x33,0xd2,0xcd,0x13,0x5b,0x36,0x8f,0x06,0x78,0x00,0x36,0x8f,0x06, +0x7a,0x00,0x26,0x81,0x3e,0xfe,0x09,0x55,0xaa,0x75,0x60,0x36,0x89,0x1e,0x13,0x04, +0x06,0xb4,0x08,0xb3,0x00,0xb2,0x00,0xcd,0x13,0x8a,0xc3,0xb4,0x00,0x80,0xfa,0x02, +0x72,0x0c,0x50,0xb4,0x08,0xb3,0x00,0xb2,0x01,0xcd,0x13,0x58,0x8a,0xe3,0x07,0x26, +0x8c,0x06,0xfe,0x09,0x26,0xff,0x1e,0xfc,0x09,0xb8,0x01,0x02,0x33,0xd2,0x8e,0xc2, +0xb9,0x01,0x00,0xbb,0x00,0x80,0x50,0xcd,0x13,0x58,0xbb,0x00,0x7c,0x06,0x53,0x26, +0x81,0x7f,0x03,0x32,0x4d,0x75,0x04,0xb2,0x80,0xcd,0x13,0x26,0x81,0x3e,0xfe,0x7d, +0x55,0xaa,0x75,0x03,0x33,0xd2,0xcb,0x22,0xd2,0x74,0xec,0xbe,0x2f,0x01,0xe8,0x06, +0x00,0xb4,0x00,0xcd,0x16,0xcd,0x19,0x03,0x36,0x44,0x00,0xfc,0xac,0x22,0xc0,0x74, +0x09,0xb4,0x0e,0xbb,0x07,0x00,0xcd,0x10,0xeb,0xf1,0xc3,0x0d,0x0a,0x32,0x4d,0x20, +0x53,0x75,0x70,0x65,0x72,0x42,0x4f,0x4f,0x54,0x20,0x32,0x2e,0x30,0x0d,0x0a,0x00, +0x0d,0x0a,0xad,0x4e,0x6f,0x20,0x62,0x6f,0x74,0x61,0x62,0x6c,0x65,0x21,0x0d,0x0a, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x4d,0x61,0x64,0x65,0x20,0x69,0x6e,0x20,0x53,0x70,0x61,0x69,0x6e,0x00,0x55,0xaa +}; + + +char program_2m_vsn_20[] = { +0x2b,0x00,0x43,0x00,0x32,0x30,0x32,0x4d,0x2d,0x53,0x54,0x56,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x4a,0x42,0x00,0x00,0x01,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfb,0xfc,0x9c,0x56,0x80, +0xfa,0x02,0x73,0x3d,0xe8,0x41,0x00,0x2e,0x80,0x3c,0x02,0x74,0x04,0x2e,0x80,0x3c, +0x04,0x72,0x2e,0x80,0xfc,0x02,0x72,0x29,0x80,0xfc,0x05,0x77,0x24,0x75,0x05,0xe8, +0x36,0x00,0xeb,0x1d,0xe8,0x85,0x00,0x73,0x09,0x5e,0x9d,0xf9,0xb8,0x00,0x06,0xca, +0x02,0x00,0x2e,0x80,0x7c,0x01,0x00,0x74,0x08,0x5e,0x9d,0xe8,0x3c,0x02,0xca,0x02, +0x00,0x5e,0x9d,0x2e,0xff,0x2e,0xfc,0x09,0x9c,0x53,0x8a,0xda,0xb7,0x00,0xd1,0xe3, +0x2e,0x8b,0xb7,0x00,0x00,0x5b,0x9d,0xc3,0x60,0xe8,0xec,0xff,0xb0,0x01,0x72,0x02, +0xb0,0x00,0x2e,0x88,0x44,0x01,0x61,0xc3,0x50,0xa0,0x12,0x00,0x0a,0x06,0x11,0x00, +0x58,0xc3,0x60,0x1e,0x6a,0x40,0x1f,0xb0,0x01,0x8a,0xca,0xd2,0xe0,0x84,0x06,0x3f, +0x00,0x75,0x04,0xf8,0xe8,0xef,0x05,0x8a,0xe2,0xc0,0xe4,0x04,0x0a,0xe0,0xc0,0xe0, +0x04,0x0c,0x0c,0x0a,0xc2,0xba,0xf2,0x03,0xfa,0x88,0x26,0x3f,0x00,0xee,0x83,0xc2, +0x05,0xeb,0x00,0xeb,0x00,0xec,0xfb,0xa8,0x80,0x1f,0x61,0xc3,0x60,0xe8,0x98,0xff, +0x2e,0x80,0x7c,0x02,0x01,0x2e,0xc6,0x44,0x02,0x00,0x74,0x08,0xe8,0xb3,0xff,0x75, +0x03,0x61,0xf8,0xc3,0xf8,0xe8,0x90,0xff,0x1e,0x06,0xbb,0x90,0x00,0x02,0xda,0x6a, +0x40,0x1f,0x80,0x27,0xef,0x0e,0x0e,0x1f,0x07,0x88,0x16,0x0c,0x00,0xf9,0xe8,0x29, +0x05,0xc6,0x06,0x11,0x00,0x01,0xc6,0x06,0x12,0x00,0x00,0xe8,0xa1,0x05,0xfe,0x0e, +0x11,0x00,0xe8,0x9a,0x05,0xf8,0xe8,0x7d,0x05,0xe8,0x76,0xff,0x74,0x07,0xc6,0x44, +0x02,0x01,0xf8,0xeb,0x68,0x1e,0x6a,0x40,0x1f,0xc6,0x06,0x41,0x00,0x06,0x1f,0xc6, +0x06,0x1b,0x00,0xff,0xc6,0x44,0x08,0x14,0xb9,0x03,0x00,0x51,0x83,0xf9,0x02,0xe8, +0xe8,0x04,0xc6,0x44,0x06,0x00,0xc6,0x06,0x11,0x00,0x00,0xc6,0x06,0x12,0x00,0x00, +0xc6,0x06,0x13,0x00,0x01,0xc6,0x06,0x16,0x00,0x00,0xc6,0x06,0x17,0x00,0x01,0xc6, +0x06,0x27,0x00,0x46,0x8b,0x3e,0x19,0x00,0xe8,0x7f,0x02,0x75,0x0b,0x59,0x8b,0x1e, +0x19,0x00,0xe8,0x1c,0x00,0xf8,0xeb,0x14,0x8a,0x44,0x06,0x40,0x3c,0x03,0x77,0x05, +0x88,0x44,0x06,0xeb,0xc1,0xc6,0x44,0x06,0x00,0x59,0xe2,0xaf,0xf9,0x07,0x1f,0x61, +0xc3,0x60,0xe8,0x88,0x00,0x72,0x5c,0x88,0x44,0x05,0x88,0x4c,0x03,0x8a,0x16,0x0c, +0x00,0xf9,0xe8,0xd3,0xfe,0x26,0x8a,0x47,0x16,0x88,0x44,0x17,0x26,0x8a,0x4f,0x41, +0x88,0x4c,0x04,0x26,0x8b,0x47,0x42,0x89,0x44,0x06,0x26,0x8a,0x47,0x18,0x88,0x44, +0x09,0x26,0x8b,0x7f,0x48,0x26,0x8a,0x41,0x01,0x8a,0xe0,0x22,0xc9,0x74,0x0a,0x80, +0xc4,0xbe,0xb0,0x0b,0xf6,0xe4,0x2d,0x3e,0x08,0xd0,0xe8,0x88,0x44,0x08,0xb9,0x0d, +0x00,0x26,0x8b,0x7f,0x4a,0x03,0xfb,0x8d,0x5c,0x0a,0x26,0x8a,0x05,0x88,0x07,0x43, +0x47,0xe2,0xf7,0x8a,0x44,0x06,0xc0,0xe0,0x06,0x0c,0x17,0x80,0x3c,0x02,0x77,0x0a, +0x24,0xf8,0x0c,0x05,0xa8,0x40,0x74,0x02,0x34,0x21,0x1e,0xbb,0x90,0x00,0x02,0x1e, +0x0c,0x00,0x6a,0x40,0x1f,0x80,0x27,0x08,0x08,0x07,0x1f,0x61,0xc3,0x56,0x57,0x8d, +0x7f,0x03,0xbe,0x06,0x00,0xb9,0x06,0x00,0xf3,0xa6,0xf9,0x75,0x19,0x33,0xc0,0x26, +0x8a,0x4f,0x40,0x80,0xf9,0x06,0x72,0x0d,0x26,0x8b,0x7f,0x44,0x4f,0x26,0x02,0x01, +0x83,0xff,0x3f,0x77,0xf7,0xf8,0x5f,0x5e,0xc3,0x50,0x73,0x37,0x80,0x3e,0x1f,0x00, +0x00,0x75,0x2f,0xa0,0x21,0x00,0xd0,0xe0,0xb4,0x04,0x72,0x22,0xc0,0xe0,0x02,0xb4, +0x10,0x72,0x1b,0xd0,0xe0,0xb4,0x08,0x72,0x15,0xc0,0xe0,0x02,0xb4,0x04,0x72,0x0e, +0xd0,0xe0,0xb4,0x03,0x72,0x08,0xd0,0xe0,0xb4,0x02,0x72,0x02,0xb4,0x20,0x08,0x26, +0x1f,0x00,0xf9,0x58,0xc3,0x9c,0x60,0x06,0x6a,0x40,0x07,0xbf,0x41,0x00,0xbe,0x1f, +0x00,0xb9,0x04,0x00,0xf3,0xa5,0x07,0x61,0x9d,0xc3,0x1e,0x60,0x0e,0x1f,0x88,0x16, +0x0c,0x00,0xe8,0xc3,0xfd,0x80,0x7c,0x05,0x00,0x74,0x08,0xc6,0x06,0x1f,0x00,0x40, +0xe9,0xbb,0x00,0x50,0xb4,0x00,0xa3,0x0d,0x00,0x8a,0xc5,0xd0,0xe0,0x8a,0xd6,0x80, +0xe6,0x7f,0x02,0xc6,0xf6,0x64,0x09,0x02,0xc1,0x80,0xd4,0x00,0x48,0xa3,0x0f,0x00, +0x8b,0xfb,0x5b,0x8a,0xdf,0xb7,0x00,0x8a,0x8f,0x26,0x00,0x88,0x0e,0x27,0x00,0xd0, +0xe2,0x72,0x73,0x23,0xc0,0x75,0x2c,0x80,0x7c,0x03,0x07,0x72,0x19,0x8a,0x44,0x17, +0x40,0xb9,0x01,0x00,0xe8,0x9b,0x00,0x75,0x6e,0xff,0x0e,0x0d,0x00,0xff,0x06,0x0f, +0x00,0xa1,0x0f,0x00,0xeb,0x0d,0x80,0x3e,0x27,0x00,0x4a,0x75,0x06,0x81,0xc7,0x00, +0x02,0xeb,0xe6,0x8a,0x4c,0x17,0xb5,0x00,0x3b,0xc1,0x77,0x0f,0xe8,0x5d,0x00,0xe8, +0x70,0x00,0x75,0x43,0x83,0x3e,0x0d,0x00,0x00,0x74,0x3c,0xa1,0x0f,0x00,0x8a,0x4c, +0x17,0xb5,0x00,0xd1,0xe1,0x3b,0xc1,0x77,0x1d,0xe8,0x40,0x00,0x80,0x3e,0x27,0x00, +0x4a,0x75,0x07,0xc1,0xe1,0x09,0x03,0xf9,0xeb,0x0c,0x8a,0x54,0x17,0xb6,0x00,0x2b, +0xc2,0xe8,0x3e,0x00,0x75,0x11,0x83,0x3e,0x0d,0x00,0x00,0x74,0x0a,0xa1,0x0f,0x00, +0x8b,0x0e,0x0d,0x00,0xe8,0x2b,0x00,0xf8,0xe8,0x2b,0x03,0xe8,0x17,0xff,0x61,0x8a, +0x26,0x1f,0x00,0x1f,0x22,0xe4,0x74,0x03,0xf9,0xb0,0x00,0xc3,0x2b,0xc8,0x41,0x3b, +0x0e,0x0d,0x00,0x76,0x04,0x8b,0x0e,0x0d,0x00,0x29,0x0e,0x0d,0x00,0x01,0x0e,0x0f, +0x00,0xc3,0x8b,0xd8,0x88,0x0e,0x17,0x00,0xf6,0x74,0x09,0xfe,0xc4,0x88,0x26,0x13, +0x00,0xd0,0xe8,0xa2,0x11,0x00,0xd0,0xd0,0x24,0x01,0xa2,0x12,0x00,0xa0,0x13,0x00, +0x02,0x06,0x17,0x00,0x72,0x06,0x48,0x3a,0x44,0x09,0x76,0x07,0xc6,0x06,0x1f,0x00, +0x04,0xeb,0x77,0x8a,0xc4,0x98,0xe8,0xbf,0xfc,0x74,0x18,0x8d,0x5c,0x09,0x48,0x43, +0xfe,0xc4,0x8a,0x0f,0x80,0xe9,0x02,0xb5,0x01,0xd2,0xe5,0x2a,0xc5,0x73,0xf0,0x02, +0xc5,0x86,0xe0,0xa2,0x13,0x00,0x88,0x26,0x16,0x00,0xe8,0xe8,0x01,0xb4,0x00,0x88, +0x26,0x15,0x00,0xe8,0x92,0xfc,0x75,0x09,0xa0,0x17,0x00,0x88,0x26,0x17,0x00,0xeb, +0x28,0x38,0x64,0x04,0x75,0x28,0x38,0x26,0x16,0x00,0x74,0x05,0xe8,0x31,0x00,0x72, +0x29,0x38,0x26,0x17,0x00,0x74,0x23,0xe8,0x9b,0x01,0x8a,0xc8,0xa0,0x17,0x00,0xf6, +0xf1,0x22,0xc0,0x74,0x09,0x88,0x26,0x17,0x00,0xe8,0x82,0x00,0x72,0x0c,0x80,0x3e, +0x17,0x00,0x00,0x74,0x05,0xe8,0x08,0x00,0x73,0xf4,0x80,0x3e,0x1f,0x00,0x00,0xc3, +0x50,0x80,0x3e,0x27,0x00,0x4a,0x74,0x16,0x80,0x3e,0x27,0x00,0x42,0x74,0x3b,0xe8, +0xbb,0x00,0x73,0x05,0xe8,0xdb,0x00,0x72,0x48,0xe8,0x6f,0x00,0xeb,0x43,0x80,0x3e, +0x16,0x00,0x00,0x75,0x09,0xe8,0x4d,0x01,0x38,0x06,0x17,0x00,0x73,0x14,0xe8,0x9c, +0x00,0x73,0x0f,0xc6,0x06,0x27,0x00,0x46,0xe8,0xb7,0x00,0xc6,0x06,0x27,0x00,0x4a, +0x72,0x1f,0xe8,0x46,0x00,0xe8,0xaa,0x00,0xeb,0x17,0x53,0x8a,0x1e,0x16,0x00,0xe8, +0x23,0x01,0xfe,0x0e,0x17,0x00,0x74,0x05,0x43,0x3a,0xd8,0x72,0xf5,0x5b,0xe8,0x91, +0x00,0x9c,0xfe,0x06,0x13,0x00,0xc6,0x06,0x16,0x00,0x00,0x9d,0x58,0xc3,0x50,0x22, +0xc0,0x74,0x16,0x8a,0x26,0x13,0x00,0x88,0x26,0x14,0x00,0x02,0xc4,0x48,0xa2,0x15, +0x00,0xfe,0xc0,0xe8,0x6c,0x00,0xa2,0x13,0x00,0x58,0xc3,0x50,0x53,0x51,0x56,0x8a, +0x1e,0x16,0x00,0xe8,0xdf,0x00,0x53,0xc1,0xe3,0x09,0x03,0x1e,0x19,0x00,0x8b,0xf3, +0xb9,0x00,0x01,0xe8,0x16,0x00,0xf3,0xa5,0xe8,0x11,0x00,0x5b,0xfe,0x0e,0x17,0x00, +0x74,0x05,0x43,0x3a,0xd8,0x72,0xdf,0x5e,0x59,0x5b,0x58,0xc3,0x2e,0x80,0x3e,0x27, +0x00,0x4a,0x74,0x02,0xf8,0xc3,0x87,0xf7,0x06,0x1e,0x07,0x1f,0xc3,0x50,0xa0,0x1b, +0x00,0x3a,0x06,0x0c,0x00,0x75,0x18,0xa0,0x11,0x00,0x8a,0x26,0x12,0x00,0x3b,0x06, +0x1c,0x00,0x75,0x0b,0xa0,0x1e,0x00,0x3a,0x06,0x13,0x00,0x75,0x02,0x58,0xc3,0xf9, +0x58,0xc3,0x50,0x53,0xe8,0x78,0x01,0x73,0x0f,0x80,0x3e,0x1f,0x00,0x00,0x75,0x05, +0x80,0x0e,0x1f,0x00,0x40,0xf9,0xeb,0x6a,0xe8,0x3d,0xfb,0xb0,0x02,0x74,0x0d,0x8d, +0x5c,0x0a,0x02,0x1e,0x13,0x00,0x80,0xd7,0x00,0x8a,0x47,0xff,0xa2,0x18,0x00,0x80, +0x3e,0x15,0x00,0x00,0x74,0x0b,0xe8,0x5c,0x02,0xc6,0x06,0x15,0x00,0x00,0x9c,0xeb, +0x3d,0x06,0x57,0x0e,0x07,0x8b,0x3e,0x19,0x00,0xa0,0x13,0x00,0xa2,0x14,0x00,0xa2, +0x15,0x00,0xe8,0x40,0x02,0xc6,0x06,0x15,0x00,0x00,0x5f,0x07,0x9c,0xb0,0xff,0x72, +0x0a,0x80,0x3e,0x27,0x00,0x42,0x74,0x16,0xa0,0x0c,0x00,0xa2,0x1b,0x00,0xa0,0x11, +0x00,0x8a,0x26,0x12,0x00,0xa3,0x1c,0x00,0xa0,0x13,0x00,0xa2,0x1e,0x00,0x9d,0xe8, +0x97,0xfc,0x5b,0x58,0xc3,0xe8,0xd0,0xfa,0xb0,0x01,0x74,0x18,0x53,0x51,0x8d,0x5c, +0x0a,0x02,0x1e,0x13,0x00,0x80,0xd7,0x00,0x8a,0x4f,0xff,0x80,0xe9,0x02,0xb0,0x01, +0xd2,0xe0,0x59,0x5b,0xc3,0x60,0x1e,0xbb,0x40,0x00,0x53,0x1f,0xb5,0xed,0xfa,0x2e, +0x8a,0x0e,0x0c,0x00,0xb0,0x01,0xd2,0xe0,0x84,0x47,0xff,0x74,0x04,0x38,0x2f,0x76, +0x33,0x08,0x47,0xff,0x80,0x67,0xff,0xcf,0x8a,0xc1,0xc0,0xe0,0x04,0x08,0x47,0xff, +0xc6,0x07,0xff,0xfb,0xba,0xf2,0x03,0x80,0xc1,0x04,0xb0,0x01,0xd2,0xe0,0x2e,0x0a, +0x06,0x0c,0x00,0x0c,0x0c,0xee,0xb8,0xfd,0x90,0xf8,0xcd,0x15,0x72,0x06,0xb8,0xe8, +0x03,0xe8,0x48,0x03,0x88,0x2f,0xfb,0x1f,0x61,0xc3,0x60,0xe8,0x68,0x00,0x8a,0x0e, +0x0c,0x00,0x8a,0xc1,0xc0,0xe0,0x02,0x0c,0x01,0xd2,0xe0,0x1e,0x6a,0x40,0x1f,0xfa, +0xa2,0x3f,0x00,0x80,0x26,0x3e,0x00,0x70,0x1f,0xc0,0xe0,0x04,0x0a,0xc1,0x0c,0x08, +0xba,0xf2,0x03,0xee,0xe8,0x08,0x03,0x0c,0x04,0xee,0xe8,0x1a,0x02,0xb0,0x08,0xe8, +0xc3,0x02,0xe8,0x82,0x02,0xe8,0x7f,0x02,0xe8,0x02,0x00,0x61,0xc3,0x50,0x1e,0x6a, +0x40,0x1f,0x8a,0x26,0x8b,0x00,0x1f,0xb0,0x03,0xe8,0xa9,0x02,0xb0,0xbf,0x80,0xe4, +0xc0,0x74,0x09,0xb0,0xaf,0x80,0xfc,0xc0,0x74,0x02,0xb0,0xdf,0xe8,0x96,0x02,0xb0, +0x02,0xe8,0x91,0x02,0x58,0xc3,0x60,0x1e,0xb0,0xff,0x72,0x0a,0x6a,0x00,0x1f,0xc5, +0x1e,0x78,0x00,0x8a,0x47,0x02,0x6a,0x40,0x1f,0xa2,0x40,0x00,0x1f,0x61,0xc3,0x60, +0xe8,0x87,0x00,0xe8,0xb7,0xff,0xb4,0x01,0x8a,0x0e,0x0c,0x00,0xd2,0xe4,0x1e,0x6a, +0x40,0x1f,0x84,0x26,0x3e,0x00,0x1f,0x75,0x05,0xe8,0xa6,0x00,0x72,0x69,0xbb,0x94, +0x00,0x02,0x1e,0x0c,0x00,0xa0,0x11,0x00,0x1e,0x6a,0x40,0x1f,0x08,0x26,0x3e,0x00, +0x8a,0x26,0x41,0x00,0x3a,0x07,0x88,0x07,0x1f,0x75,0x05,0x80,0xfc,0x40,0x75,0x44, +0xb0,0x0f,0xe8,0x30,0x02,0x72,0x40,0xa0,0x12,0x00,0xc0,0xe0,0x02,0x0a,0x06,0x0c, +0x00,0xe8,0x21,0x02,0xa0,0x11,0x00,0xe8,0x1b,0x02,0xe8,0x6a,0x01,0x72,0x28,0xb0, +0x08,0xe8,0x11,0x02,0x72,0x21,0xe8,0xce,0x01,0x72,0x1c,0x8a,0xe0,0xe8,0xc7,0x01, +0xf6,0xc4,0xc0,0x75,0x12,0xb0,0x0f,0x80,0x3e,0x27,0x00,0x4a,0x74,0x02,0xb0,0x01, +0x98,0xe8,0x38,0x02,0x61,0xf8,0xc3,0x61,0xf9,0xc3,0x60,0xe8,0x4a,0xf9,0x8b,0x44, +0x06,0x74,0x02,0x8a,0xc4,0x1e,0x6a,0x40,0x1f,0x8a,0x26,0x8b,0x00,0xc0,0xec,0x06, +0x3a,0xc4,0x74,0x10,0xba,0xf7,0x03,0xee,0xc0,0xe0,0x06,0x80,0x26,0x8b,0x00,0x3f, +0x08,0x06,0x8b,0x00,0x1f,0xbf,0x1f,0x00,0xb9,0x08,0x00,0x88,0x2d,0x47,0xe2,0xfb, +0x61,0xc3,0x60,0xbb,0x94,0x00,0x02,0x1e,0x0c,0x00,0x1e,0x6a,0x40,0x1f,0x88,0x3f, +0x1f,0xb9,0x02,0x00,0xb0,0x07,0xe8,0x9c,0x01,0x72,0x35,0xa0,0x12,0x00,0xc0,0xe0, +0x02,0x0a,0x06,0x0c,0x00,0xe8,0x8d,0x01,0x72,0x26,0xe8,0xda,0x00,0x72,0x21,0xb0, +0x08,0xe8,0x81,0x01,0x72,0x1a,0xe8,0x3e,0x01,0x72,0x15,0x8a,0xe0,0xe8,0x37,0x01, +0x80,0xf4,0x20,0xf6,0xc4,0xf0,0x75,0x08,0xb8,0x01,0x00,0xe8,0xae,0x01,0xeb,0x03, +0xe2,0xc2,0xf9,0x61,0xc3,0x50,0x53,0x51,0x52,0x8a,0x0e,0x18,0x00,0xb5,0x00,0xf9, +0xd2,0xd5,0xb1,0x00,0xa0,0x15,0x00,0x2a,0x06,0x14,0x00,0x40,0x98,0xf7,0xe1,0x8b, +0xd0,0x8b,0xc8,0x49,0x8c,0xc0,0xe8,0x72,0x00,0x72,0x6a,0xa0,0x27,0x00,0xe8,0xb7, +0x00,0x3c,0x4a,0xb0,0xc5,0x74,0x02,0xb0,0xe6,0xe8,0x29,0x01,0x72,0x57,0xa0,0x12, +0x00,0xc0,0xe0,0x02,0x0a,0x06,0x0c,0x00,0xe8,0x1a,0x01,0xa0,0x11,0x00,0xe8,0x14, +0x01,0xa0,0x12,0x00,0xe8,0x0e,0x01,0xa0,0x14,0x00,0xe8,0x08,0x01,0xa0,0x18,0x00, +0xe8,0x02,0x01,0xa0,0x15,0x00,0xe8,0xfc,0x00,0x8a,0x44,0x08,0xe8,0xf6,0x00,0xb0, +0x80,0xe8,0xf1,0x00,0xe8,0x40,0x00,0x9c,0xbb,0x20,0x00,0xb9,0x07,0x00,0xe8,0xa6, +0x00,0x88,0x07,0x43,0xe2,0xf8,0x9d,0x72,0x0c,0xf6,0x06,0x20,0x00,0xc0,0x75,0x05, +0x03,0xfa,0xf8,0xeb,0x01,0xf9,0x5a,0x59,0x5b,0x58,0xc3,0x52,0xbb,0x10,0x00,0xf7, +0xe3,0x03,0xc7,0x83,0xd2,0x00,0x8b,0xd8,0x8a,0xe2,0x8b,0xd1,0x03,0xd3,0x73,0x05, +0xc6,0x06,0x1f,0x00,0x09,0x5a,0xc3,0xfb,0x60,0x1e,0x6a,0x40,0x1f,0xb8,0x01,0x90, +0xf8,0xcd,0x15,0xba,0x80,0x02,0xbb,0x3e,0x00,0x72,0x0f,0x33,0xc9,0x84,0x17,0x75, +0x0f,0xe8,0xf6,0x00,0xe2,0xf7,0xfe,0xce,0x75,0xf1,0x2e,0x08,0x16,0x1f,0x00,0xf9, +0x9c,0x80,0x27,0x7f,0x9d,0x1f,0x61,0xc3,0x50,0xfa,0xe6,0x0b,0xb0,0x00,0xeb,0x00, +0xeb,0x00,0xe6,0x0c,0x8a,0xc3,0xeb,0x00,0xeb,0x00,0xe6,0x04,0x8a,0xc7,0xeb,0x00, +0xeb,0x00,0xe6,0x04,0xeb,0x00,0xeb,0x00,0x8a,0xc4,0xe6,0x81,0x8a,0xc1,0xeb,0x00, +0xeb,0x00,0xe6,0x05,0x8a,0xc5,0xeb,0x00,0xeb,0x00,0xe6,0x05,0xfb,0xb0,0x02,0xeb, +0x00,0xeb,0x00,0xe6,0x0a,0x58,0xc3,0x51,0x52,0x50,0xe8,0x72,0x00,0xba,0xf4,0x03, +0xb9,0x85,0x00,0xeb,0x00,0xeb,0x00,0xec,0x24,0xc0,0x3c,0xc0,0x74,0x1c,0xeb,0x00, +0xeb,0x00,0xe4,0x61,0x24,0x10,0x3a,0xc4,0x74,0xe9,0x8a,0xe0,0xe2,0xe5,0x58,0x5a, +0x59,0x80,0x0e,0x1f,0x00,0x80,0xb0,0x00,0xf9,0xc3,0x58,0x42,0xeb,0x00,0xeb,0x00, +0xec,0x5a,0x59,0xf8,0xc3,0x51,0x52,0x50,0xe8,0x34,0x00,0xba,0xf4,0x03,0xb9,0x85, +0x00,0xeb,0x00,0xeb,0x00,0xec,0xa8,0x80,0x75,0x1a,0xeb,0x00,0xeb,0x00,0xe4,0x61, +0x24,0x10,0x3a,0xc4,0x74,0xeb,0x8a,0xe0,0xe2,0xe7,0x58,0x5a,0x59,0x80,0x0e,0x1f, +0x00,0x80,0xf9,0xc3,0x42,0x58,0xeb,0x00,0xeb,0x00,0xee,0x5a,0x59,0xf8,0xc3,0x50, +0x51,0xb9,0x04,0x00,0xe8,0x23,0x00,0xe2,0xfb,0x59,0x58,0xc3,0x9c,0x60,0xba,0x4a, +0x42,0xf7,0xe2,0x8a,0xcc,0x8a,0xea,0x8a,0xd6,0xb6,0x00,0xe8,0x0c,0x00,0xe2,0xfb, +0x23,0xd2,0x74,0x03,0x4a,0xeb,0xf4,0x61,0x9d,0xc3,0xeb,0x00,0xeb,0x00,0xe4,0x61, +0x24,0x10,0x3a,0xc4,0x74,0xf4,0x8a,0xe0,0xc3,0x1e,0x16,0x1f,0x26,0xa2,0x2b,0x00, +0x26,0x88,0x26,0x43,0x00,0xbf,0xfc,0x09,0xbe,0x4c,0x00,0xfc,0xfa,0xa5,0xa5,0xc7, +0x44,0xfc,0x5b,0x00,0x8c,0x44,0xfe,0xfb,0x1f,0xcb,0x00,0x00,0xd9,0x09,0x55,0xaa +}; + +do_2m_write() +{ + int i; + if( !force && ( disk_trck != 82 || disk_sect != 22 )) + { + fprintf(stderr, "A bootable 2M disk must be 22 sectors 82 tracks\n"); + exit(1); + } + write_sector(bs_offset, buffer); + + /* This needs to be altered to allow for the disk format description to + be cpied from the old boot sector */ + + for(i=0; i<sysboot_dosfs_stat; i++) + buffer[i] = boot_sector_2m_22_82[i]; + for(i=sysboot_codestart; i<512; i++) + buffer[i] = boot_sector_2m_22_82[i]; + + write_sector(0, buffer); + + for(i=0; i<sizeof(program_2m_vsn_20); i+=512) + { + write_sector(bs_offset+i/512+1, program_2m_vsn_20+i); + } +} diff --git a/bootblocks/mbr.s b/bootblocks/mbr.s index f6a8048..ddd406f 100644 --- a/bootblocks/mbr.s +++ b/bootblocks/mbr.s @@ -14,6 +14,11 @@ preboot=0 ! Include the pre-boot loader ? org ORGADDR include sysboot.s +public partition_1 +public partition_2 +public partition_3 +public partition_4 + org ORGADDR+$3 .ascii "ELKS MBR Copyright 1996, Robert de Bath" diff --git a/bootblocks/monitor.c b/bootblocks/monitor.c index 5c78aaf..084f301 100644 --- a/bootblocks/monitor.c +++ b/bootblocks/monitor.c @@ -44,12 +44,20 @@ static char minibuf[2] = " "; struct t_cmd_list * cptr; #ifdef __STANDALONE__ - printf("\n\n"); + printf("\r"); #else if( argc > 1 && strcmp(argv[1], "-t") == 0 ) x86_test=0; else x86_test=1; #endif init_prog(); + if( __get_ds() != 0x1000 ) + { + relocator(-1); + relocator(1); + if( __get_ds() > 0x1000 ) relocator(2); + printf("Relocated to CS=$%04x DS=%04x\n", __get_cs(), __get_ds()); + } + #ifdef __STANDALONE__ if( (__argr.x.dx & 0xFF) == 0 ) #endif @@ -254,6 +262,38 @@ unsigned int * valptr; return flg; } +more_char(ch) +int ch; +{ +static int line_number = 0; + + if( ch == -1 ) { line_number = 0; return 0; } + + if( (ch & 0xE0 ) || ch == '\n' ) + putchar(ch); + if( ch == '\n' && ++line_number == 24) + { + char buf[4]; + printf("More ?"); fflush(stdout); + if( read(0, buf, 1) <= 0 ) return -1; + if( buf[0] == 3 || buf[0] == '\033' + || buf[0] == 'q' || buf[0] == 'Q' ) return -1; + if( buf[0] == '\r' ) line_number--; + if( buf[0] == ' ' ) line_number=2; + printf("\r \r"); + } + return 0; +} + +more_strn(str, len) +char * str; +int len; +{ + for(; len>0 && *str ; len--,str++) + if( more_char( *str & 0xFF ) < 0 ) return -1; + return 0; +} + /****************************************************************************/ int cmd_quit(args) @@ -337,13 +377,15 @@ int cmd_rel(ptr) char * ptr; { int nseg = 0xFFFF; + int cs = __get_cs(); getnum(&ptr, &nseg); - printf("Monitor code seg from 0x%04x ", __get_cs()); - fflush(stdout); relocator(nseg); - printf("to 0x%04x\n", __get_cs()); + if( __get_cs() == cs ) + printf("Didn't relocate; CS=$%04x DS=%04x\n", __get_cs(), __get_ds()); + else + printf("Relocated to CS=$%04x DS=%04x\n", __get_cs(), __get_ds()); } int cmd_dir(ptr) @@ -373,7 +415,38 @@ char * ptr; write(1, buffer, len); } else - printf("Cannout open file '%s'\n", fname); + printf("Cannot open file '%s'\n", fname); + close_file(); + return 0; +} + +int cmd_more(ptr) +char * ptr; +{ + char * fname; + char buffer[1024]; + long len; + int cc; + char * sptr; + + while(*ptr == ' ') ptr++; + if( (fname=ptr) == 0 ) return 0; + while(*ptr & *ptr != ' ') ptr++; + + more_char(-1); + + if( open_file(fname) >= 0 ) for(len=file_length(); len>0; len-=1024) + { + if( read_block(buffer) < 0 ) break; + if( len > 1024 ) cc = 1024; else cc = len; + for(sptr=buffer; cc>0 ; cc--,sptr++) + { + if( more_char(*sptr & 0xFF) < 0 ) goto break_break; + } + } + else + printf("Cannot open file '%s'\n", fname); +break_break:; close_file(); return 0; } @@ -395,8 +468,8 @@ struct t_cmd_list cmd_list[] = {"bzimage",cmd_bzimage}, /* Load and run 386 bzimage file */ {"=", cmd_bzimage}, /* Load and run 386 bzimage file */ {"dir", cmd_dir}, /* Display directory */ - {"type", cmd_type}, /* Cat/Type a file to the screen */ {"cat", cmd_type}, /* Cat/Type a file to the screen */ + {"more", cmd_more}, /* More a file to the screen */ /* Debugger/monitor commands */ {"memdump",cmd_memdump}, {"mem",cmd_memdump}, {"m", cmd_memdump}, diff --git a/bootblocks/msdos.s b/bootblocks/msdos.s index fdded78..a48718c 100644 --- a/bootblocks/msdos.s +++ b/bootblocks/msdos.s @@ -65,29 +65,31 @@ bios_disk: .blkb 12 cont: sti ! Let the interrupts back in. -! Need to fix BPB for fd0 to correct sectors (Like linux bootblock does) - mov di,#bios_disk - mov bp,#0x78 -! 0:bx is parameter table address - push ds - lds si,[bp] - -! ds:si is source - - mov cx,#6 -! copy 12 bytes - push di - rep - movsw - pop di - pop ds - -! New BPB is 0:di - mov [bp],di - mov 2[bp],ax - - mov al,[dos_spt] ! Finally, correct spt. - mov 4[di],al +! DONT Need to fix BPB for fd0 to correct sectors (Like linux bootblock does) +! as we only ever read one sector at a time. + +! mov di,#bios_disk +! mov bp,#0x78 +!! 0:bx is parameter table address +! push ds +! lds si,[bp] +! +!! ds:si is source +! +! mov cx,#6 +!! copy 12 bytes +! push di +! rep +! movsw +! pop di +! pop ds +! +!! New BPB is 0:di +! mov [bp],di +! mov 2[bp],ax +! +! mov al,[dos_spt] ! Finally, correct spt. +! mov 4[di],al ! For each sector in root dir ! For each dir entry diff --git a/bootblocks/nofs.c b/bootblocks/nofs.c deleted file mode 100644 index e671a69..0000000 --- a/bootblocks/nofs.c +++ /dev/null @@ -1,55 +0,0 @@ - -#ifndef __STANDALONE__ - -#include <sys/types.h> -#include <sys/stat.h> -#include "readfs.h" - -static int fd = -1; - -open_file(fname) -char * fname; -{ - if( fd >= 0 ) close(fd); - fd = open(fname, 0); - if( fd >= 0 ) return 0; - return -1; -} - -rewind_file() -{ - if( fd == -1 ) return -1; - lseek(fd, 0L, 0); - return 0; -} - -close_file() -{ - if( fd >= 0 ) close(fd); - fd = -1; -} - -long -file_length() -{ - struct stat st; - if( fd == -1 ) return -1; - if( fstat(fd, &st) < 0 ) return -1; - - return st.st_size; -} - -read_block(buffer) -char * buffer; -{ - int rv; - if( fd == -1 ) return -1; - - rv = read(fd, buffer, 1024); - if( rv <= 0 ) return -1; - if( rv < 1024 ) - memset(buffer+rv, '\0', 1024-rv); - return 0; -} - -#endif diff --git a/bootblocks/readfs.h b/bootblocks/readfs.h index aa6b87c..5a52bbb 100644 --- a/bootblocks/readfs.h +++ b/bootblocks/readfs.h @@ -15,3 +15,30 @@ int close_file P((void)); long file_length P((void)); int read_block P((char * buffer)); +int tar_open_file P((char * fname)); +int tar_rewind_file P((void)); +int tar_close_file P((void)); +long tar_file_length P((void)); +int tar_read_block P((char * buffer)); + +int min_open_file P((char * fname)); +int min_rewind_file P((void)); +int min_close_file P((void)); +long min_file_length P((void)); +int min_read_block P((char * buffer)); + +int dos_open_file P((char * fname)); +int dos_rewind_file P((void)); +int dos_close_file P((void)); +long dos_file_length P((void)); +int dos_read_block P((char * buffer)); + +#define read_sector(__sect) read_lsector((unsigned long)(__sect)) +char * read_lsector P((long sector)); +void reset_disk P((void)); + +extern char * track_buffer; +extern int disk_drive; +extern int disk_cyls; +extern int disk_heads; +extern int disk_spt; diff --git a/bootblocks/relocate.c b/bootblocks/relocate.c index 6101296..7f8b124 100644 --- a/bootblocks/relocate.c +++ b/bootblocks/relocate.c @@ -1,10 +1,22 @@ -#include <i86_funcs.h> +#include <stdio.h> +#include <dos.h> +#include "i86_funcs.h" static unsigned memseg = 0, memlen = 0; char buf[1]; +/* If newseg == 0x0000 => Lowest address CS=$50 + * If newseg == 0x0001 => DS to 64k position + * If newseg == 0x0002 => DS to 128k position + * ... + * If newseg == 0x0009 => DS to 576k position + * If newseg == 0xFFFF => Highest address leaving Linux-i386 clear. + * + * All others are literal, will fail if would overlap with something important. + */ + void relocator(newseg) unsigned newseg; @@ -27,12 +39,17 @@ unsigned newseg; __set_es(es); } + if( newseg == 0 ) newseg = 0x50; + if( newseg > 0 && newseg < 10 ) + { + newseg = (newseg<<12) - (__get_ds() - __get_cs()); + } if( newseg < 0x50 ) return; if( newseg == 0xFFFF ) { newseg = boot_mem_top; - if( newseg > 0x90000 ) newseg = 0x90000; + if( newseg > 0x9000 ) newseg = 0x9000; newseg -= memlen; } @@ -44,16 +61,14 @@ unsigned newseg; for(moved=0; moved < memlen; ) { unsigned int lump; - if( memlen <= 0x800 ) lump = memlen; else lump = 0x800; + if( memlen-moved <= 0x800 ) lump = memlen-moved; else lump = 0x800; __movedata(memseg+moved, 0, newseg+moved, 0, (lump<<4)); moved += lump; } /* re-link int 0x80, this one is only an example (used by 'standalone.c') */ - /* - __set_es(0); __doke_es(0x80*4+2, newseg); __set_es(es); - */ + /* __set_es(0); __doke_es(0x80*4+2, newseg); __set_es(es); */ /* The actual jump ... */ memseg = newseg; diff --git a/bootblocks/standalone.c b/bootblocks/standalone.c index 57634d4..3fb0e28 100644 --- a/bootblocks/standalone.c +++ b/bootblocks/standalone.c @@ -1,4 +1,5 @@ +#include <dos.h> #include <errno.h> #asm entry _int_80 ! Tell ld86 we really do need this file. diff --git a/bootblocks/sysboot.s b/bootblocks/sysboot.s index ee62e69..c7be509 100644 --- a/bootblocks/sysboot.s +++ b/bootblocks/sysboot.s @@ -53,10 +53,6 @@ codestart: j codestart ! Partition table -public partition_1 -public partition_2 -public partition_3 -public partition_4 public bootblock_magic .blkb sysboot_start+0x1BE-* diff --git a/bootblocks/tarboot.s b/bootblocks/tarboot.s index be68ecd..2e31570 100644 --- a/bootblocks/tarboot.s +++ b/bootblocks/tarboot.s @@ -148,9 +148,7 @@ blk_link: .byte 'V block blk_mode public sectors -sectors: .blkw 1 ! POSITION OF THIS FIELD IS MAGIC! - ! other programs know it's at pos 100 - +sectors: .blkw 1 ! bios_disk: .blkb 12 ! BPB for FD0 head: .word 0 ! current head track: .word 0 ! current track diff --git a/bootblocks/trk_buf.c b/bootblocks/trk_buf.c new file mode 100644 index 0000000..3039169 --- /dev/null +++ b/bootblocks/trk_buf.c @@ -0,0 +1,275 @@ + +#include <stdio.h> +#include <dos.h> +#include <ctype.h> +#include <malloc.h> +#include "readfs.h" + +int disk_drive = 0; +int disk_spt = 7; +int disk_heads = 2; +int disk_cyls = 0; + +static int last_drive = 0; +static int data_len = 0; +static long data_trk1 = 0; +static char * data_buf1 = 0; +static long data_trk2 = 0; +static char * data_buf2 = 0; + +static long bad_track = -1; /* Track number of last unsuccesful read */ + +static long get_dpt(); + +void reset_disk() +{ + if( data_buf1 ) free(data_buf1); + if( data_buf2 ) free(data_buf2); + data_buf1 = data_buf2 = 0; + last_drive = disk_drive; + + if( !(disk_drive & 0x80 ) ) + { + disk_spt = 7; /* Defaults for reading Boot area. */ + disk_heads = 2; + disk_cyls = 0; + } +#if defined(__MSDOS__) || defined(__STANDALONE__) + else + { + /* Hard disk, get parameters from bios */ + long dpt; + int v; + + disk_spt = 17; /* Defaults for reading Boot area. */ + disk_heads = 1; + disk_cyls = 0; + + dpt = get_dpt(disk_drive); + v = ((dpt>>16) & 0xFF); + if( v == 0xFF || v <= (disk_drive&0x7F) ) return; /* Bad dpt */ + + disk_spt = (dpt & 0x3F); /* Max sector number 1-63 */ + if( disk_spt == 0 ) disk_spt = 64; /* 1-64 ? */ + disk_heads = ((dpt>>24) & 0xFF) + 1; /* Head count 1-256 */ + disk_cyls = ((dpt>>8) & 0xFF) + ((dpt<<2) & 0x300) + 1; + + /* Cyls count, unchecked, only needs != 0, if AMI 386 bios can be + * upto 4096 cylinder, otherwise BIOS limit is 1024 cyl. + */ + } +#endif +} + +char * read_lsector(sectno) +long sectno; +{ + int tries = 6; + int rv; + + int phy_s = 1; + int phy_h = 0; + int phy_c = 0; + + if( disk_drive != last_drive ) reset_disk(); + + if( disk_spt < 0 || disk_spt > 63 || disk_heads < 1 ) + { + phy_s = sectno; + reset_disk(); + +#ifdef __ELKS__ + fprintf(stderr, "read_sector(%ld = %d,%d,%d)\n", + sectno, phy_c, phy_h, phy_s+1); +#endif + } + else + { + phy_s = sectno%disk_spt; + phy_h = sectno/disk_spt%disk_heads; + phy_c = sectno/disk_spt/disk_heads; + +#ifdef __ELKS__ + fprintf(stderr, "read_sector(%ld = %d,%d,%d)\n", + sectno, phy_c, phy_h, phy_s+1); +#endif + + if( fetch_track_buf(phy_c, phy_h, phy_s) >= 0 ) + return data_buf1 + (phy_s % data_len) * 512; + } + + data_len = -1; /* Zap the cache */ + if( data_buf1 == 0 ) + data_buf1 = malloc(512); + if( data_buf1 == 0 ) + { + printf("Cannot allocate memory for disk read!!!\n"); + return 0; + } + +#ifdef __ELKS__ + fprintf(stderr, "WARNING: Single sector read\n"); +#endif + + do + { + rv = phy_read(disk_drive, phy_c, phy_h, phy_s+1, 1, data_buf1); + tries--; + if( rv ) printf("Error in phy_read(%d,%d,%d,%d,%d,%d);\n", + disk_drive, phy_c, phy_h, phy_s+1, 1, data_buf1); + } + while(rv && tries > 0); + + if(rv) return 0; else return data_buf1; +} + +fetch_track_buf(phy_c, phy_h, phy_s) +int phy_c, phy_h, phy_s; +{ + long trk_no, t; + char * p; + int tries = 3; + int rv, nlen; + + /* Big tracks get us short of memory so limit it. */ + nlen = (disk_spt-1)/22; + nlen = (disk_spt+nlen)/(nlen+1); + trk_no = (long)phy_c*disk_heads*4+phy_h*4+phy_s/nlen+1; + + if( data_len != nlen ) + { + if( data_buf1 ) free(data_buf1); + if( data_buf2 ) free(data_buf2); + data_buf1 = data_buf2 = 0; + data_len = disk_spt; + } + if( trk_no == bad_track ) return -1; + + if( data_buf1 && trk_no == data_trk1 ) return 0; + + /* Two cases: + * 1) buffer2 has the one we want, need to swap to make it most recent + * 2) Neither has it, need to swap to overwrite least recent. + */ + + /* So we always swap */ + p = data_buf1; data_buf1 = data_buf2; data_buf2 = p; + t = data_trk1; data_trk1 = data_trk2; data_trk2 = t; + + /* The other one right ? */ + if( data_buf1 && trk_no == data_trk1 ) return 0; + + /* If we get here we have to do a physical read ... */ + /* into data_buf1. */ + + if( data_buf1 == 0 ) + { + data_buf1 = malloc(disk_spt*512); + +#ifdef __ELKS__ + fprintf(stderr, "Allocated buffer to %d\n", data_buf1); +#endif + } + if( data_buf1 == 0 ) + { + /* Is buf2 allocated ? Yes take it! */ + data_buf1 = data_buf2; data_buf2 = 0; data_trk2 = -1; + } + + bad_track = -1; + data_trk1 = -1; + + /* Not enough memory for track read. */ + if( data_buf1 == 0 ) return -1; + + do /* the physical read */ + { + rv = phy_read(disk_drive, phy_c, phy_h, phy_s/data_len+1, data_len, + data_buf1); + tries--; + if( rv ) printf("Error in phy_read(%d,%d,%d,%d,%d,%d);\n", + disk_drive, phy_c, phy_h, phy_s/data_len+1, data_len, data_buf1); + } + while(rv && tries > 0); + + /* Disk error, it'll try one at a time, _very_ slowly! */ + if(rv) + { + bad_track = trk_no; + return -1; + } + + /* Yes! */ + data_trk1 = trk_no; + return 0; +} + +#if defined(__MSDOS__) || defined(__STANDALONE__) +phy_read(drive, cyl, head, sect, length, buffer) +{ +#asm + push bp + mov bp,sp + + push es + push ds + pop es + + mov dl,[bp+2+_phy_read.drive] + mov ch,[bp+2+_phy_read.cyl] + mov dh,[bp+2+_phy_read.head] + mov bx,[bp+2+_phy_read.buffer] + + mov ax,[bp+2+_phy_read.cyl] ! Bits 10-11 of cylinder, AMI BIOS. + mov cl,#4 + sar ax,cl + and al,#$C0 + xor dh,al + + mov cl,[bp+2+_phy_read.sect] + and cl,#$3F + mov ax,[bp+2+_phy_read.cyl] ! Bits 8-9 of cylinder. + sar ax,#1 + sar ax,#1 + and al,#$C0 + or cl,al + + mov al,[bp+2+_phy_read.length] + mov ah,#$02 + int $13 + jc read_err + mov ax,#0 +read_err: + + pop es + pop bp +#endasm +} + +long +get_dpt(drive) +{ +#asm + push bp + mov bp,sp + + push di + push es + + mov dl,[bp+2+_get_dpt.drive] + + mov ah,#$08 + int $13 + jnc func_ok + mov cx,ax + mov dx,#-1 +func_ok: + mov ax,cx + + pop es + pop di + pop bp +#endasm +} +#endif + diff --git a/bootblocks/unix.c b/bootblocks/unix.c new file mode 100644 index 0000000..ec8ee89 --- /dev/null +++ b/bootblocks/unix.c @@ -0,0 +1,137 @@ + +#ifdef __ELKS__ + +#include <stdio.h> + +bios_khit() { + return 0; +} + +bios_getc() { + return 0; +} + +static int phy_fd = -1; + +static open_fd() +{ + phy_fd = open("/dev/fd0", 0); + if( phy_fd < 0 ) + fprintf(stderr, "Cannot open /dev/fd0\n"); +} + +phy_read(drive, cyl, head, sect, len, buffer) +int drive, cyl, head, sect, len; +char *buffer; +{ +extern long lseek(); + int rv = 0; + long offset; + int i; + + if( phy_fd == -1 ) open_fd(); + + offset = (((cyl*2 + head)*18L + sect-1)*512L); + + fprintf(stderr, "PHY_READ(d%d, c%d, h%d, s%d, l%d, b%d) (Sect=%ld)\n", + drive, cyl, head, sect, len, buffer, offset/512); + + if( lseek(phy_fd, offset, 0) < 0 ) + perror("Phyread lseek error\n"); + + + for(i=0; i< len; i++) + { + rv = read(phy_fd, buffer, 512); + if( rv < 0 ) + perror("Phyread read error\n"); + buffer+=512; + } + + if( rv < 0 ) return -1; + return 0; +} + +putsect(buffer, address) +char * buffer; +int address; +{ + fprintf(stderr, "Sector write from DS:%04x to 0000:%04x00\n", + buffer, address); + return 0; +} +#endif + +/* crctab calculated by Mark G. Mendel, Network Systems Corporation */ +static unsigned short crctab[256] = { + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, + 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, + 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, + 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, + 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, + 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, + 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, + 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, + 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, + 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, + 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, + 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, + 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, + 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, + 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, + 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, + 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, + 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, + 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, + 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, + 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, + 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, + 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 +}; + +/* + * updcrc macro derived from article Copyright (C) 1986 Stephen Satchell. + * NOTE: First srgument must be in range 0 to 255. + * Second argument is referenced twice. + * + * Programmers may incorporate any or all code into their programs, + * giving proper credit within the source. Publication of the + * source routines is permitted so long as proper credit is given + * to Stephen Satchell, Satchell Evaluations and Chuck Forsberg, + * Omen Technology. + */ + +#define updcrc(cp, crc) ( crctab[((crc >> 8) & 255)] ^ (crc << 8) ^ cp) + +static unsigned short crc = 0; + +reset_crc() +{ + crc = 0; +} + +addcrc(buffer, len) +unsigned char * buffer; +int len; +{ + while(len>0) + { + crc = updcrc((*buffer++), crc); + len--; + } +} + +display_crc() +{ + printf("Image CRC value = %u\n", crc); +} + |