summaryrefslogtreecommitdiff
path: root/bootblocks
diff options
context:
space:
mode:
authorRobert de Bath <rdebath@poboxes.com>1998-02-01 11:26:21 +0100
committerLubomir Rintel <lkundrak@v3.sk>2013-10-23 23:40:14 +0200
commit48f0b3eb836162d41622cedc1eb5f5168168fb8e (patch)
treec53156383d4682a0a296f6611575dbc1d64d1881 /bootblocks
parent48798bf2eb93ec3b99720ac2e16093441156653d (diff)
downloaddev86-48f0b3eb836162d41622cedc1eb5f5168168fb8e.tar.gz
Import Dev86src-0.13.5.tar.gzv0.13.5
Diffstat (limited to 'bootblocks')
-rw-r--r--bootblocks/Makefile14
-rw-r--r--bootblocks/bzimage.c197
-rw-r--r--bootblocks/fs.c81
-rw-r--r--bootblocks/fs_dos.c (renamed from bootblocks/dosfs.c)291
-rw-r--r--bootblocks/fs_min.c31
-rw-r--r--bootblocks/fs_tar.c156
-rw-r--r--bootblocks/i86_funcs.c1
-rw-r--r--bootblocks/makeboot.c348
-rw-r--r--bootblocks/mbr.s5
-rw-r--r--bootblocks/monitor.c85
-rw-r--r--bootblocks/msdos.s48
-rw-r--r--bootblocks/nofs.c55
-rw-r--r--bootblocks/readfs.h27
-rw-r--r--bootblocks/relocate.c27
-rw-r--r--bootblocks/standalone.c1
-rw-r--r--bootblocks/sysboot.s4
-rw-r--r--bootblocks/tarboot.s4
-rw-r--r--bootblocks/trk_buf.c275
-rw-r--r--bootblocks/unix.c137
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);
+}
+