diff -ruN ./elkscomp/elkscmd/Make.defs ./elkscurr/elkscmd/Make.defs --- ./elkscomp/elkscmd/Make.defs 2002-03-03 18:17:05.000000000 -0500 +++ ./elkscurr/elkscmd/Make.defs 2004-07-12 19:46:51.000000000 -0400 @@ -147,7 +147,7 @@ MKFS=/sbin/mkfs.minix MKFS_OPTS=-n14 -MINIX_BOOT=$(DEV86_DIR)/bootblocks +BOOTBLOCKS_DIR=./bootblocks ############################################################################## # diff -ruN ./elkscomp/elkscmd/Makefile ./elkscurr/elkscmd/Makefile --- ./elkscomp/elkscmd/Makefile 2004-06-09 12:25:40.000000000 -0400 +++ ./elkscurr/elkscmd/Makefile 2004-07-12 19:50:57.000000000 -0400 @@ -30,9 +30,9 @@ # # State location of boot sector and boot helper. -FD_BSECT = $(MINIX_BOOT)/minix.bin +FD_BSECT = $(BOOTBLOCKS_DIR) minix.bin -KHELPER = $(MINIX_BOOT)/minix_elks.bin +KHELPER = $(BOOTBLOCKS_DIR) minix_elks.bin ############################################################################### # @@ -46,12 +46,8 @@ $(FULL3_TARGET_FS) $(FULL5_TARGET_FS) || true rm -f $(COMB_TARGET_FS) $(ROOT_TARGET_FS) $(ROOT_NET_TARGET_FS) \ $(FULL3_TARGET_FS) $(FULL5_TARGET_FS) boot images.zip core @for i in $(DIRS); do make -C $$i clean ; done + make -C $(BOOTBLOCKS_DIR) clean ############################################################################### # # Create relevant parts of ELKS package. $(ELKS_DIR)/.config: @@ -121,11 +93,10 @@ # Create relevant parts of other packages. $(FD_BSECT): - make -C $(MINIX_BOOT) - make -C $(MINIX_BOOT) minix.bin + make -C $(BOOTBLOCKS_DIR) minix.bin $(KHELPER): - make -C $(MINIX_BOOT) + make -C $(BOOTBLOCKS_DIR) minix_elks.bin ############################################################################### # diff -ruN ./elkscomp/elkscmd/bootblocks/Makefile ./elkscurr/elkscmd/bootblocks/Makefile --- ./elkscomp/elkscmd/bootblocks/Makefile 1969-12-31 19:00:00.000000000 -0500 +++ ./elkscurr/elkscmd/bootblocks/Makefile 2004-07-12 19:37:25.000000000 -0400 @@ -0,0 +1,143 @@ + +HOSTCC=cc +HOSTCCFLAGS=-O +BCC=bcc +AS86=as86 + +DEFS= +CC=$(BCC) +CFLAGS=-ansi -Ms -Oi -O $(DEFS) +LDFLAGS=-s -i -H0x10000 +ASFLAGS=-0 -w +MINIXDEFS=-DDOTS +# CFLAGS=-ansi -Ms $(DEFS) +# LST=-l $*.lst + +default: makeboot makeboot.com monitor.sys minix_elks.bin lsys.com + +all: bootbin bootsys default tgz + +bootsys: bootfile.sys boottar.sys bootminix.sys monitor.sys boot_win.sys + +CSRC=minix.c +SSRC=sysboot.s tarboot.s skip.s mbr.s msdos.s noboot.s \ + boot_fpy.s killhd.s bb_linux.s bb_init1.s bb_init2.s + +encap: $(SSRC:s=v) $(CSRC:c=v) minixhd.v msdos16.v +bootbin: $(SSRC:s=bin) $(CSRC:c=bin) minixhd.bin msdos16.bin minix_elks.bin + +MOBJ=monitor.o commands.o i86_funcs.o relocate.o help.o bzimage.o \ + buffer.o unix.o fs.o fs_tar.o fs_min.o fs_dos.o +MSRC=monitor.c commands.c i86_funcs.c relocate.c help.c bzimage.c \ + buffer.c unix.c fs.c fs_tar.c fs_min.c fs_dos.c +MINC=i86_funcs.h readfs.h monitor.h + +BOOTBLOCKS=sysboot.v noboot.v skip.v msdos.v msdos16.v \ + tarboot.v minix.v minixhd.v mbr.v killhd.v + +EXTRAS=minix.h zimage.s minix_elks.c lsys.c boot_win.c + +install: makeboot + install -m 755 -s makeboot $(DIST)$(PREFIX)/bin/makeboot + +monitor.com: $(MOBJ) + $(CC) $(CFLAGS) $(LDFLAGS) $(MONDEFS) -d $(MOBJ) -o monitor.com -M > monitor.sym + +monitor.out: $(MOBJ) + $(CC) $(CFLAGS) $(LDFLAGS) $(MONDEFS) $(MOBJ) -o monitor.out -M > monitor.sym + +$(MOBJ): $(MINC) +fs_min.o: minix.h + +bootfile.sys: $(MSRC) $(MINC) + @rm -f $(MOBJ) + make 'CFLAGS=$(CFLAGS) -DDOSFLOPPY' monitor.out + mv monitor.out bootfile.sys + @rm -f $(MOBJ) + +boottar.sys: $(MSRC) $(MINC) tarboot.bin + @rm -f $(MOBJ) + make 'CFLAGS=$(CFLAGS) -DTARFLOPPY' monitor.out + mv monitor.out boottar.sys + @rm -f $(MOBJ) + +bootminix.sys: $(MSRC) $(MINC) minix.bin + @rm -f $(MOBJ) + make 'CFLAGS=$(CFLAGS) -DMINFLOPPY' monitor.out + mv monitor.out bootminix.sys + @rm -f $(MOBJ) + +monitor.sys: $(MSRC) $(MINC) + @rm -f $(MOBJ) + make monitor.out + mv monitor.out monitor.sys + @rm -f $(MOBJ) + +monitor: $(MSRC) $(MINC) + @rm -f $(MOBJ) + make 'CFLAGS=-ansi $(DEFS)' monitor.out + mv monitor.out monitor + @rm -f $(MOBJ) + +bzimage.o: bzimage.c zimage.v + +minix.s: minix.c Makefile + $(CC) -Mf -O -DTRY_FLOPPY $(MINIXDEFS) -S minix.c + +minix_elks.s: minix_elks.c Makefile minix.v + $(CC) -Mf -O $(MINIXDEFS) -S minix_elks.c + +minixhd.s: minix.c Makefile + $(CC) -Mf -O -DHARDDISK $(MINIXDEFS) -S minix.c -o minixhd.s + +msdos16.s: msdos.s + sed 's/^fatbits=12/fatbits=16/' < msdos.s > msdos16.s + +mbr_dm.s: mbr.s + sed -e 's/^diskman=0/diskman=1/' \ + -e 's/^message=1/message=0/' \ + -e 's/^mbrkey=1/mbrkey=0/' \ + -e 's/^preboot=1/preboot=0/' \ + < mbr.s > mbr_dm.s + +boot_win.sys: boot_win.c + $(CC) -Ms -H0x6000 -s boot_win.c -o boot_win.sys + +makeboot: makeboot.c $(BOOTBLOCKS) + $(HOSTCC) $(HOSTCCFLAGS) -o makeboot makeboot.c + +makeboot.com: makeboot.c $(BOOTBLOCKS) + $(CC) -Md -O -o makeboot.com makeboot.c + +lsys.com: lsys.c msdos.v msdos16.v + $(CC) -Md -O -o lsys.com lsys.c + +clean realclean: + rm -f bootfile.sys boottar.sys bootminix.sys monitor.sys boot_win.sys + rm -f monitor makeboot bootblocks.tar.gz + rm -f minix.s minixhd.s minix_elks.s msdos16.s mbr_dm.s + rm -f *.com *.o *.bin *.out *.lst *.sym *.v *.tmp + +tgz: minix.bin monitor.sys makeboot.com makeboot + tar cfV bootblocks.tar ENIAC monitor.sys \ + README Makefile \ + $(MSRC) \ + $(MINC) \ + makeboot.c $(CSRC) \ + $(SSRC) \ + makeboot.com minix.bin \ + $(EXTRAS) + makeboot tar bootblocks.tar + gzip -f9 bootblocks.tar + +distribution: + tar czf /tmp/bootblocks.tar.gz \ + README Makefile $(MSRC) $(MINC) makeboot.c $(CSRC) $(SSRC) $(EXTRAS) + +.SUFFIXES: .bin .v + +.s.bin: + $(AS86) -w- -0 -b $*.bin -s $*.sym $*.s $(LST) + +.s.v: + as86_encap $*.s $*.v $*_ $(ASFLAGS) $(LST) diff -ruN ./elkscomp/elkscmd/bootblocks/minix.c ./elkscurr/elkscmd/bootblocks/minix.c --- ./elkscomp/elkscmd/bootblocks/minix.c 1969-12-31 19:00:00.000000000 -0500 +++ ./elkscurr/elkscmd/bootblocks/minix.c 2004-07-12 19:37:14.000000000 -0400 @@ -0,0 +1,943 @@ +/* + * This bootblock loads the linux-8086 executable in the file 'boot' + * from the root directory of a minix filesystem. + * + * Copyright (C) 1990-1998 Robert de Bath, distributed under the GPL Version 2 + * Based on minix filesystem definitions. + * + * TODO: + * Alter nogood() to do a mov sp,... so the helper program can override + * the panic message. + */ + +#include +#include "minix.h" + +/* #define DOTS /* define to have dots printed */ +/* #define HARDDISK /* Define for hard disk version */ +/* #define TRY_FLOPPY /* To do trial reads to find floppy size */ + +/* #define MIN_SPACE */ + +#define zone_shift 0 /* for any < 32M (!= 0 not supported yet, if ever) */ +#define seg_at(k) ((k)*64) +#define seg_of(p) ((unsigned int)p >>4) +#define BOOTSEG (0x07c0) +#define LOADSEG (0x1000) +#define ORGADDR (0x0500) + +#ifdef HARDDISK +#define get_now() +#endif + +#ifdef zone_shift +#if zone_shift == 0 +#define load_zone load_block +#endif +#else +static short zone_shift; +#endif + +#asm +BOOTADDR = 0x7c00 + +.text +! Apparently on startup the only things we can assume are that we start at +! `start` (ABS addr $07C00) and the boot sector is in the segment. + +! So first set CS=DS=ES=SS=0 +! The we move this to $0500 and put the stack at the top of the first 64k. +! The directory 'file' is loaded $1500 and scanned there. +! The final executable will be loaded in the 2nd 64k chunk. +! +org ORGADDR ! The lowest available address. +start: +#ifndef MIN_SPACE + include sysboot.s + +org start ! The lowest available address, again. + j skip_vars + +org dos_sysid + .ascii "MINIXFS BOOT (C) 1990-1999, Robert de Bath" + + org codestart +#endif + +! A few variables we need to know the positions of for patching, so export +! them and as86_encaps will make some variables. Put them here at the start +! so they're in the same place for both Floppy and harddisk versions as they +! will be used by helper programs. + +export inode ! Inode to search +inode: +_inode: .word 1 ! ROOT_INODE + +#ifndef MIN_SPACE +export dinode ! Inode of directory file was found in. +dinode: +_dinode: .word 1 ! ROOT_INODE +#endif + +export bootfile ! File to boot, make this whatever you like, +bootfile: ! 'boot' is good, 'linux' too. +_bootfile: + .ascii "boot" + .byte 0,0,0,0,0,0,0,0,0,0 + +skip_vars: +#ifdef HARDDISK + mov bx,[si+8] ! Fetch the linear address of part from DS:SI + mov dh,[si+10] ! DL is drive number +#endif + + xor ax,ax ! All segments are zero, first 64k of mem. + mov ds,ax + mov es,ax + mov ss,ax + mov sp,ax + +#ifndef HARDDISK +loopy: + mov ax,#$0203 ! Read 3 sectors, code + superblock. + mov bx,#start ! Where this _should_ be + mov cx,#$0001 ! From sector 1 + xor dx,dx ! Of the floppy drive head zero + int $13 + jc loopy +#else + + mov cx,#$100 ! Move 256 words + mov si,#BOOTADDR ! From default BB + mov di,#ORGADDR ! To the correct address. + rep + movsw + + xchg dl,dh + mov [bootpart],bx ! Save the partition sector offset (and drive) + mov [bootpart+2],dx + + ! Read next 2 sectors of hd. + xor dx,dx + mov cx,#1 + mov bx,#ORGADDR+$200 + mov al,#2 + + call load_sect +#endif + + jmpi code,#0 + +#endasm + +/* /* */ +/****************************************************************************/ +/* Section cdef */ +/****************************************************************************/ + +/* The name of the file and inode to start */ +extern char bootfile[]; +extern inode_nr inode; +extern inode_nr dinode; + +/* For multi-sector reads */ +extern sect_nr lastsect; +extern sect_nr firstsect; +extern unsigned loadaddr; +extern unsigned loadcount; + +/* Keep track of zones to load */ +extern zone_nr * next_zone; +extern zone_nr * end_zone; +extern zone_nr indirect; + +/* Where to load zones */ +extern unsigned ldaddr; + +/* Directory reading */ +extern dir_struct * dirptr; +extern unsigned flength; +extern unsigned dir_32; + +#ifndef HARDDISK +/* The 'shape' of the floppy - intuit from superblock or try to read max */ +extern unsigned n_sectors; +#endif + +extern struct super_block b_super; +extern d_inode b_inode[INODES_PER_BLOCK]; +extern zone_nr b_zone[NR_INDIRECTS]; +extern dir_struct directory[]; + +/* /* */ +/****************************************************************************/ +/* Section adef */ +/****************************************************************************/ + +#asm +.text + +#ifdef HARDDISK +bootpart: .long 0 +#else +_loadcount: .word 0 +_firstsect: .word 0 +_loadaddr: .word 0 +_lastsect: .word 0 +#endif + + block start+0x400 +_b_super: .blkb 512 + +#ifndef MIN_SPACE +export helper +helper: .blkb 1024 +export helper_end +helper_end: +#endif + +_b_inode: .blkb 1024 +_b_zone: .blkb 1024 + +#ifdef MIN_SPACE +temp_space: .blkb 512 +#endif +probe_buf: +_directory: .blkb 32768 + endb + +#endasm + +/* /* */ +/****************************************************************************/ +/* Section nogood */ +/****************************************************************************/ +/* #if defined(HARDDISK) && !defined(SKIPBOOT) */ +#ifndef SKIPBOOT +static +nogood() +{ +#asm + mov si,#fail_fs +min_nextc: + lodsb + cmp al,#0 + jz min_eos + mov bx,#7 + mov ah,#$E ! Can't use $13 cause that's AT+ only! + int $10 + jmp min_nextc +min_eos: ! Wait for a key then reboot + xor ax,ax + int $16 + jmpi $0,$FFFF ! Reboot. + +fail_fs: + .byte 13,10 +#if defined(HARDDISK) + .asciz "Initial boot failed, press return to reboot\r\n" +#else + .asciz "Boot failed:" +#endif +#endasm +} + +#else + +static +nogood() +{ +/* This didn't work, chain the boot sector of the HD */ +#asm + push cs + pop es +hcode: + mov ax,#$0201 ! Read 1 sector + mov bx,#BOOTADDR ! In the boot area + mov cx,#$0001 ! From sector 1 + mov dx,#$0080 ! Of the hard drive head zero + int $13 + jc hcode ! Keep trying forever! + jmpi BOOTADDR,0 +#endasm +} +#endif + +/* /* */ +/****************************************************************************/ +/* Section hd_sect */ +/****************************************************************************/ +#ifdef HARDDISK +#asm +! +! Load AL sectors from linear sector DX:CX into location ES:BX +! Linear sector zero is at [bootpart] +! This loads one sector at a time, but that's OK cause even in the _very_ +! worst case it'll take no more that 5 seconds to load a 16 bit executable. +! +load_sect: + add cx,[bootpart] + adc dx,[bootpart+2] +moresect: + cmp al,#0 + jnz onesect + clc + ret + +! Load one sector... +onesect: + push ax ! Save lots + push di + push si + push cx ! Drive and sector. + push dx + + push es ! Load location + push bx + + push cx ! Drive and sector again. + push dx + + ! Fetch drive 'shape' + mov ah,#8 + mov dl,dh + int $13 ! DX:CX = drive specification + jc _nogood + + and cx,#$3F ! Get sector count => DI + mov di,cx + + xor dl,dl ! Get head count => SI + xchg dl,dh + inc dx + mov si,dx + + pop dx ! Get back drive and sector + pop ax + + mov bl,dh ! Save drive + xor dh,dh + + div di ! DX=sector, AX=track number + mov cx,dx + inc cl ! CL=sector number + + xor dx,dx + div si ! DX=head, AX=cylinder + + mov dh,dl + mov dl,bl ! DX for int 1302 + + xchg al,ah + ror al,#1 + ror al,#1 + or cx,ax ! CX for int 1302 + + pop bx ! ES:BX for int 1302 + pop es + + mov di,#5 ! Lots of retries for a hd +retry: + mov ax,#$0201 + int $13 + jnc got_hd_sect + + xor ax,ax ! Reset between each try. + int $13 + + dec di + jnz retry + br _nogood + +got_hd_sect: + pop dx + pop cx + pop si + pop di + pop ax + + dec al + add cx,#1 + adc dh,#0 + add bh,#2 + jmp moresect +#endasm +#endif + +/****************************************************************************/ +/* This is the end of the parts that MUST be in the first sector */ +/* From here down the functions can safely be in any order. */ +/****************************************************************************/ + +/* /* */ +/****************************************************************************/ +/* Section fd_block */ +/****************************************************************************/ +#ifndef HARDDISK +static +load_block(address, blkno) +unsigned address, blkno; +{ + register sect_nr sectno; + if(blkno == 0) { zero_block(address); return; } +#ifdef DOTS + prt_dot(); +#endif + + sectno = (sect_nr)blkno * 2; + load_sect(address, sectno); + load_sect(address+32, sectno+1); +} +#endif + +/****************************************************************************/ +/* Section fd_bpb */ +/****************************************************************************/ +#ifndef HARDDISK +#asm +_set_bpb: +#ifdef MIN_SPACE +bios_tabl=temp_space ! Temp space. +bios_disk=temp_space+4 ! +#else +bios_tabl=dosfs_stat ! Temp space. +bios_disk=dosfs_stat+4 ! +#endif + +#ifndef __CALLER_SAVES__ + push si + push di +#endif + + mov di,#bios_disk + mov bx,#0x78 +! 0:bx is parameter table address + + push ds + push di + + mov si,[bx] + mov ax,[bx+2] + mov [bios_tabl],si + mov [bios_tabl+2],ax + push ax + + pop ds +! ds:si is source + +! copy 12 bytes + mov cl,#6 + cld + rep + movsw + + pop di + pop ds + mov ax,[_n_sectors] + movb 4[di],al ! patch sector count + + mov [bx],di + mov 2[bx],es + +#ifndef __CALLER_SAVES__ + pop si + pop di +#endif + ret + +_unset_bpb: +! 0:0x78 is parameter table address + + mov ax,[bios_tabl] + mov [0x78],ax + mov ax,[bios_tabl+2] + mov [0x78+2],ax + ret + +#endasm +#endif + +/****************************************************************************/ +/* Section fd_get_now */ +/****************************************************************************/ +#ifndef HARDDISK +static +get_now() +{ +#asm + mov si,#5 +retry_get: + xor dx,dx + mov cx,[_firstsect] + shr ch,#1 + adc dh,#0 + mov es,[_loadaddr] + xor bx,bx + mov ax,[_loadcount] + test ax,ax + jz no_load + mov ah,#2 + int $13 ! Try fetch + jnc no_load + xor ax,ax ! Bad, retry. + int $13 + dec si + jnz retry_get + br _nogood +no_load: + xor ax,ax + mov [_loadcount],ax +#endasm +} +#endif + +/****************************************************************************/ +/* Section fd_probe */ +/****************************************************************************/ +#ifndef HARDDISK +#ifdef TRY_FLOPPY +#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. + +_probe_sectors: + mov si,#disksizes ! table of sizes to try + +probe_loop: + lodsb + cbw ! extend to word + mov _n_sectors, 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 +#else +probe_sectors() +{ + /* Guess the number of sectors based on the size of the file system */ + if( (n_sectors = b_super.s_nzones / 40) > 11 ) n_sectors /= 2; +} +#endif +#endif + +/****************************************************************************/ +/* Section fd_sect */ +/****************************************************************************/ +#ifndef HARDDISK +static +load_sect(address, sectno) +unsigned address; +sect_nr sectno; +{ + register sect_nr nsect; + + nsect = sectno%n_sectors +1; + sectno /= n_sectors; + nsect |= (sectno<<8); + + if( loadcount ) + { + lastsect++; + if( ( address & 4095 ) && nsect == lastsect ) + { + loadcount++; + return; + } + get_now(); + } + + lastsect = firstsect = nsect; + loadaddr = address; + loadcount = 1; +} +#endif + +/****************************************************************************/ +/* Section fd_zeroblk */ +/****************************************************************************/ +#ifndef HARDDISK +static +zero_block(address) +{ +#asm +#if __FIRST_ARG_IN_AX__ + mov es,ax +#else + mov bx,sp + mov es,[bx+2] +#endif + push di + mov cx,#512 + xor ax,ax + mov di,ax + rep + stosw + pop di +#endasm +} +#endif + +/****************************************************************************/ +/* Section hd_block */ +/****************************************************************************/ +#ifdef HARDDISK +/*----------------------------------*/ +/* Hard disk block driver */ +/*----------------------------------*/ + +#asm +_load_block: + push bp + mov bp,sp +#if __FIRST_ARG_IN_AX__ + ! Fetch load location + mov es,ax + + ! Test for block zero + mov ax,4[bp] +#else + ! Fetch load location + mov ax,[bp+4] + mov es,ax + + ! Test for block zero + mov ax,6[bp] +#endif + test ax,ax + jne real_block + + ! Iff block zero, zap memory + push di + mov cx,#512 + xor ax,ax + mov di,ax + rep + stosw + pop di + +func_exit: + mov sp,bp + pop bp + ret + +real_block: +#ifdef DOTS + push ax + call _prt_dot + pop ax +#endif + +! Load a real block. + mov cx,ax + xor dx,dx + shl cx,#1 + rcl dx,#1 + + xor bx,bx + mov al,#2 + call load_sect + + j func_exit +#endasm +#endif + +/****************************************************************************/ +/* Section main */ +/****************************************************************************/ +#asm +code: + call _loadprog + call _runprog + br _nogood + +#endasm + +/****************************************************************************/ +/* Section prt_dots */ +/****************************************************************************/ +#ifdef DOTS +#asm +_prt_crlf: + mov al,#13 + call outch + mov al,#10 + j outch +_prt_dot: + mov al,#'. +outch: + mov ah,#$0E + mov bx,#7 + int $10 + ret +#endasm +#endif + +/****************************************************************************/ +/* Section end_1 */ +/****************************************************************************/ +#if defined(HARDDISK) || !defined(MIN_SPACE) +#asm +end_of_part1: +#ifdef HARDDISK + if *>start+0x1FE ! Leave space for magic +#else + if *>start+0x200 +#endif + fail! Part 1 too large! + endif + .blkb 0x200+start-* +#endasm +#endif + +/****************************************************************************/ +/* Section prog_load */ +/****************************************************************************/ + +loadprog() +{ +#ifdef DOTS + prt_dot(); +#endif + if( b_super.s_magic == SUPER_MAGIC2 ) + dir_32 = 1; + else if( b_super.s_magic == SUPER_MAGIC ) + dir_32 = 0; + else + nogood(); + +#ifdef zone_shift + if( zone_shift != b_super.s_log_zone_size) nogood(); +#else + zone_shift = b_super.s_log_zone_size; +#endif + +#ifndef HARDDISK + probe_sectors(); + + /* if( (n_sectors = b_super.s_nzones / 40) > 11 ) n_sectors /= 2; */ + + set_bpb(); +#endif + +try_again:; + inode--; + load_block(seg_of(b_inode), inode/INODES_PER_BLOCK + + b_super.s_imap_blocks + + b_super.s_zmap_blocks + + 2); + get_now(); + + ldaddr = LOADSEG; /* Load at 64k mark */ + + { + register d_inode * i_ptr; + i_ptr = b_inode + inode%INODES_PER_BLOCK; + next_zone = i_ptr->i_zone; + flength = i_ptr->i_size; + if( (i_ptr->i_mode & I_TYPE) == I_DIRECTORY ) + { + ldaddr = seg_of(directory); +#ifndef MIN_SPACE + dinode = inode+1; /* Remember current directory */ +#endif + inode = 0; /* Mark - we've no _file_ inode yet */ + } + } + + end_zone = next_zone+NR_DZONE_NUM; + load_zone(seg_of(b_zone), (indirect = next_zone[NR_DZONE_NUM])); + get_now(); + + for(;;) + { + if( next_zone >= end_zone ) + { + if( indirect != 0 ) + { + next_zone = b_zone; + end_zone = next_zone + NR_INDIRECTS; + indirect = 0; + continue; + } + break; + } + load_zone(ldaddr, *next_zone); + next_zone++; + ldaddr += (seg_at(1) << zone_shift); + } + get_now(); + +#ifdef DOTS + prt_crlf(); +#endif + if(!inode) + { + dirptr = directory; + while(flength > 0) + { +register char * s = bootfile; +register char * p = dirptr->d_name; + + if( dirptr->d_inum ) + { + for(;;) + { + if( *s == '\0') + { + if(*p == '\0') + { + inode = dirptr->d_inum; + goto try_again; + } + break; + } + if( *s++ != *p++ ) break; + } + } + flength -= 16; + dirptr++; + if( dir_32 ) + { + flength -= 16; + dirptr++; + } + } + nogood(); + } +#ifndef HARDDISK + unset_bpb(); +#endif +} + +/****************************************************************************/ +/* Section prog_run */ +/****************************************************************************/ +static +runprog() +{ +/* It all worked, run the loaded executable */ +#asm +#ifdef HARDDISK + mov dx,[bootpart+2] + xchg dh,dl ! DX => hard drive + push [bootpart] ! CX => partition offset + xor si,si +#else + xor dx,dx ! DX=0 => floppy drive + push dx ! CX=0 => partition offset = 0 + mov si,[_n_sectors] ! Save for monitor.out +#endif + + mov bx,#LOADSEG + mov ds,bx ! DS = loadaddress + xor di,di ! Zero + mov ax,[di] + cmp ax,#0x0301 ! Right magic ? + jnz binfile ! Yuk ... assume .SYS + inc bx + inc bx ! bx = initial CS + mov ax,[di+2] + and ax,#$20 ! Is it split I/D ? + jz impure ! No ... + mov cl,#4 + mov ax,[di+8] + shr ax,cl +impure: + pop cx + add ax,bx + mov ss,ax + mov sp,[di+24] ! Chmem value + mov ds,ax +binfile: + + push bx + push di ! jmpi 0,#LOADSEG+2 + retf +#endasm +} + +/****************************************************************************/ +/* Section sys_libs */ +/****************************************************************************/ +#asm +! These functions are pulled from the C library. +libstuff: +imodu: + xor dx,dx + div bx + mov ax,dx ! instruction queue full so xchg slower + ret +idiv_u: + xor dx,dx + div bx + ret +#ifndef zone_shift +isl: +islu: + mov cl,bl + shl ax,cl + ret +#endif +libend: +#endasm + +/****************************************************************************/ +/* Section sys_vars */ +/****************************************************************************/ +#asm +#ifdef MIN_SPACE + block temp_space+64 +#endif +vars: +#ifndef HARDDISK +_n_sectors: .blkw 1 +#endif +_next_zone: .blkw 1 +_end_zone: .blkw 1 +_indirect: .blkw 1 +_ldaddr: .blkw 1 +_dirptr: .blkw 1 +_flength: .blkw 1 +_dir_32: .blkw 1 +varend: +#ifdef MIN_SPACE + endb +#endif +#endasm + +/****************************************************************************/ +/* Section end_2 */ +/****************************************************************************/ +#asm +end_of_prog: + if *>start+0x400 + fail! Part 2 too large! + endif + + if end_of_prog