diff options
author | Robert de Bath <rdebath@poboxes.com> | 1999-01-23 13:29:22 +0100 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2013-10-23 23:40:39 +0200 |
commit | e62b35169cdcd13632ae353b1e5ffde7dec44201 (patch) | |
tree | 2646548ca84edb365354a6e68459f92943532cee | |
parent | 2233d47f9d89c107b6c425626d6eb2669363b055 (diff) | |
download | dev86-e62b35169cdcd13632ae353b1e5ffde7dec44201.tar.gz |
Import Dev86src-0.14.7.tar.gzv0.14.7
72 files changed, 2381 insertions, 549 deletions
@@ -1,5 +1,9 @@ For version 0.15.0. +> A bit more in the manpages on how to use the assembler etc. + +> Bug fixes in stdio, fp->mode cached too much, buffer type mixup. + > Altered initial make variables, you only need to modify 'PREFIX=' to allow installs into /usr/local. @@ -12,19 +16,17 @@ For version 0.15.0. > I appear to have bcc generating a consistant set of code fragments for floating point operations. No floating libs though ... -> Added lsys.com to install the dosfs boot sector under dos. - -> monitor.out now (finally!) loads zImage files. - -> Monitor.out now works with a TAR "filesystem" on a floppy. - -> Added two conpile time options (-DTARFLOPPY and -DDOSFLOPPY) for smaller - executables to only boot linux-386 from a floppy. - -> Makeboot can install the mbr. - -> Removed the ELKS specific code from the minixfs loader, added a helper - program to load and relocate ELKS. +> Lots of bootblocks changes including + Added lsys.com to install the dosfs boot sector under dos. + monitor.out now (finally!) loads zImage files. + Monitor.out now works with a TAR "filesystem" on a floppy. + Added two conpile time options (-DTARFLOPPY and -DDOSFLOPPY) for smaller + executables to only boot linux-386 from a floppy. + Makeboot can install the mbr. + Removed the ELKS specific code from the minixfs loader, added a helper + program to load and relocate ELKS. + One config file for booting a [b]zImage. + DOSFS boot can boot any named file. > Fixed/avoided some problems with the optimiser breaking hand optimised code. @@ -35,6 +37,8 @@ For version 0.15.0. > Added some more library code for MSDOS programs, there's still more to go. +> Removed the 'libc-8086' distribution tgz file. + For version 0.14.0. > Objdump86 utility added, also includes nm86 and size86 that work on diff --git a/Contributors b/Contributors index 7b935e7..6fd51bc 100644 --- a/Contributors +++ b/Contributors @@ -32,3 +32,4 @@ Dale Schumacher <dal@syntel.UUCP> Wietse Venema <wietse@wzv.win.tue.nl> Joel Weber II <nemo@koa.iolani.honolulu.hi.us> Claudio Matsuoka <claudio@pos.inf.ufpr.br> +Andrew Chittenden <achitten@madge.com> diff --git a/Libc_version b/Libc_version index 436d0ce..c24a395 100644 --- a/Libc_version +++ b/Libc_version @@ -1 +1 @@ -0.14.5 +0.14.7 @@ -100,13 +100,6 @@ distribution: cd /tmp &&\ VER=`cat linux-86/Libc_version` &&\ - ln -s linux-86/libc libc-$$VER &&\ - tar cf Dist/libc-8086-$$VER.tar libc-$$VER/* &&\ - rm libc-$$VER - gzip -f9 /tmp/Dist/libc-8086-*.tar & - - cd /tmp &&\ - VER=`cat linux-86/Libc_version` &&\ $(MAKE) -C /tmp/linux-86 install \ ARFLAGS=q DIST=/tmp/linux-86-dist ELKSSRC=/dev/null &&\ $(MAKE) -C /tmp/linux-86 other &&\ diff --git a/as/assemble.c b/as/assemble.c index c631905..5ae7319 100644 --- a/as/assemble.c +++ b/as/assemble.c @@ -215,7 +215,11 @@ PRIVATE void asline() readline(); getsym(); if (sym != IDENT) /* expect label, mnemonic or macro */ - return; /* anything else is a comment */ + { + if( sym != EOLSYM ) + list_force = TRUE; + return; /* anything else is a comment */ + } symptr = gsymptr; if (!ifflag) /* not assembling, just test for IF/ELSE/ELSEIF/ENDIF */ diff --git a/as/genlist.c b/as/genlist.c index f7c2572..399a71e 100644 --- a/as/genlist.c +++ b/as/genlist.c @@ -172,7 +172,7 @@ PUBLIC void listline() if (!listpre) { if (errcount || (list.current && (!macflag || mcount != 0)) || - (macflag && maclist.current)) + (macflag && maclist.current) || list_force ) list1(lstfil); if (errcount) { @@ -196,6 +196,7 @@ fd_t fd; if (errcount != 0) listerrors(); listpre = TRUE; + list_force=FALSE; } /* list object code for 1 line */ diff --git a/as/globvar.h b/as/globvar.h index df4ed6e..d22f6a5 100644 --- a/as/globvar.h +++ b/as/globvar.h @@ -27,6 +27,8 @@ EXTERN bool_t symgen; /* generate symbol table flag */ EXTERN unsigned toterr; /* total errors */ EXTERN unsigned totwarn; /* total warnings */ +EXTERN bool_t list_force; /* Force line to be listed - no error */ + /* bookeeping for current line */ EXTERN char *linebuf; /* buffer */ diff --git a/bcc/assign.c b/bcc/assign.c index 73a9883..5f25cc0 100644 --- a/bcc/assign.c +++ b/bcc/assign.c @@ -83,12 +83,14 @@ struct symstruct *target; storereg(i, target); } } +#ifdef I8088 else if (tscalar & FLOAT) { target->indcount = 1; /* XXX outnnadr clobbers this */ target->offset.offi += accregsize; storereg(DATREG2, target); } +#endif target->storage = source->storage; target->offset.offi = 0; } diff --git a/bcc/const.h b/bcc/const.h index cd1f16e..2383a30 100644 --- a/bcc/const.h +++ b/bcc/const.h @@ -43,9 +43,11 @@ typedef long no_hope; #else +#ifndef NO_I80386 # define I80386 /* Little BCC doesn't need 386 */ #endif #endif +#endif #ifdef MC6809 # define DYNAMIC_LONG_ORDER 0 /* have to define it so it works in #if's */ diff --git a/bcc/exptree.c b/bcc/exptree.c index 0f95439..d3e6386 100644 --- a/bcc/exptree.c +++ b/bcc/exptree.c @@ -940,8 +940,13 @@ struct nodestruct *nodeptr; } nodeptr->left.nodeptr = left = unconvert(left); nodeptr->right = right = unconvert(right); - if ((targtype = left->nodetype) == right->nodetype) - return targtype; /* XXX - reduced from promote(targtype) */ + if ( +#ifdef I80386 + i386_32 || +#endif + ((targtype = left->nodetype)->scalar & FLOAT ) == 0) + if (targtype == right->nodetype) + return targtype; /* XXX - reduced from promote(targtype) */ if ((lscalar = targtype->scalar) != 0 && (rscalar = right->nodetype->scalar) != 0) { diff --git a/bcc/function.c b/bcc/function.c index db2745d..0407028 100644 --- a/bcc/function.c +++ b/bcc/function.c @@ -98,8 +98,10 @@ struct symstruct *source; { if (source->type->scalar & DOUBLE) source->storage = doublreturnregs; +#ifdef I8088 else if (source->type->scalar & FLOAT) source->storage = RETURNREG|DATREG2; +#endif else source->storage = RETURNREG; } @@ -210,8 +212,10 @@ PUBLIC void loadretexpression() { if (returntype->scalar & DOUBLE) loadexpression(doublreturnregs, returntype); +#ifdef I8088 else if (returntype->scalar & FLOAT) loadexpression(/* REURNREG|*/ DATREG2, returntype); +#endif else loadexpression(RETURNREG, returntype); } diff --git a/bcc/genloads.c b/bcc/genloads.c index b39856e..9aff996 100644 --- a/bcc/genloads.c +++ b/bcc/genloads.c @@ -348,12 +348,14 @@ store_pt targreg; return; if (source->storage == CONSTANT) { +#ifdef I80386 if (i386_32) { loadconst(((offset_T *) source->offset.offd)[0], DREG); loadconst(((offset_T *) source->offset.offd)[1], targreg&~DREG); } else /* XXX - more for non-386 */ +#endif { int regs, i, off=1; loadconst(((unsigned short *) source->offset.offd)[0], DREG); @@ -394,7 +396,11 @@ store_pt targreg; loadconst(((unsigned short *) &val)[1], targreg&~DREG); } } +#ifdef I80386 else if (!i386_32 && source->type->scalar & FLOAT) +#else + else if (source->type->scalar & FLOAT) +#endif { /* Treat a float just like a long ... */ if (source->indcount == 0) diff --git a/bcc/preproc.c b/bcc/preproc.c index 507591f..84262e6 100644 --- a/bcc/preproc.c +++ b/bcc/preproc.c @@ -323,7 +323,8 @@ ts_s_macstring += 2; { gch1(); skipcomment(); - ch = *--lineptr = ' '; /* comment is space in modern cpp's */ + /* comment is space in modern cpp's but they have '##' too */ + ch = *--lineptr = ' '; } } #ifdef TS @@ -547,7 +548,14 @@ ts_s_macparam_tot += sizeof *paramlist * nparleft; blanks(); } if (ch != '(') + { + if (nparleft > 0) /* macro has params, doesn't match bare word */ + { + outstr(symptr->name.namea); + return; + } error("missing '('"); + } else { gch1(); diff --git a/bin86/Makefile b/bin86/Makefile index 5cd0ce8..4d1a185 100644 --- a/bin86/Makefile +++ b/bin86/Makefile @@ -38,7 +38,7 @@ depend clean clobber: (cd $$d; $(MAKE) $(MFLAGS) $@;); \ done -ungrab: +ungrab: ../as/as.c rm -rf as ld man grab: cp -a ../as ../ld . diff --git a/bootblocks/Makefile b/bootblocks/Makefile index 7ad0907..ebdcf08 100644 --- a/bootblocks/Makefile +++ b/bootblocks/Makefile @@ -21,16 +21,17 @@ SSRC=sysboot.s \ tarboot.s skip.s com_bcc.s tich.s \ bootlist.s mbr.s msdos.s noboot.s -encap: $(SSRC:s=v) $(CSRC:c=v) minixhd.v -bin: $(SSRC:s=bin) $(CSRC:c=bin) minixhd.bin +encap: $(SSRC:s=v) $(CSRC:c=v) minixhd.v msdos16.v +bin: $(SSRC:s=bin) $(CSRC:c=bin) minixhd.bin msdos16.bin MOBJ=monitor.o commands.o i86_funcs.o relocate.o help.o bzimage.o \ - trk_buf.o min_buf.o unix.o fs.o fs_tar.o fs_min.o fs_dos.o + trk_buf.o min_buf.o unix.o fs.o fs_tar.o fs_min.o fs_dos.o cprintf.o MSRC=monitor.c commands.c i86_funcs.c relocate.c help.c bzimage.c \ - trk_buf.c min_buf.c unix.c fs.c fs_tar.c fs_min.c fs_dos.c + trk_buf.c min_buf.c unix.c fs.c fs_tar.c fs_min.c fs_dos.c cprintf.c MINC=i86_funcs.h readfs.h monitor.h -BOOTBLOCKS=sysboot.v noboot.v skip.v msdos.v tarboot.v minix.v minixhd.v mbr.v +BOOTBLOCKS=sysboot.v noboot.v skip.v msdos.v msdos16.v \ + tarboot.v minix.v minixhd.v mbr.v EXTRAS=minix.h elf_info.c elf_info.h standalone.c li86.s \ zimage.s minix_elks.c crc.c lsys.c @@ -59,13 +60,16 @@ minix_elks.s: minix_elks.c Makefile minix.v minixhd.s: minix.c Makefile $(BCC) -Mf -O -DHARDDISK $(MINIXDEFS) -S minix.c -o minixhd.s +msdos16.s: msdos.s + sed 's/^fatbits=12/fatbits=16/' < msdos.s > msdos16.s + makeboot: makeboot.c $(BOOTBLOCKS) $(HOSTCC) $(HOSTCCFLAGS) -o makeboot makeboot.c makeboot.com: makeboot.c $(BOOTBLOCKS) $(BCC) -Md -O -o makeboot.com makeboot.c -lsys.com: lsys.c msdos.v +lsys.com: lsys.c msdos.v msdos16.v $(BCC) -Md -O -o lsys.com lsys.c version.h: @@ -74,7 +78,7 @@ version.h: clean realclean: rm -f monitor makeboot bootblocks.tar.gz - rm -f minix.s minixhd.s minix_elks.s version.h + rm -f minix.s minixhd.s minix_elks.s version.h msdos16.s rm -f *.com *.o *.bin *.out *.lst *.sym *.v *.tmp tgz: minix.bin monitor.out makeboot.com makeboot diff --git a/bootblocks/README b/bootblocks/README index ab115e3..d5054c6 100644 --- a/bootblocks/README +++ b/bootblocks/README @@ -37,12 +37,12 @@ Contents 1.2 ) Dosfs boot sector - Install with makeboot, the boot sector requires the floppy to be double - sided and makeboot checks for this. This boot sector loads and executes - a binary BOOTFILE.SYS from the root directory of the floppy. The file - can be any length and is loaded at $07C00. Because of the load address - this boot sector can be configured to load another boot sector, for - example LILO can be succesfully used in this way. + Install with makeboot, there is also a version for 16 bit FAT floppies + (eg LS-120 disks) This boot sector loads and executes a binary + BOOTFILE.SYS from the root directory of the floppy. The file can + be any length and is loaded at $07C00. Because of the load address + this boot sector can be configured to load another boot sector, + for example LILO can be succesfully used in this way. In fact LILO can be succesfully used in this way on a 2M disk, but you must create the floppy with the real dos 2M package as superformat @@ -53,6 +53,9 @@ Contents as my testing has gone this is only significant on 8086 machines, all others (286 8Mhz +) are fast enough to keep up at a 1-1 interleve. + Unfortunatly the most recent versions of superformat (5.0+) defeat this + because they do not correctly calculate intersector gaps. + 1.3 ) Minixfs boot block This boot block has varients for floppy and harddisk and works similarly @@ -63,7 +66,7 @@ Contents The sector looks for a file or directory called 'boot' if it's a directory it loads that and does the search again. When it finds a - file it loads it at location $10000 and executes it, beware this + file it loads it at location $10000 and executes it, note this is limited to a file size of 519k. There is also support for a helper boot which mean this is the only @@ -83,6 +86,8 @@ Contents tar file but when booted from will load and execute 'monitor.out' at location $00800 (Yes thats 2k!) + Warning: the tar boot sector moves the BPB to the location $666. + 1.5 ) Skip boot sector This bootsector displays a message then loads and executes the hard disk @@ -90,7 +95,8 @@ Contents 1.6 ) Panic boot sector - Displays the message 'PANIC! NO OS Found!' and freezes. + Displays the message 'PANIC! NO OS Found!' (or the message specified + on install) and freezes. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- @@ -127,34 +133,19 @@ Contents $ cp monitor.out /mnt/bootfile.sys $ cp /usr/src/linux/arch/i386/boot/zImage /mnt/vmlinuz - $ echo 'root=/dev/ram ramdisk_file=ramdisk.gz mem=80M' > /mnt/vmlinuz.cmd + $ echo 'root=/dev/ram ramdisk_file=ramdisk.gz mem=80M' > /mnt/vmlinuz.cfg $ cp /archive/ramdisk.gz /mnt/ramdisk.gz $ umount /dev/fd0 The stuff about ramdisk is only if you want an init ramdisk, if the ramdisk name begins with a '+' the program will ask for another disk first. - You can also use: - - vmlinuz.app: Arguments prepended to the Linux command line. - vmlinuz.cmd: Arguments appended to the Linux command line. - vmlinux.dfl: Arguments appended to the Linux command line. - - If there's a *.cmd file you won't be asked anything. If there's a *.dfl or - neither you'll be asked: - - vmlinuz: - - where you can type a command line to override the *.dfl file. If there's - a *.cmd file the *.dfl file is ignored, the *.app file is placed at the - start of the line whichever you do. - If the file isn't called 'vmlinuz' you can still boot it by typing "=linux" at the prompt '>' where 'linux' is the name of the bzImage file. Escape or ^C will interrupt the boot and drop you to the '>' prompt. Esacpe or ^C at the '>' prompt will reboot - (This may be a little sensitive :-) + (This may be a little too sensitive :-) A file called 'help.txt' will be displayed upto the first line that starts with a '%', chunks after that (seperated by '%'s) will be displayed when @@ -162,4 +153,4 @@ Contents -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -Robert de Bath <rdebath@poboxes.com> 22 Mar 1998 +Robert de Bath <rdebath@poboxes.com> 31 Dec 1998 diff --git a/bootblocks/bootlist.s b/bootblocks/bootlist.s index 9230796..a9c603c 100644 --- a/bootblocks/bootlist.s +++ b/bootblocks/bootlist.s @@ -17,10 +17,9 @@ BOOTSEG = 0x07c0 LOADSEG = 0x07e0 ! Just after boot sector. public linear -linear = 1 ! Is linear processing done ? - +linear = 1 ! Is linear processing done ? (0 doesn't work) public floppy -floppy = 0 *linear ! Allow for floppy drive ? +floppy = 0 *linear ! Allow for floppy drive ? (don't work) public reloc reloc = 1 *linear ! Auto configure of bootpart. @@ -93,7 +92,7 @@ load_addrs: adc dl,al mov al,ah else - lodsw + lodsw ; XXX Broken, doesn't set AL correctly. mov cx,ax lodsw mov dx,ax diff --git a/bootblocks/bzimage.c b/bootblocks/bzimage.c index cb713d7..1d7ff73 100644 --- a/bootblocks/bzimage.c +++ b/bootblocks/bzimage.c @@ -29,7 +29,7 @@ int load_crc = 0; static char buffer[1024]; cmd_bzimage(ptr) -char * ptr; +register char * ptr; { char * image; int ch; @@ -103,8 +103,8 @@ char * command_line; (int)(len/1024), (int)(len*10/1024%10)); return -1; } - if( main_mem_top < 3072 ) - printf("RTFM warning: Linux really needs at least 4MB of memory.\n"); + if( main_mem_top <= 3072 ) + printf("RTFM warning: Linux needs at least 4MB of memory.\n"); #endif low_sects = buffer[497] + 1; /* setup sects + boot sector */ @@ -220,6 +220,7 @@ char * command_line; printf("linux "); if( linux_command_line ) printf("%s", linux_command_line); + printf("\n"); fflush(stdout); if( a20_closed() ) open_a20(); @@ -289,6 +290,8 @@ char * command_line; /* Default boot drive is auto-detected floppy */ if( __peek_es(508) == 0 ) __poke_es(508, 0x200); + printf("Starting ...\n");; + #if ZIMAGE_LOAD_SEG == 0x10000 if( is_zimage ) /* Copy 512k from high memory then start */ @@ -319,8 +322,8 @@ char * command_line; } check_magics(fname, image_buf) -char * fname; -char * image_buf; +register char * fname; +register char * image_buf; { is_zimage = 0; @@ -371,7 +374,7 @@ unsigned int address; retry: tc--; - /* + if( x86_test ) return 0; /* In an EMU we can't write to high mem but we'll pretend we can for debuggering */ @@ -407,9 +410,9 @@ static char * read_cmdfile(iname) char * iname; { + char * ptr = strchr(iname, '.'); char buf[16]; long len; - char * ptr = strchr(iname, '.'); buf[8] = '\0'; strncpy(buf, iname, 8); @@ -427,7 +430,7 @@ char * iname; } if( read_block(buffer) >= 0 ) { - int i; + register int i; for(i=0; i<len; i++) if( buffer[i] < ' ' ) buffer[i] = ' '; buffer[len] = '\0'; @@ -445,7 +448,7 @@ input_cmd(iname) char * iname; { char lbuf[20]; - int cc; + register int cc; for(;;) { @@ -462,8 +465,11 @@ char * iname; if( cc == 0xAD ) /* ALT-X */ return 0; - sprintf(lbuf, "$%02x", cc); - cmd_help(lbuf); +#ifdef NOCOMMAND + cmd_type("helpprmt.txt"); +#else + help_key(cc); +#endif continue; } if( buffer[cc-1] == '\n' ) buffer[cc-1] = '\0'; diff --git a/bootblocks/commands.c b/bootblocks/commands.c index 459430d..9720cfe 100644 --- a/bootblocks/commands.c +++ b/bootblocks/commands.c @@ -1,29 +1,6 @@ #include "monitor.h" -#ifndef NOCOMMAND -extern unsigned int current_address; -extern int number_base; - -int cmd_quit(args) -char * args; -{ - printf("Bye\n"); - exit(0); -} - -int cmd_nop(ptr) -char * ptr; -{ -} - -int cmd_dir(ptr) -char * ptr; -{ - open_file("."); - return 0; -} - int cmd_type(ptr) char * ptr; { @@ -49,6 +26,29 @@ char * ptr; return 0; } +#ifndef NOCOMMAND +extern unsigned int current_address; +extern int number_base; + +int cmd_quit(args) +char * args; +{ + printf("Bye\n"); + exit(0); +} + +int cmd_nop(ptr) +char * ptr; +{ +} + +int cmd_dir(ptr) +char * ptr; +{ + open_file("."); + return 0; +} + int cmd_more(ptr) char * ptr; { @@ -117,12 +117,45 @@ int len; #ifndef NOMONITOR +cmd_monhelp() { +static char * helps[] = { + "Monitor help\n", + "zimage filename [args] Start Linux-386\n", + "bzimage filename [args] Start Linux-386\n", + "=filename [args] Start Linux-386\n", + "quit Reboot\n", + "help Display help file\n", + "dir Display directory\n", + "type Display file to screen\n", + "more Display file to screen\n", + "m[em] [address] Hexdump memory\n", + "seg [val] Set/show default segment\n", + "rel [segment] Relocate this program\n", + "base [val] Set default number base (or 'n' cmd)\n", + "init Re-init program\n", + "r[egs] Display register values\n", + + 0 +}; + char **p = helps; + more_char(-1); + + while(*p) + if( more_strn(*p, strlen(*p)) <0 ) + break; + else + p++; + printf("\n"); + return 0; +} + cmd_regs() { #ifdef __STANDALONE__ - printf("REGS: AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x\n", + printf(": AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x", __argr.x.ax, __argr.x.bx, __argr.x.cx, __argr.x.dx, __argr.x.si, __argr.x.di); + printf(" CS=%04x DS=%04x ES=%04x\n", __get_cs(), __get_ds(), __get_es()); #else printf("Only in standalone\n"); #endif diff --git a/bootblocks/cprintf.c b/bootblocks/cprintf.c new file mode 100644 index 0000000..3fefda3 --- /dev/null +++ b/bootblocks/cprintf.c @@ -0,0 +1,136 @@ + +#include <stdarg.h> + +static unsigned char * __numout(long i, int base); + +cputchar(ch) +int ch; +{ + if(ch == '\n') bios_putc('\r'); + return bios_putc(ch); +} + +cprintf(char * fmt, ...) +{ + register int c; + int count = 0; + int type, base; + long val; + char * cp; + char padch=' '; + int minsize = 0; + va_list ap; + + va_start(ap, fmt); + + while(c=*fmt++) + { + if(c!='%') + { + cputchar(c); + count++; + } + else + { + type=1; + padch = *fmt; + minsize=0; + if(padch == '-') fmt++; + + for(;;) + { + c=*fmt++; + if( c<'0' || c>'9' ) break; + minsize*=10; minsize+=c-'0'; + } + + while( c=='.' || (c>='0' && c<='9')) { c=*fmt++; } + + if( padch == '-' ) minsize = -minsize; + else + if( padch == '0' ) padch='0'; else padch=' '; + + if( c == 0 ) break; + if(c=='h') + { + c=*fmt++; + type = 0; + } + else if(c=='l') + { + c=*fmt++; + type = 2; + } + + switch(c) + { + case 'x': base=16; if(0) { + case 'o': base= 8; } if(0) { + case 'd': base=10; } + switch(type) + { + case 0: val=va_arg(ap, short); break; + case 1: val=va_arg(ap, int); break; + case 2: val=va_arg(ap, long); break; + default:val=0; break; + } + cp = __numout(val,base); + if(0) { + case 's': + cp=va_arg(ap, char *); + } + if( minsize > 0 ) + { + minsize -= strlen(cp); + while(minsize>0) { cputchar(padch); minsize--; } + minsize=0; + } + if( minsize < 0 ) minsize= -minsize-strlen(cp); + while(*cp) + cputchar(*cp++); + while(minsize>0) { cputchar(' '); minsize--; } + break; + case 'c': + cputchar(va_arg(ap, int)); + break; + default: + cputchar(c); + break; + } + } + } + va_end(ap); + return count; +} + +static char nstring[]="0123456789ABCDEF"; + +static unsigned char * +__numout(long i, int base) +{ + static unsigned char out[16]; + int n; + int flg = 0; + unsigned long val; + + if (i<0 && base==10) + { + flg = 1; + i = -i; + } + val = i; + + for (n = 0; n < 15; n++) + out[n] = ' '; + out[15] = '\0'; + n = 14; + do + { + out[n] = nstring[val % base]; + n--; + val /= base; + } + while(val); + if(flg) out[n--] = '-'; + return &out[n+1]; +} diff --git a/bootblocks/fs_dos.c b/bootblocks/fs_dos.c index bc223fc..6b0638e 100644 --- a/bootblocks/fs_dos.c +++ b/bootblocks/fs_dos.c @@ -19,19 +19,24 @@ #define DOS4_MAXSECT(P) get_long(P,0x20) #define DOS4_PHY_DRIVE(P) get_byte(P,0x24) #define DOS4_SERIAL(P) get_long(P,0x27) +#define DOS4_FATTYPE(P) get_uint(P,0x39) /* These assume alignment is not a problem */ #define get_byte(P,Off) *((unsigned char*)((char*)(P)+(Off))) #define get_uint(P,Off) *((unsigned short*)((char*)(P)+(Off))) #define get_long(P,Off) *((long*)((char*)(P)+(Off))) +typedef long Tsect; + static int read_bootblock(); static int dir_nentry, dir_sect; -static int dos_clust0, dos_spc, dos_fatpos, dos_fatlen; +static Tsect dos_clust0, dos_spc; +static int dos_fatpos, dos_fatlen, dos_fattype; static int last_serial = 0; #ifdef BUFFER_FAT static char * fat_buf = 0; +int use_fatbuf = 0; #endif static @@ -39,7 +44,7 @@ struct filestatus { char fname[12]; unsigned short first_cluster; unsigned short cur_cluster; - unsigned short sector_no; + unsigned short sector_no; /* Max filesize = 32M */ long file_length; } cur_file = { "", 0, 0, 0 }; @@ -47,7 +52,6 @@ struct filestatus { dos_open_file(fname) char * fname; { - extern union REGS __argr; char conv_name[12]; char *s, *d; int i; @@ -86,22 +90,31 @@ char * fname; memset(&cur_file, '\0', sizeof(cur_file)); #ifdef BUFFER_FAT - if( !dodir ) + if( !dodir && dos_fattype == 12 ) { /* Read in and buffer the FAT */ if( fat_buf ) free(fat_buf); fat_buf = malloc(dos_fatlen * 512); - if( fat_buf == 0 ) return -1; + if( fat_buf == 0 ) + use_fatbuf = 0; else { + use_fatbuf = 1; for(i=0; i<dos_fatlen; i++) { s = read_sector(dos_fatpos+i); - if(s == 0) return -1; + if(s == 0) + { + use_fatbuf = 0; + free(fat_buf); + fat_buf = 0; + } memcpy(fat_buf+i*512, s, 512); } } } + else + use_fatbuf = 0; #endif /* Scan the root directory for the file */ @@ -115,30 +128,36 @@ char * fname; #ifdef NOCOMMAND break; #else - char dtime[20]; + int dtime = 0; char lbuf[90]; *lbuf = 0; - sprintf(dtime, " %02d/%02d/%04d %02d:%02d", - (get_uint(d,24)&0x1F), - ((get_uint(d,24)>>5)&0xF), - ((get_uint(d,24)>>9)&0x7F)+1980, - ((get_uint(d,22)>>11)&0x1F), - ((get_uint(d,22)>>5)&0x3F) - ); if( *d > ' ' && *d <= '~' ) switch(d[11]&0x18) { case 0: - printf("%-8.8s %-3.3s %10ld%s\n", d, d+8, get_long(d,28), dtime); + printf("%-8.8s %-3.3s %10ld", d, d+8, get_long(d,28)); + dtime=1; break; case 0x10: - printf("%-8.8s %-3.3s <DIR> %s\n", d, d+8, dtime); + printf("%-8.8s %-3.3s <DIR> ", d, d+8); + dtime=1; break; case 8: if( (d[11] & 7) == 0 ) - printf("%-11.11s <LBL> %s\n", d, dtime); + { + printf("%-11.11s <LBL> ", d); + dtime=1; + } break; } + if( dtime ) + printf(dtime, " %02d/%02d/%04d %02d:%02d\n", + (get_uint(d,24)&0x1F), + ((get_uint(d,24)>>5)&0xF), + ((get_uint(d,24)>>9)&0x7F)+1980, + ((get_uint(d,22)>>11)&0x1F), + ((get_uint(d,22)>>5)&0x3F) + ); if( more_strn(lbuf, sizeof(lbuf)) < 0 ) break; #endif } @@ -151,7 +170,7 @@ char * fname; cur_file.cur_cluster = cur_file.first_cluster; cur_file.sector_no = 0; -#ifdef __ELKS__ +#ifdef DEBUG fprintf(stderr, "Opened first cluster %d, len %ld\n", cur_file.first_cluster, cur_file.file_length @@ -204,16 +223,18 @@ char * buffer; /* Is there an opened file ? */ if( cur_file.fname[0] == 0 ) { -#ifdef __ELKS__ +#ifdef DEBUG 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 ) + /* Are we before the EOF ? */ + if( ( dos_fattype == 12 && cur_file.cur_cluster >= 0xFF0 ) || + ( dos_fattype == 16 && (cur_file.cur_cluster&0xFFF0) == 0xFFF0 ) || + cur_file.cur_cluster < 2 ) { -#ifdef __ELKS__ +#ifdef DEBUG fprintf(stderr, "Hit end of file; cluster 0x%03x\n", cur_file.cur_cluster); #endif @@ -222,9 +243,11 @@ char * buffer; for(s=0; s<2; s++) { - unsigned int sectno; + Tsect sectno; - if( cur_file.cur_cluster >= 0xFF0 || cur_file.cur_cluster < 2 ) + if( ( dos_fattype == 12 && cur_file.cur_cluster >= 0xFF0 ) || + ( dos_fattype == 16 && (cur_file.cur_cluster&0xFFF0) == 0xFFF0 ) || + cur_file.cur_cluster < 2 ) { memset(buffer, '\0', 512); buffer += 512; @@ -242,31 +265,43 @@ char * buffer; cur_file.sector_no++; if( cur_file.sector_no % dos_spc == 0 ) { - int odd = (cur_file.cur_cluster&1); - unsigned int val, val2; + if( dos_fattype == 12 ) + { + int odd = (cur_file.cur_cluster&1); + unsigned int val, val2; - val = cur_file.cur_cluster + (cur_file.cur_cluster>>1); + val = cur_file.cur_cluster + (cur_file.cur_cluster>>1); #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 ) + if( use_fatbuf ) + val2 = get_uint(fat_buf, val); + else +#endif + { + 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)); + } + + if( odd ) val2>>=4; + + val2 &= 0xFFF; + + cur_file.cur_cluster = val2; + } + else { - val2 = (ptr[511]&0xFF); - ptr = read_sector(dos_fatpos+(val/512)+1); + ptr = read_sector(dos_fatpos+(cur_file.cur_cluster/256)); if( ptr == 0 ) return -1; - val2 |= (ptr[0]<<8); + cur_file.cur_cluster = get_uint(ptr, (cur_file.cur_cluster%256*2)); } - else - val2 = get_uint(ptr, (val%512)); -#endif - - if( odd ) val2>>=4; - - val2 &= 0xFFF; - - cur_file.cur_cluster = val2; } buffer += 512; @@ -303,6 +338,13 @@ static int read_bootblock() dos_fatpos = DOS_RESV(sptr); dos_fatlen = DOS_FATLEN(sptr); dos_spc = DOS_CLUST(sptr); + dos_fattype = DOS4_FATTYPE(sptr); + switch(dos_fattype) + { + case '1'+'6'*256: dos_fattype = 16; break; + case '1'+'2'*256: + default: dos_fattype = 12; break; + } if( dos_spc < 1 ) dos_spc = 1; dos_clust0 = dir_sect + (dir_nentry+15)/16 - 2*dos_spc; diff --git a/bootblocks/fs_tar.c b/bootblocks/fs_tar.c index 1dac3a4..a5cd55d 100644 --- a/bootblocks/fs_tar.c +++ b/bootblocks/fs_tar.c @@ -49,7 +49,9 @@ tar_open_file(fname) char * fname; { HEADER * sptr; +#ifndef NOCOMMAND int dodir = 0; +#endif int sectno; #ifdef __STANDALONE__ @@ -64,9 +66,11 @@ char * fname; tar_set_drive(); +#ifndef NOCOMMAND if( strcmp(fname, ".") == 0 ) dodir=1; else +#endif { if( tar_status.diskoffset == 0 && strcmp(fname, tar_status.name) == 0 ) return tar_rewind_file(); @@ -92,8 +96,10 @@ char * fname; if( sptr->member.m_linked != 0 && sptr->member.m_linked != '0' ) ; +#ifndef NOCOMMAND else if( dodir ) printf("%s %d tape blocks\n", sptr->member.m_name, (int)v-1); +#endif else if( strcmp(fname, sptr->member.m_name, NAME_SIZE) == 0 ) { strncpy(tar_status.name, sptr->member.m_name, NAME_SIZE); @@ -229,10 +235,10 @@ int type; } valid_tar_checksum(sptr) -HEADER * sptr; +register HEADER * sptr; { register char *ptr; - register int ac = 0; + int ac = 0; ptr = sptr->hdr_block; while (ptr < sptr->hdr_block+sizeof(sptr->hdr_block)) @@ -257,6 +263,7 @@ tar_set_drive() */ if( disk_spt <= 9 ) disk_cyls = 40; if( disk_spt == 21 || disk_spt > 36 ) disk_cyls = 82; + else if( disk_spt == 32 ) disk_cyls = 1024; else disk_cyls = 80; #else disk_spt = 18; /* Testing only */ diff --git a/bootblocks/help.c b/bootblocks/help.c index 3d53fad..049aa3d 100644 --- a/bootblocks/help.c +++ b/bootblocks/help.c @@ -7,6 +7,8 @@ #include "monitor.h" +#ifndef NOCOMMAND + struct keys { int key; int rel; @@ -33,12 +35,19 @@ struct keys { cmd_help(ptr) char * ptr; { -static int lastpage = 0; int helpkey = 1; - int i; getnum(&ptr, &helpkey); + return help_key(helpkey); +} + +help_key(helpkey) +int helpkey; +{ +static int lastpage = 0; + int i; + for(i=0; keys[i].key; i++) if( keys[i].key == helpkey || i == helpkey ) break; @@ -90,3 +99,4 @@ int page; return 0; } +#endif diff --git a/bootblocks/i86_funcs.c b/bootblocks/i86_funcs.c index b45343e..7b88da2 100644 --- a/bootblocks/i86_funcs.c +++ b/bootblocks/i86_funcs.c @@ -116,12 +116,10 @@ void cpu_check() void mem_check() { - if (x86_test) - { - main_mem_top = 16384; - return; /* If not standalone don't try */ - } - +#ifndef __STANDALONE__ + main_mem_top = 16384; + return; /* If not standalone don't try */ +#else { #asm int 0x12 ! Amount of boot memory @@ -150,6 +148,7 @@ got_ext: { /* It say 64Mb-1k - Hmmmm I think it might be 128! */ } +#endif } #define RIGHTS (0x93000000L) diff --git a/bootblocks/lsys.c b/bootblocks/lsys.c index 77f3931..442e920 100644 --- a/bootblocks/lsys.c +++ b/bootblocks/lsys.c @@ -1,5 +1,6 @@ #include "msdos.v" +#include "msdos16.v" #define DOS_SYSID 0x03 #define DOS_SECT 0x0B @@ -31,8 +32,8 @@ char ** argv; if( argc > 1 ) { - static char * s = "Usage: sys a:"; - if( argc == 1 && argv[1][1] == ':' && argv[1][2] == 0 ) + static char * s = "Usage: lsys [a:]\n"; + if( argc == 2 && argv[1][1] == ':' && argv[1][2] <= ' ' ) { if( argv[1][0] == 'a' || argv[1][0] == 'A' ) drive = 0; @@ -57,26 +58,37 @@ char ** argv; if( buffer[DOS_MEDIA] != buffer[512] || buffer[DOS_MEDIA] < 0xF0 || buffer[DOS_NFAT] > 2 || - buffer[DOS_SECT+1] != 2 || - buffer[DOS_HEADS] != 2 ) + buffer[DOS_SECT+1] != 2 ) fatal("Floppy has invalid format"); - for(i=0; i<msdos_dosfs_stat; i++) - buffer[i] = msdos_data[i]; - for(i=msdos_codestart; i<512; i++) - buffer[i] = msdos_data[i]; + if( memcmp(buffer+DOS4_FATTYPE, "FAT16", 5) ) + { + for(i=0; i<msdos_dosfs_stat; i++) + buffer[i] = msdos_data[i]; + for(i=msdos_codestart; i<512; i++) + buffer[i] = msdos_data[i]; + } + else + { + for(i=0; i<msdos16_dosfs_stat; i++) + buffer[i] = msdos16_data[i]; + for(i=msdos_codestart; i<512; i++) + buffer[i] = msdos16_data[i]; + } for(tries=0; tries<6; tries++) - if( (rv = dos_sect_read(drive, 0, 0, 1, buffer)) == 0 ) + if( (rv = dos_sect_write(drive, 0, 0, 1, buffer)) == 0 ) break; if( rv ) fatal("Cannot write bootsector"); + write(0, "Wrote bootsector\r\n", 18); return 0; } fatal(str) { write(0, str, strlen(str)); + write(0, "\r\n", 2); exit(1); } diff --git a/bootblocks/makeboot.c b/bootblocks/makeboot.c index 4eda4c6..c749d20 100644 --- a/bootblocks/makeboot.c +++ b/bootblocks/makeboot.c @@ -2,10 +2,12 @@ #include <stdio.h> #include <ctype.h> #include <time.h> +#include <string.h> #include "sysboot.v" #include "noboot.v" #include "msdos.v" +#include "msdos16.v" #include "skip.v" #include "tarboot.v" #include "minix.v" @@ -31,18 +33,39 @@ struct bblist { char * desc; char * data; int size; + int name_type; + int boot_name; int fstype; + int fsmod; } bblocks[] = { -{ "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}, -{ "mbr", "Master boot record for HD", mbr_data,mbr_size, FS_MBR}, -{ "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}, +{ "tar", "Bootable GNU tar volume lable", + tarboot_data, tarboot_size, 0, 0, FS_TAR}, +{ "dosfs","Boot file BOOTFILE.SYS from dos floppy", + msdos_data, msdos_size, + 1, msdos_boot_name-msdos_start, FS_DOS, 12}, +{ "dos16","Boot file BOOTFILE.SYS from 16 bit dos floppy", + msdos16_data, msdos16_size, + 1, msdos16_boot_name-msdos16_start, FS_DOS, 16}, +{ "none", "No OS bootblock, just message", + noboot_data, noboot_size, + 2, noboot_boot_message-noboot_start, FS_DOS}, +{ "skip", "Bypasses floppy boot with message", + skip_data, skip_size, + 2, skip_mesg-skip_start, FS_DOS}, +{ "minix","Minix floppy FS booter", + minix_data, minix_size, + 2, minix_bootfile-minix_start, FS_ZERO}, +{ "hdmin","Minix Hard disk FS booter", + minixhd_data, minixhd_size, + 2, minixhd_bootfile-minixhd_start, FS_ZERO}, +{ "mbr", "Master boot record for HD", + mbr_data,mbr_size, 0, 0, FS_MBR}, +{ "stat", "Display dosfs superblock", + 0, 0, 0, 0, FS_STAT}, +{ "copy", "Copy boot block to makeboot.sav", + 0, 0, 0, 0, FS_STAT}, +{ "Zap", "Clear boot block to NULs", + 0, 1024, 0, 0, FS_NONE}, 0 }; @@ -60,6 +83,8 @@ 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 */ +char * boot_id = 0; + main(argc, argv) int argc; char ** argv; @@ -76,6 +101,10 @@ char ** argv; } if( argc != 3 ) Usage(); + boot_id = strchr(argv[1], '='); + if( boot_id ) + *boot_id++ = '\0'; + if( (i=strlen(argv[1])) < 2 ) Usage(); for(ptr = bblocks; ptr->name; ptr++) if( strncmp(argv[1], ptr->name, i) == 0 ) break; @@ -93,12 +122,10 @@ char ** argv; { case FS_NONE: /* override */ break; - case FS_ADOS: - check_simpledos(); - break; case FS_DOS: case FS_STAT: check_msdos(); + if(ptr->fsmod) check_simpledos(ptr->fsmod); break; case FS_TAR: check_tar(); @@ -123,7 +150,6 @@ char ** argv; save_super(buffer); close_disk(); exit(0); - case FS_ADOS: case FS_DOS: for(i=0; i<sysboot_dosfs_stat; i++) buffer[i] = ptr->data[i]; @@ -139,9 +165,10 @@ char ** argv; copy_mbr(ptr->data); break; + case FS_ZERO: case FS_NONE: if( ptr->data ) - memcpy(buffer, ptr->data, 512); + memcpy(buffer, ptr->data, ptr->size); else { memset(buffer, '\0', 1024); @@ -150,6 +177,19 @@ char ** argv; break; } + if( boot_id ) switch(ptr->name_type) + { + case 1: + set_dosname(ptr->boot_name); + break; + case 2: + set_asciz(ptr->boot_name); + break; + default: + fprintf(stderr, "Cannot specify boot file for this block\n"); + exit(1); + } + if( bs_offset ) { if( write_zero ) do_2m_write(); @@ -172,11 +212,12 @@ Usage() progname = "makeboot"; #ifdef __MSDOS__ - fprintf(stderr, "Usage: %s [-f] bootname a:\n", progname); + fprintf(stderr, "Usage: %s [-f] bootblock[=bootname] a:\n", progname); #else - fprintf(stderr, "Usage: %s [-f] bootname /dev/fd0\n", progname); + fprintf(stderr, "Usage: %s [-f] bootblock[=bootname] /dev/fd0\n", progname); #endif - fprintf(stderr, "Blocks\n"); + fprintf(stderr, "\nThe bootname is a filename to use with the block,\n"); + fprintf(stderr, "the blocks are:\n"); for(;ptr->name; ptr++) fprintf(stderr, "\t%s\t%s\n", ptr->name, ptr->desc); exit(1); @@ -189,6 +230,9 @@ open_disk(diskname) char * diskname; { #ifdef __MSDOS__ + /* Freedos fix */ + if( diskname[2] == '\r' ) diskname[2] = 0; + if( strcmp("a:", diskname) == 0 ) { disktype = 1; return 0; } if( strcmp("b:", diskname) == 0 ) { disktype = 2; return 0; } if( strcmp("A:", diskname) == 0 ) { disktype = 1; return 0; } @@ -199,7 +243,7 @@ char * diskname; if( diskfd == 0 ) diskfd = fopen(diskname, "r"); if( diskfd == 0 ) { - fprintf(stderr, "Cannot open %s\n", diskname); + fprintf(stderr, "Cannot open '%s'\n", diskname); exit(1); } return 0; @@ -516,7 +560,8 @@ copy_tarblock() struct bootfields { int offset; int length; - int value; + unsigned value; + long lvalue; } dosflds[] = { @@ -606,6 +651,7 @@ char * bootsect; v = v*256 + (0xFF&( bootsect[dosflds[i].offset+j] )); } dosflds[i].value = v; + dosflds[i].lvalue = v; } else dosflds[i].value = 0; @@ -616,7 +662,11 @@ save_super(bootsect) char * bootsect; { FILE * fd; - fd = fopen("makeboot.sav", "wb"); + char * fname = "makeboot.sav"; + if( boot_id ) fname = boot_id; + + printf("Copying boot block to '%s'\n", fname); + fd = fopen(fname, "wb"); fwrite(bootsect, 1024, 1, fd); fclose(fd); } @@ -675,11 +725,12 @@ check_msdos() if(!force) exit(2); } -check_simpledos() +check_simpledos(bb_fatbits) +int bb_fatbits; { - int numclust = 0xFFFF; + unsigned numclust = 0xFFFF; char * err = 0; - check_msdos(); + int fatbits = 0; /* Work out how many real clusters there are */ if( dosflds[DOS_MAXSECT].value + 2 > 2 ) @@ -687,29 +738,112 @@ check_simpledos() - dosflds[DOS_RESV].value - dosflds[DOS_NFAT].value * dosflds[DOS_FATLEN].value - ((dosflds[DOS_NROOT].value+15)/16) - ) / dosflds[DOS_MAXSECT].value + 2; + ) / dosflds[DOS_CLUST].value + 2; + else + numclust = ( dosflds[DOS4_MAXSECT].lvalue + - dosflds[DOS_RESV].value + - dosflds[DOS_NFAT].value * dosflds[DOS_FATLEN].value + - ((dosflds[DOS_NROOT].value+15)/16) + ) / dosflds[DOS_CLUST].value + 2; + + if( memcmp(buffer+dosflds[DOS4_FATTYPE].offset, "FAT12", 5) == 0 ) + fatbits=12; + else if( memcmp(buffer+dosflds[DOS4_FATTYPE].offset, "FAT16", 5) == 0 ) + fatbits=16; + else + fatbits=12+4*(numclust > 0xFF0); if( dosflds[DOS_NFAT].value > 2 ) err = "Too many fat copies on disk"; - else if( dosflds[DOS_HIDDEN].value != 0 ) - err = "Dubious MSDOS floppy, it's got hidden sectors."; else if( dosflds[DOS_NROOT].value < 15 ) err = "Root directory has unreasonable size."; else if( dosflds[DOS_SECT].value != 512 ) err = "Drive sector size isn't 512 bytes sorry no-go."; - else if( dosflds[DOS_HEADS].value != 2 ) - err = "Drive doesn't have two heads, this is required."; - else if( numclust > 0xFF0 ) - err = "Filesystem has a 16 bit fat, only 12bits allowed."; - else if( dosflds[DOS_RESV].value + dosflds[DOS_FATLEN].value > - dosflds[DOS_SPT].value ) - err = "The bootblock needs all of fat1 on the first track."; - else - return; + else if( fatbits != bb_fatbits ) + err = "Filesystem has the wrong fat type for this bootblock."; + else if( numclust * dosflds[DOS_CLUST].lvalue / + dosflds[DOS_SPT].value > 65535 ) + err = "Maximum of 65535 tracks allowed, sorry"; - fprintf(stderr, "ERROR: %s\n\n", err); - print_super(buffer); - if(!force) exit(2); + if( !err && bb_fatbits == 12 ) + { + if( (0x7C00-msdos_start-512)/512 < dosflds[DOS_FATLEN].value ) + err = "The FAT is too large to load in the available space."; + else if( dosflds[DOS_RESV].value + dosflds[DOS_FATLEN].value > + dosflds[DOS_SPT].value ) + err = "The bootblock needs all of fat1 on the first track."; + else if( msdos_heads == 2 && dosflds[DOS_HEADS].value != 2 ) + err = "Drive doesn't have two heads, this is required."; + else if( dosflds[DOS_HIDDEN].lvalue != 0 ) + err = "MSDOS floppies shouldn't have hidden sectors."; + } + + if( err ) + { + fprintf(stderr, "ERROR: %s\n\n", err); + print_super(buffer); + if(!force) exit(2); + } +} + +set_dosname(boot_name) +int boot_name; +{ + char dos_name[20]; + int i,j; + + strcpy(dos_name, " "); + + for(i=0; boot_id[i] && boot_id[i] != '.' && i<16; i++) + dos_name[i] = toupper(boot_id[i]); + + if( boot_id[i] == '.' ) + { + for(j=8,i++; boot_id[i] && boot_id[i] != '.' && j<16; i++,j++) + dos_name[j] = toupper(boot_id[i]); + } + + printf("Bootfile set to '%11.11s'\n", dos_name); + + memcpy(buffer+boot_name, dos_name, 11); +} + +set_asciz(boot_name) +int boot_name; +{ + int i, j; + + for(i=boot_name; buffer[i]; i++) ; + for( ; !buffer[i]; i++) ; + i = i - boot_name -1; + + if( strlen(boot_id) > i ) + { + fprintf(stderr, "Filename '%s' is too long for bootblock\n"); + exit(1); + } + else + { + for(i=0,j=boot_name; boot_id[i]; i++) + { + if( boot_id[i] == '\\' && boot_id[i+1] ) + { + i++; + switch(boot_id[i]) + { + case 'n': buffer[j++] = '\n'; break; + case 'r': buffer[j++] = '\r'; break; + case 'b': buffer[j++] = '\b'; break; + case 't': buffer[j++] = '\t'; break; + case 'a': buffer[j++] = '\007'; break; + case 'e': buffer[j++] = '\033'; break; + default: buffer[j++] = boot_id[i]; break; + } + } + else buffer[j++] = boot_id[i]; + } + buffer[j] = 0; + } } check_mbr() diff --git a/bootblocks/mbr.s b/bootblocks/mbr.s index 0d8560e..3a22984 100644 --- a/bootblocks/mbr.s +++ b/bootblocks/mbr.s @@ -90,7 +90,7 @@ bad_boot: cmp si,#bootblock_magic jnz check_active - # Check for Disk manager partitions (12 more!) + ! Check for Disk manager partitions (12 more!) if diskman cmp word ptr diskman_magic,#$55AA jnz no_diskman diff --git a/bootblocks/min_buf.c b/bootblocks/min_buf.c index 97324f3..797ee7b 100644 --- a/bootblocks/min_buf.c +++ b/bootblocks/min_buf.c @@ -8,17 +8,18 @@ int disk_drive = 0; int disk_spt = 7; -int disk_heads = 2; +int disk_heads = 0; int disk_cyls = 0; int bad_track = -1; -static int track_no = -1; +static int track_no = -1; +static int buf_len = 0; static char buffer[MAXTRK*512]; void reset_disk() { disk_spt = 7; - disk_heads = 2; + disk_heads = 0; disk_cyls = 0; bad_track = -1; } @@ -35,6 +36,7 @@ long sectno; int ltrack; if( sectno == 0 ) reset_disk(); + if( buf_len != disk_spt ) track_no = -1; if( disk_spt < 1 || disk_heads < 1 ) phy_s = sectno; @@ -45,31 +47,34 @@ long sectno; phy_c = sectno/disk_spt/disk_heads; } -#ifdef __ELKS__ +#ifdef DEBUG fprintf(stderr, "read_sector(%ld = %d,%d,%d)\n", sectno, phy_c, phy_h, phy_s); #endif ltrack = phy_c*disk_heads+phy_h; - if( disk_spt > 7 && disk_spt <= MAXTRK + if( disk_spt > 1 && disk_spt <= MAXTRK && track_no != ltrack && ltrack != bad_track) { rv = phy_read(disk_drive, phy_c, phy_h, 1, disk_spt, buffer); if( rv == 0 ) + { track_no = ltrack; + buf_len = disk_spt; + } else bad_track = ltrack; } - if( track_no == phy_c*disk_heads+phy_h ) + if( track_no == ltrack ) return buffer + phy_s * 512; do { rv = phy_read(disk_drive, phy_c, phy_h, phy_s+1, 1, buffer); 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, buffer); } while(rv && tries > 0); + if( rv ) printf("Disk error 0x%02x %d:%d:%d:%d[%2d] -> 0x%04x[]\n", + rv, disk_drive, phy_c, phy_h, phy_s+1, 1, buffer); if(rv) return 0; else return buffer; } diff --git a/bootblocks/monitor.c b/bootblocks/monitor.c index a44bad7..4fecfd7 100644 --- a/bootblocks/monitor.c +++ b/bootblocks/monitor.c @@ -8,7 +8,7 @@ typedef int (*proc)(); int cmd_quit(), cmd_dump(), cmd_seg(), cmd_rel(), cmd_bzimage(), cmd_help(); int cmd_nop(), cmd_memdump(), cmd_set_base(), cmd_dir(), cmd_type(), cmd_more(); -int cmd_regs(); +int cmd_regs(), cmd_monhelp(); void init_prog(); @@ -33,6 +33,7 @@ static char minibuf[2] = " "; init_prog(); #ifdef __STANDALONE__ +#if 0 #ifndef NOCOMMAND if( __get_ds() != 0x1000 ) { @@ -42,12 +43,17 @@ static char minibuf[2] = " "; printf("Relocated to CS=$%04x DS=$%04x\n", __get_cs(), __get_ds()); } #endif +#else + printf("Loaded at CS=$%04x DS=$%04x\n", __get_cs(), __get_ds()); +#endif if( (__argr.x.dx & 0xFF) == 0 ) #endif { +#ifdef NOCOMMAND + cmd_type("help.txt"); +#else display_help(0); -#ifndef NOCOMMAND if( x86 > 2 && !x86_emu ) /* Check some basics */ #endif cmd_bzimage((void*)0); @@ -70,8 +76,9 @@ static char minibuf[2] = " "; command_buf[ch] = '\0'; if( ch == 1 && command_buf[0] != '\n' ) { - sprintf(command_buf, "?$%02x\n", command_buf[0]&0xFF); - printf("%s", command_buf); + putchar('\n'); + help_key(command_buf[0]&0xFF); + continue; } if( command_buf[ch-1] == '\n' ) command_buf[ch-1] = 0; @@ -241,7 +248,6 @@ struct t_cmd_list cmd_list[] = {"exit", cmd_quit}, {"quit", cmd_quit}, {"q", cmd_quit}, {"#", cmd_nop}, {"help", cmd_help}, /* Display from help.txt */ - {"?", cmd_help}, /* Display from help.txt */ {"dir", cmd_dir}, /* Display directory */ {"cat", cmd_type}, /* Cat/Type a file to the screen */ {"type", cmd_type}, /* Cat/Type a file to the screen */ @@ -249,6 +255,8 @@ struct t_cmd_list cmd_list[] = #ifndef NOMONITOR /* Debugger/monitor commands */ + {"?", cmd_monhelp}, /* Display builtin help */ + {"memdump",cmd_memdump}, {"mem",cmd_memdump}, {"m", cmd_memdump}, /* Display bytes */ {"seg", cmd_seg}, /* Set default segment */ @@ -257,6 +265,7 @@ struct t_cmd_list cmd_list[] = {"n", cmd_set_base}, {"init", init_prog}, + {"regs", cmd_regs}, {"reg", cmd_regs}, {"r", cmd_regs}, diff --git a/bootblocks/monitor.h b/bootblocks/monitor.h index de42a20..7674afd 100644 --- a/bootblocks/monitor.h +++ b/bootblocks/monitor.h @@ -2,7 +2,7 @@ #include <stdio.h> #include <errno.h> #include <ctype.h> -#include <dos.h> +#include <bios.h> #include <malloc.h> #include "i86_funcs.h" #include "readfs.h" @@ -11,14 +11,12 @@ #define X_DOSFLOPPY #define X_CALC_CRC - #ifdef __STANDALONE__ #define COLOUR extern union REGS __argr; #endif - #ifdef TARFLOPPY #define SINGLEFS #define NOMONITOR @@ -45,3 +43,11 @@ extern union REGS __argr; #define file_length dos_file_length #define read_block dos_read_block #endif + +#if 1 +#undef putchar +#define putchar cputchar +#define printf cprintf +#define fflush(x) +#endif + diff --git a/bootblocks/msdos.s b/bootblocks/msdos.s index 72e2a11..11a4fe4 100644 --- a/bootblocks/msdos.s +++ b/bootblocks/msdos.s @@ -1,32 +1,42 @@ -! -! This is a bootblock to load an execute a standalone program from an -! MSDOS filesystem on a floppy disk. -! -! The file loaded is called 'BOOTFILE.SYS' it can be changed at install time -! by following the label boot_name. -! -! The file is loaded at address $7C00, this means it can be the image of a -! boot block (eg LILO). It's also checked for the magic number associated -! with a Linux-8086 standalone executable and this is used if found. +!--------------------------------------------------------------------------- +!! This is a bootblock to load an execute a standalone program from an +!! MSDOS filesystem on a floppy disk. +!! +!! The file loaded is called 'BOOTFILE.SYS' and is loaded at address $7C00. +!--------------------------------------------------------------------------- +! The filename can be changed at install time by following the label +! boot_name, because the file is loaded at address $7C00 it can be the +! image of a boot block (eg LILO). It's also checked for the magic number +! associated with a Linux-8086 standalone executable and this is used if +! it's found. ! ! There are a number of assumptions made by the code concerning the layout ! of the msdos files system: ! -! 1) All of the first FAT must be on the first track. +! 1) All of the first 12 bit FAT must be on the first track. ! 2) The FAT must be 12 bit ! 3) The value of the hidden sectors field must be zero -! 4) There must be two heads on the disk. ! ! All these are true for mtools created floppies on normal PC drives. -! +!--------------------------------------------------------------------------- ORGADDR=$0500 use16 ! Some configuration values LOADSEG= $7C0 +export fatbits +fatbits=12 ! Set to 12 or 16 (16 for LS-120 disks) + +export heads + +if fatbits =12 +heads=2 ! This can be 0,1 or 2. 0 is dynamic. +else +heads=0 ! This can be 0,1 or 2. 0 is dynamic. +endif -!------------------------------------------------------------------------- +!--------------------------------------------------------------------------- ! Absolute position macro, fails if code before it is too big. macro locn if *-start>?1 @@ -35,18 +45,16 @@ macro locn .blkb ?1 + start-* mend -heads=2 ! This can be 1 or 2 ONLY. (1 is untested) - org ORGADDR start: include sysboot.s +!--------------------------------------------------------------------------- ! Data into the temp area, 30 clear bytes org floppy_temp root_count: .blkw 1 -old_bpb: .blkw 2 -bios_disk: .blkb 12 +!--------------------------------------------------------------------------- locn(codestart-start) cld ! Assume _nothing_! @@ -68,7 +76,6 @@ cont: ! DONT Need to fix BPB for fd0 to correct sectors (Like linux bootblock does) ! as we only ever read one sector at a time. - ! For each sector in root dir ! For each dir entry ! If entry name is == boot_name @@ -102,7 +109,7 @@ nextsect: mov si,bx nextentry: - ! Test attributes for !dir !label here ? + ! TODO: Test attributes for !dir !label here ? ! test entry name push si @@ -129,13 +136,16 @@ bad_entry: jp nextsect jmp no_system -! Convert a cluster number in AX into a CHS in CX:DX +!--------------------------------------------------------------------------- +! Convert a cluster number in DI into a CHS in CX:DX linclust: + mov ax,di sub ax,#2 mov dl,[dos_clust] xor dh,dh mul dx add ax,bp ! Add sector number of first data sector. + adc dx,#0 jmp linsect2 ! @@ -144,22 +154,36 @@ linclust: ! linsect: mov ax,di -linsect2: +linsect1: xor dx,dx +linsect2: + if fatbits =16 + add ax,[dos_hidden] + adc dx,[dos_hidden+2] + endif div [dos_spt] inc dx - mov cl,dl ! Sector num - xor dx,dx ! Drive 0 + mov cl,dl ! Sector num + xor dx,dx ! Drive 0 if heads =2 - shr ax,#1 ! Assume dos_heads == 2 - adc dh,#0 ! Head num + shr ax,#1 ! Assume dos_heads == 2 + adc dh,#0 ! Head num + endif + if heads =0 + div [dos_heads] + xchg dh,dl + endif + mov ch,al ! Cylinder bits 0-7 + if heads =0 + sar ax,#1 ! Cylinder bits 8&9 + sar ax,#1 + and al,#$C0 + or cl,al endif - mov ch,al ! Cylinder ret -error_msg: - .asciz "\r\nError during initial boot\r\nPress a key:" - +!--------------------------------------------------------------------------- +! Error processing. no_system: floppy_error: @@ -178,7 +202,7 @@ EOS: int $19 ! This should be OK as we haven't touched anything. jmpi $0,$FFFF ! Wam! Try or die! -! +!--------------------------------------------------------------------------- ! This loads the boot program 1 sector at a time, funny thing is it actually ! loads at exactly the same speed as loading a track at a time, at least on ! my slow old 286/8Mhz. Oh well, we need the space so if you're worried just @@ -186,6 +210,7 @@ EOS: ! load_system: + if fatbits =12 push ax ! Save cluster we're loading ! 1) Load FAT @@ -198,19 +223,20 @@ load_system: xor dx,dx ! Head zero int $13 jc floppy_error + pop di ! Cluster to start load. + else + mov di,ax + endif mov ax,#LOADSEG mov es,ax - pop di ! Cluster to start load. ! load whole cluster next_cluster: mov si,[dos_clust] ! How big is a cluster and si,#255 - - mov ax,di ! Find it's physical address - call linclust + call linclust ! Find it's physical address next: mov ax,#$0201 @@ -231,6 +257,12 @@ next: jnz sectok xor dh,dh endif + if heads=0 + inc dh + cmp dh,[dos_heads] ! Nb low byte only. + jnz sectok + xor dh,dh + endif inc ch sectok: inc cl @@ -242,6 +274,7 @@ sectok: jmp maincode next_fat: + if fatbits =12 mov ax,di shr ax,#1 pushf ! Save if odd number @@ -255,8 +288,44 @@ noshift: and di,#$FFF cmp di,#$FF0 ! FFF is EOF, clear carry flag. ! FF0+ are badblocks etc. + endif + + if fatbits =16 + mov ax,di + ! load fat sector AH (if it's not already loaded) + + xchg ah,al + xor ah,ah + add ax,[dos_resv] + + cmp ax,[fatsect] + jz got_fsect + mov [fatsect],ax + + call linsect1 + + push es + mov bx,#fat_table + xor ax,ax + mov es,ax + mov ax,#$0201 + int $13 + pop es + jnc got_fsect + br floppy_error + +got_fsect: + ! Load di with cluster number in di + and di,#$FF + shl di,#1 + mov di,fat_table[di] + cmp di,#$FFF0 + endif + ret +!--------------------------------------------------------------------------- +! File is now loaded, execute it. maincode: mov bx,#7 mov ax,#$0E3E @@ -292,7 +361,22 @@ impure: ! AX=ds, BX=cs, CX=X, DX=X, SI=X, DI=0, BP=X, ES=X, DS=*, SS=*, CS=* retf bad_magic: - jmpi $7C00,0 ! No magics, just go. + pop cx + jmpi LOADSEG<<4,0 ! No magics, just go. + +!--------------------------------------------------------------------------- +! initilised data + +fatsect: + .word 0 + +! if fatbits =16 +error_msg: + .asciz "\r\nError during initial boot\r\nPress a key:" +! else +! error_msg: +! .asciz "\r\nBoot error:" +! endif export boot_name boot_name: @@ -300,6 +384,13 @@ boot_name: name_end: ! NNNNNNNNEEE -locn(512) +if fatbits =16 +locn(510) + .word 0 ! This is a floppy so it should not need the magic _but_ + ! the debian MBR requires the magic even on floppies + ! so only clear on a superfloppy (LS-120). +endif + fat_table: ! This is the location that the fat table is loaded. - ! Note: The fat must be entirely on track zero. + ! Note: The fat must be entirely on track zero if 12 bit. +!--------------------------------------------------------------------------- diff --git a/bootblocks/noboot.s b/bootblocks/noboot.s index 7ab9f4e..22e1312 100644 --- a/bootblocks/noboot.s +++ b/bootblocks/noboot.s @@ -13,11 +13,8 @@ org codestart mov sp,ax jmpi code,#0 -no_os: - .asciz "PANIC! NO OS Found!\r\n" - code: ! SI = pointer to error message - mov si,#no_os + mov si,#boot_message nextc: lodsb cmp al,#0 @@ -30,3 +27,8 @@ eos: ! Wait for a key then reboot xor ax,ax int $16 jmpi $0,$FFFF ! Wam! Try or die! + +export boot_message +boot_message: + .asciz "PANIC! NO OS Found!\r\n" + diff --git a/bootblocks/skip.s b/bootblocks/skip.s index 3e55cd9..0c1184d 100644 --- a/bootblocks/skip.s +++ b/bootblocks/skip.s @@ -52,16 +52,6 @@ error: call prtmsg jmp hcode - if BOOTDISK = 0x80 -mesg: .asciz "Bypassing floppy boot\r\n" - else -mesg: .asciz "Booting drive two\r\n" - endif - -mesg2: .asciz "Disk error\r\n" -mesg3: .asciz "Retrying\r\n" -mesg4: .asciz "Press a key:" - prtmsg: lodsb cmp al,#0 @@ -82,3 +72,14 @@ reboot: int $19 ! This should be OK as we haven't touched anything. jmpi $0,$FFFF ! Wam! Try or die! +mesg2: .asciz "Disk error\r\n" +mesg3: .asciz "Retrying\r\n" +mesg4: .asciz "Press a key:" + +export mesg + if BOOTDISK = 0x80 +mesg: .asciz "Bypassing floppy boot\r\n" + else +mesg: .asciz "Booting drive two\r\n" + endif + diff --git a/bootblocks/standalone.c b/bootblocks/standalone.c index 3fb0e28..8344c64 100644 --- a/bootblocks/standalone.c +++ b/bootblocks/standalone.c @@ -1,5 +1,5 @@ -#include <dos.h> +#include <bios.h> #include <errno.h> #asm entry _int_80 ! Tell ld86 we really do need this file. diff --git a/bootblocks/tarboot.s b/bootblocks/tarboot.s index 2e31570..f872ad0 100644 --- a/bootblocks/tarboot.s +++ b/bootblocks/tarboot.s @@ -93,7 +93,7 @@ endif call probe_floppy call get_size ! Get number of clicks in di - cmp di,#0 + test di,di jz nogood ! If it`s zero .. Hmm if STACK = 0 @@ -122,7 +122,7 @@ hcode: ! 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 +disksizes: .byte 36,32,21,18,15,9 ! End of part 1 !-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/bootblocks/trk_buf.c b/bootblocks/trk_buf.c index f9ae3c8..69c7eaa 100644 --- a/bootblocks/trk_buf.c +++ b/bootblocks/trk_buf.c @@ -3,12 +3,15 @@ #ifndef MINI_BUF +/* #define DEBUG 1 */ + int disk_drive = 0; int disk_spt = 7; int disk_heads = 2; int disk_cyls = 0; +long disk_partition_offset = 0; /* FIXME: fetch from __argr */ -static int last_drive = 0; +static int last_drive = -1; static int data_len = 0; static long data_trk1 = 0; static char * data_buf1 = 0; @@ -32,6 +35,7 @@ void reset_disk() disk_spt = 7; /* Defaults for reading Boot area. */ disk_heads = 2; disk_cyls = 0; + disk_partition_offset = 0; } #if defined(__MSDOS__) || defined(__STANDALONE__) else @@ -40,6 +44,13 @@ void reset_disk() long dpt; int v; +#ifdef __STANDALONE__ + if( disk_partition_offset == 0 && disk_drive == __argr.h.dl ) + { + disk_partition_offset = __argr.x.cx + ((long)__argr.h.dh<<16); + } +#endif + disk_spt = 17; /* Defaults for reading Boot area. */ disk_heads = 1; disk_cyls = 0; @@ -72,12 +83,15 @@ long sectno; if( disk_drive != last_drive || sectno == 0 ) reset_disk(); + if( disk_partition_offset > 0 ) + sectno += disk_partition_offset; + if( disk_spt < 0 || disk_spt > 63 || disk_heads < 1 ) { phy_s = sectno; reset_disk(); -#ifdef __ELKS__ +#if DEBUG > 1 fprintf(stderr, "read_sector(%ld = %d,%d,%d)\n", sectno, phy_c, phy_h, phy_s+1); #endif @@ -88,7 +102,7 @@ long sectno; phy_h = sectno/disk_spt%disk_heads; phy_c = sectno/disk_spt/disk_heads; -#ifdef __ELKS__ +#if DEBUG > 1 fprintf(stderr, "read_sector(%ld = %d,%d,%d)\n", sectno, phy_c, phy_h, phy_s+1); #endif @@ -106,10 +120,15 @@ long sectno; return 0; } -#ifdef __ELKS__ +#ifdef DEBUG fprintf(stderr, "WARNING: Single sector read\n"); #endif +#ifdef DEBUG + fprintf(stderr, "phy_read(%d,%d,%d,%d,%d,0x%x)\n", + disk_drive, phy_c, phy_h, phy_s+1, 1, data_buf1); +#endif + do { rv = phy_read(disk_drive, phy_c, phy_h, phy_s+1, 1, data_buf1); @@ -133,14 +152,23 @@ int phy_c, phy_h, phy_s; /* Big tracks get us short of memory so limit it. */ nlen = (disk_spt-1)/24; nlen = (disk_spt+nlen)/(nlen+1); + /* trk_no = (long)phy_c*disk_heads*4+phy_h*4+phy_s/nlen+1; + */ + + trk_no = (long)(phy_c*disk_heads+phy_h)*((disk_spt+4)/nlen)+phy_s/nlen+1; + +#if DEBUG > 1 + fprintf(stderr, "Info len=%d,%d trk=%ld,%ld,%ld\n", + data_len,nlen, trk_no,data_trk1,data_trk2); +#endif 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; + data_len = nlen; } if( trk_no == bad_track ) return -1; @@ -151,9 +179,15 @@ int phy_c, phy_h, phy_s; * 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; + /* But sequential reads may spoil this so don't swap if we are shifting + * to the next track. + */ + + if( trk_no == data_trk2 || trk_no != data_trk1 + 1 ) + { + 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; @@ -165,8 +199,11 @@ int phy_c, phy_h, phy_s; { data_buf1 = malloc(disk_spt*512); -#ifdef __ELKS__ - fprintf(stderr, "Allocated buffer to %d\n", data_buf1); +#ifdef DEBUG + if( data_buf1 ) + fprintf(stderr, "Allocated buffer to %d\n", data_buf1); + else + fprintf(stderr, "Failed to allocated buffer.\n"); #endif } if( data_buf1 == 0 ) @@ -180,9 +217,14 @@ int phy_c, phy_h, phy_s; /* Not enough memory for track read. */ if( data_buf1 == 0 ) return -1; +#ifdef DEBUG + fprintf(stderr, "phy_read(%d,%d,%d,%d,%d,0x%x)\n", + disk_drive, phy_c, phy_h, phy_s/data_len*data_len+1, data_len, data_buf1); +#endif + do /* the physical read */ { - rv = phy_read(disk_drive, phy_c, phy_h, phy_s/data_len+1, data_len, + rv = phy_read(disk_drive, phy_c, phy_h, phy_s/data_len*data_len+1, data_len, data_buf1); tries--; } diff --git a/copt/copt.c b/copt/copt.c index 12a5ac2..24577ae 100644 --- a/copt/copt.c +++ b/copt/copt.c @@ -54,9 +54,7 @@ struct line_s { char *text; struct line_s *prev; struct line_s *next; -#ifdef KEEPCOMMENTS int comment_flg; -#endif }; @@ -196,9 +194,7 @@ static struct line_s *readlist(FILE *fp, char quit, char comment) if (quit != NOCHAR && quit == *cp) break; if (comment != NOCHAR && comment == *cp) -#ifdef KEEPCOMMENTS if (quit != NOCHAR) -#endif continue; if (*cp == '\0') continue; @@ -206,9 +202,7 @@ static struct line_s *readlist(FILE *fp, char quit, char comment) lp->text = install(cp, -1); lp->prev = last_line; lp->next = NULL; -#ifdef KEEPCOMMENTS lp->comment_flg = (comment != NOCHAR && *cp == comment); -#endif if (first_line == NULL) first_line = lp; if (last_line != NULL) @@ -677,12 +671,6 @@ static struct line_s *optline(struct line_s *cur) /* Scan through pattern texts and match them against the input file */ ins = cur; pat = rp->old; -#ifndef KEEPCOMMENTS - while (ins != NULL && pat != NULL && match(ins->text, pat->text)) { - ins = ins->next; - pat = pat->next; - } -#else while (ins != NULL && pat != NULL && ( ins->comment_flg || @@ -693,7 +681,6 @@ static struct line_s *optline(struct line_s *cur) pat = pat->next; ins = ins->next; } -#endif /* Current pattern matched input line, so replace input with new */ if (pat == NULL) { @@ -701,7 +688,6 @@ static struct line_s *optline(struct line_s *cur) lp1 = cur; cur = cur->prev; while (lp1 != ins) { -#ifdef KEEPCOMMENTS #if 0 /* I'd like to keep the comment lines but this doesn't work XXX */ if( lp1->comment_flg ) { @@ -714,7 +700,6 @@ static struct line_s *optline(struct line_s *cur) } else #endif -#endif { lp2 = lp1; lp1 = lp1->next; @@ -730,9 +715,7 @@ static struct line_s *optline(struct line_s *cur) lp2->text = subst(pat->text); lp2->next = NULL; lp2->prev = lp1; -#ifdef KEEPCOMMENTS lp2->comment_flg = 0; -#endif if (lp1 != NULL) lp1->next = lp2; else @@ -763,14 +746,11 @@ static void optimize(int backup) { struct line_s *cur, *lp; int i; -#ifdef KEEPCOMMENTS int in_asm = 0; -#endif /* Scan through all lines in the input file */ cur = infile; while (cur != NULL) { -#ifdef KEEPCOMMENTS if (cur->comment_flg || in_asm) { lp=cur->next; @@ -778,7 +758,6 @@ static void optimize(int backup) in_asm = (memcmp(cur->text+5, "ASM", 3) == 0); } else -#endif if ((lp = optline(cur)) != NULL && lp != cur->next) { for (i = 0; i < backup && lp != NULL; i++) lp = lp->prev; diff --git a/copt/rules.86 b/copt/rules.86 index b788312..f0654f4 100644 --- a/copt/rules.86 +++ b/copt/rules.86 @@ -344,7 +344,7 @@ ret jmp .%1 .%1: = -.%1 +.%1: jmp .%1 .%2: @@ -435,3 +435,14 @@ add sp,*%4 %1 %2 add sp,*%3+%4 +# And a great bug floating push/pop +push dx +push cx +push bx +push ax +pop ax +pop bx +pop cx +pop dx += +! push/pop diff --git a/elksemu/README b/elksemu/README index 23d3111..6a5bdae 100644 --- a/elksemu/README +++ b/elksemu/README @@ -2,23 +2,21 @@ Elksemu is an emulator for the environment that elks will provide on a real ELKS machine. The emulator only runs on linux-i386 or similar. +If you're using a 2.0.36, 2.1.43, 2.2.0 or later kernel then the +binfmt_misc driver is in the stock kernel add the following line to a +/etc/rc*/* file and you don't need to install a patch or module! + +echo ':i86-elks:M::\x01\x03\x20\x00:\xff\xff\xff\x83:/lib/elksemu:' \ + > /proc/sys/fs/binfmt_misc/register + + If your kernel version is 1.2.13 then apply the patch in the Kernel_patch file. -If you're using one of the 2.0.X series then the binfmt_elks.c module +If you're using one of the other 2.0.X series then the binfmt_elks.c module should be able to compile and install. BUT do note you need the modules and probably modversions options and you _may_ have to alter the compile command to match those seen when you compile modules that come with the kernel. -If you're using a 2.1.43 or later then the binfmt_misc driver is in -the stock kernel add the following line to a /etc/rc*/* file and -you don't need to install a patch or module! - -echo ':i86-elks:M::\x01\x03\x00\x20:\xff\xff\x83\xff:/lib/elksemu:' \ - > /proc/sys/fs/binfmt_misc/register - Rob. - -(NB I'm not running 2.1.X so I haven't tested the binfmt_misc method - as of 26/7/97) @@ -1,4 +1,4 @@ -/* (C) 1992,1996 R de Bath */ +/* (C) 1992,1996,1998-9 R de Bath */ #include <stdio.h> #include <ctype.h> @@ -13,6 +13,10 @@ #define void char #endif +/* + * Linked list of variables, the only source for these is the command line + * and the (optional) manifest constants. + */ struct varrec { struct varrec * next; @@ -25,6 +29,8 @@ int cuttype = 0; /* 0 = use blank lines */ /* 1 = use #lines */ /* 2 = use '# 'oldtext */ /* 3 = delete unused lines */ +int striphash = 0; +int stripcomment = 0; char linebuf[2048]; @@ -84,6 +90,7 @@ char ** argv; case 'C': case 'c': cuttype = 2; break; case 'r': cuttype = 3; break; + case 'h': striphash=1; break; case 'M': manifest_constant(); break; case 'D': unknown_stat = 'D'; break; @@ -146,11 +153,14 @@ char * fname; if( cuttype == 1 ) printf("#line 1 \"%s\"\n", filename); + /* NB: limited line length */ while( fgets(linebuf, sizeof(linebuf), fd) != 0 ) { int f = 1; + char * p = linebuf; lineno++; - if( linebuf[0] == '#' ) + while(isspace(*p)) p++; + if( *p == '#' ) f = do_hashcom(); if(f) { @@ -184,9 +194,12 @@ int lineno; int do_hashcom() { - char * p = linebuf+1; + char * p = linebuf; int flg = -1; - while( *p == ' ' || *p == '\t' ) p++; + + while(isspace(*p)) p++; + if( *p == '#' ) p++; + while(isspace(*p)) p++; if(strncmp(p, "ifdef", 5) == 0) { @@ -198,7 +211,7 @@ do_hashcom() do_ifdef(p+6, 'U'); } else - if(strncmp(p, "if", 2) == 0 && (p[2]==' ' || p[2]=='\t') ) + if(strncmp(p, "if", 2) == 0 && isspace(p[2]) ) { state[iflevel++] = keeptext; keeptext |= 2; @@ -217,7 +230,7 @@ do_hashcom() iflevel--; keeptext = state[iflevel]; } - else if( cuttype != 0 ) return 1; + else if( !striphash ) return 1; if( flg < 0 ) flg = (keeptext&2); @@ -245,7 +258,7 @@ int which; s = curr->name; p = nm; while( *p == *s ) { p++; s++; } - if( *s == '\0' && *p <= ' ' ) + if( *s == '\0' && *p <= ' ' ) /* FIXME alphanum */ break; } state[iflevel] = keeptext; @@ -272,6 +285,79 @@ int which; return 1; } +#if 0 + +do_if(p) +char * p; +{ + /* + * Look for: + * defined Label + * one sort of || && + * 0 + * 1 + * + * Skip characters: WS, (, ) + * + * Give up on unknown characters and labels without a defined or assumed + * state. BUT note that if there is another label that forces the state + * of the result irrespective of an unknown label the state should be set. + * + */ + +static char wbuf[256]; + + int combiner = 0; + int true_defs = 0; + int false_defs = 0; + int unkn_defs = 0; + + int state = 0; + + char * d; + + for(;;) + { + d=wbuf; + do + { + while( isspace(*p) || (d==wbuf && (*p == '(' || *p == ')' ))) p++; + + if( d!=wbuf && (*p == '(' || *p == ')' )) break; + + while( !(isspace(*p) || *p == '(' || *p == ')' )) + if( d<wbuf+sizeof(wbuf)-2) *d++ = *p++; + else p++; + + *d= 0; + } + while( strcmp(wbuf, "!") == 0 ); + + if( state == 0 ) + { + if( strcmp(wbuf, "defined" ) == 0 ) + { + state = 1; + continue; + } + if( strcmp(wbuf, "!defined" ) == 0 ) + { + state = 2; + continue; + } + if( strcmp(wbuf, "||" ) == 0 || strcmp(wbuf, "&&") == 0 ) + { + if( combiner == 0 ) combiner = wbuf[0]; + if( combiner != wbuf[0] ) combiner = '@'; + continue; + } + /* Something we're not ready for ... */ + goto Dont_know; + } + } +} +#endif + void check_name(nm) char * nm; @@ -121,6 +121,7 @@ char **argv; case 'z': /* unmapped zero page */ case 'N': /* Native format a.out */ case 'd': /* Make a headerless outfile */ + case 'y': /* Use a newer symbol table */ if (arg[2] == 0) flag[(int) arg[1]] = TRUE; else if (arg[2] == '-' && arg[3] == 0) @@ -250,7 +251,7 @@ char **argv; else #endif write_elks(outfilename, flag['i'], flag['3'], flag['s'], - flag['z'] & flag['3']); + flag['z'], flag['y']); if (flag['m']) dumpmods(); if (flag['M']) diff --git a/ld/objdump86.c b/ld/objdump86.c index b1e46bd..58a935f 100644 --- a/ld/objdump86.c +++ b/ld/objdump86.c @@ -69,15 +69,29 @@ char ** argv; if( p[0] == 's' ) display_mode = 1; if( p[0] == 'n' ) display_mode = 2; + multiple_files = 0; + for(ar=1; ar<argc; ar++) + { + if( argv[ar][0] == '-' ) switch(argv[ar][1]) + { + case 's': display_mode = 1; break; + case 'n': display_mode = 2; break; + } + else + multiple_files++; + } + + if( !multiple_files ) exit(1); + + multiple_files = (multiple_files>1); + if( display_mode == 1 ) printf("text\tdata\tbss\tdec\thex\tfilename\n"); - multiple_files = (argc>2); - - for(ar=1; ar<argc; ar++) + for(ar=1; ar<argc; ar++) if(argv[ar][0] != '-') do_file(argv[ar]); - return (argc<=1); + return 0; } void @@ -149,6 +163,7 @@ char * fname; case 1: /* ELKS executable */ fseek(ifd, 0L, 0); + fetch_aout_hdr(); switch(display_mode) { @@ -529,8 +544,6 @@ static char * byteord[] = { "LITTLE_ENDIAN", "(2143)","(3412)","BIG_ENDIAN" }; int i; long l; - if( display_mode == 0 ) fetch_aout_hdr(); - if( h_cpu > 0x17 ) h_cpu &= 3; printf("HLEN %d\n", h_len); @@ -597,8 +610,6 @@ static char * byteord[] = { "LITTLE_ENDIAN", "(2143)","(3412)","BIG_ENDIAN" }; void size_aout() { - if( display_mode == 1 ) fetch_aout_hdr(); - if( display_mode == 0 ) printf("text\tdata\tbss\tdec\thex\tfilename\n"); @@ -616,8 +627,7 @@ nm_aout() long n_value; int n_sclass, n_numaux, n_type; long bytes_left; - - if( display_mode == 2 ) fetch_aout_hdr(); + int pending_nl = 0; fseek(ifd, h_len+header[2]+header[3]+header[8]+header[9], 0); @@ -632,13 +642,20 @@ nm_aout() while(bytes_left > 16) { - if( fread(n_name, 1, 8, ifd) != 8 ) return; + if( fread(n_name, 1, 8, ifd) != 8 ) break; n_name[8] = 0; n_value = get_long(); - if( (n_sclass = getc(ifd)) == EOF ) return; - if( (n_numaux = getc(ifd)) == EOF ) return; + if( (n_sclass = getc(ifd)) == EOF ) break; + if( (n_numaux = getc(ifd)) == EOF ) break; n_type = get_word(); + if( pending_nl && n_sclass == 0 ) + { + printf("%s", n_name); + continue; + } + + if( pending_nl ) putchar('\n'); if( n_sclass == 0x10 ) printf(" "); else @@ -687,6 +704,10 @@ nm_aout() printf("n_type=%04x ", n_type); } - printf("%s\n", n_name); + printf("%s", n_name); + + pending_nl=1; } + + if( pending_nl ) putchar('\n'); } @@ -165,7 +165,7 @@ void write_rel P((char *outfilename, bool_pt argsepid, bool_pt argbits32, /* write_elks.c */ void write_elks P((char *outfilename, bool_pt argsepid, bool_pt argbits32, - bool_pt argstripflag, bool_pt arguzp)); + bool_pt argstripflag, bool_pt arguzp, bool_pt nsym)); /* linksym.c */ void linksyms P((bool_pt argreloc_output)); diff --git a/ld/writex86.c b/ld/writex86.c index b2bab23..86c3157 100644 --- a/ld/writex86.c +++ b/ld/writex86.c @@ -67,6 +67,7 @@ PRIVATE bool_t sepid; /* nonzero for separate I & D */ PRIVATE bool_t stripflag; /* nonzero to strip symbols */ PRIVATE bin_off_t spos; /* position in current seg */ PRIVATE bool_t uzp; /* nonzero for unmapped zero page */ +PRIVATE bool_t xsym; /* extended symbol table */ FORWARD void linkmod P((struct modstruct *modptr)); FORWARD void padmod P((struct modstruct *modptr)); @@ -81,12 +82,13 @@ EXTERN bool_t reloc_output; /* write binary file */ -PUBLIC void write_elks(outfilename, argsepid, argbits32, argstripflag, arguzp) +PUBLIC void write_elks(outfilename, argsepid, argbits32, argstripflag, arguzp, argxsym) char *outfilename; bool_pt argsepid; bool_pt argbits32; bool_pt argstripflag; bool_pt arguzp; +bool_pt argxsym; { char buf4[4]; char *cptr; @@ -108,6 +110,7 @@ bool_pt arguzp; bits32 = argbits32; stripflag = argstripflag; uzp = arguzp; + xsym = argxsym; if (uzp) { if (btextoffset == 0) @@ -387,6 +390,23 @@ bool_pt arguzp; } writeout((char *) &extsym, sizeof extsym); ++nsym; +#if !ELF_SYMS + if( xsym ) + { + int i; + extsym.n_sclass = 0; + extsym.n_value = 0; + + for(i=sizeof extsym.n_name; i<strlen(symptr->name); + i+=sizeof extsym.n_name) + { + strncpy((char *) extsym.n_name, symptr->name+i, + sizeof extsym.n_name); + writeout((char *) &extsym, sizeof extsym); + ++nsym; + } + } +#endif } } seekout((unsigned long) offsetof(struct exec, a_syms)); diff --git a/libc/Makefile b/libc/Makefile index 640c468..2e1ffd3 100644 --- a/libc/Makefile +++ b/libc/Makefile @@ -11,7 +11,7 @@ endif VERMAJOR=0 VERMINOR=14 -VERPATCH=5 +VERPATCH=7 VER=$(VERMAJOR).$(VERMINOR).$(VERPATCH) CC=bcc @@ -76,13 +76,11 @@ clean: ############################################################################ install_incl: - # rm -rf $(BCCHOME)/include - rm -rf $(BCCHOME)/include/linuxmt $(BCCHOME)/include/arch - cp -pr include $(BCCHOME)/include - if [ -f kinclude/Used ] ; \ - then cp -pr kinclude/arch $(BCCHOME)/include/arch ; \ - cp -pr kinclude/linuxmt $(BCCHOME)/include/linuxmt ; \ - else rm -rf $(BCCHOME)/include/linuxmt $(BCCHOME)/include/arch ; \ + install -d $(BCCHOME)/include + rm -f $(BCCHOME)/include/linuxmt $(BCCHOME)/include/arch ||: + cp -pr include/* $(BCCHOME)/include + if [ ! -f kinclude/Used ] ; \ + then rm -rf $(BCCHOME)/include/linuxmt $(BCCHOME)/include/arch ; \ ln -s $(ELKSSRC)/include/linuxmt $(BCCHOME)/include ; \ ln -s $(ELKSSRC)/include/arch $(BCCHOME)/include ; \ fi diff --git a/libc/Pre_main b/libc/Pre_main index 0b3bec2..f0a5b83 100644 --- a/libc/Pre_main +++ b/libc/Pre_main @@ -1,5 +1,5 @@ -There is now support for calling functions before main and from inside the +There is support for calling functions before main and from inside the exit() function. The exit processing uses the standard 'atexit' and 'on_exit' functions diff --git a/libc/README b/libc/README index 6f45f26..653ed06 100644 --- a/libc/README +++ b/libc/README @@ -12,7 +12,8 @@ are in this version of the combined development environment. Some other versions will work but often they'll just appear to work or not work at all. The original bcc-cc1 won't pickup the right header files, the original ld86 won't generate COM files or 386-Linux files and looks in -the wrong place for crt0.o and libc.a. +the wrong place for crt0.o and libc.a. The original as is just plain +broken! Main Subdirectories. diff --git a/libc/bcc/__ldivmod.c b/libc/bcc/__ldivmod.c index 596d022..359c692 100644 --- a/libc/bcc/__ldivmod.c +++ b/libc/bcc/__ldivmod.c @@ -8,35 +8,35 @@ .text .even -| ldivmod.s - 32 over 32 to 32 bit division and remainder for 8086 +! ldivmod.s - 32 over 32 to 32 bit division and remainder for 8086 -| ldivmod( dividend bx:ax, divisor di:cx ) [ signed quot di:cx, rem bx:ax ] -| ludivmod( dividend bx:ax, divisor di:cx ) [ unsigned quot di:cx, rem bx:ax ] +! ldivmod( dividend bx:ax, divisor di:cx ) [ signed quot di:cx, rem bx:ax ] +! ludivmod( dividend bx:ax, divisor di:cx ) [ unsigned quot di:cx, rem bx:ax ] -| dx is not preserved +! dx is not preserved -| NB negatives are handled correctly, unlike by the processor -| divison by zero does not trap +! NB negatives are handled correctly, unlike by the processor +! divison by zero does not trap -| let dividend = a, divisor = b, quotient = q, remainder = r -| a = b * q + r mod 2^32 -| where: +! let dividend = a, divisor = b, quotient = q, remainder = r +! a = b * q + r mod 2^32 +! where: -| if b = 0, q = 0 and r = a +! if b = 0, q = 0 and r = a -| otherwise, q and r are uniquely determined by the requirements: -| r has the same sign as b and absolute value smaller than that of b, i.e. -| if b > 0, then 0 <= r < b -| if b < 0, then 0 >= r > b -| (the absoulute value and its comparison depend on signed/unsigned) +! otherwise, q and r are uniquely determined by the requirements: +! r has the same sign as b and absolute value smaller than that of b, i.e. +! if b > 0, then 0 <= r < b +! if b < 0, then 0 >= r > b +! (the absoulute value and its comparison depend on signed/unsigned) -| the rule for the sign of r means that the quotient is truncated towards -| negative infinity in the usual case of a positive divisor +! the rule for the sign of r means that the quotient is truncated towards +! negative infinity in the usual case of a positive divisor -| if the divisor is negative, the division is done by negating a and b, -| doing the division, then negating q and r +! if the divisor is negative, the division is done by negating a and b, +! doing the division, then negating q and r .globl ldivmod @@ -105,7 +105,7 @@ divlarge: cmp dx,ax ja zdivu -| rotate w (= b) to greatest dyadic multiple of b <= r +! rotate w (= b) to greatest dyadic multiple of b <= r loop1: shl dx,*1 ! w = 2*w diff --git a/libc/bcc/bcc_bsw.c b/libc/bcc/bcc_bsw.c index a80a679..1693f5a 100644 --- a/libc/bcc/bcc_bsw.c +++ b/libc/bcc/bcc_bsw.c @@ -18,7 +18,7 @@ #ifdef L___laddb #asm -| laddb.s +! laddb.s .globl laddb .globl laddub @@ -37,7 +37,7 @@ laddub: #ifdef L___landb #asm -| landb.s +! landb.s .globl landb .globl landub @@ -56,15 +56,15 @@ landub: #ifdef L___lcmpb #asm -| lcmpb.s -| lcmpb, lcmpub don`t preserve ax +! lcmpb.s +! lcmpb, lcmpub don`t preserve ax .globl lcmpb .globl lcmpub lcmpb: lcmpub: - sub ax,(di) | don`t need to preserve ax + sub ax,(di) ! don`t need to preserve ax je LCMP_NOT_SURE ret @@ -72,17 +72,17 @@ lcmpub: LCMP_NOT_SURE: cmp bx,2(di) - jb LCMP_B_AND_LT | b (below) becomes lt (less than) as well - jge LCMP_EXIT | ge and already ae - | else make gt as well as a (above) - inc ax | clear ov and mi, set ne for greater than + jb LCMP_B_AND_LT ! b (below) becomes lt (less than) as well + jge LCMP_EXIT ! ge and already ae + ! else make gt as well as a (above) + inc ax ! clear ov and mi, set ne for greater than LCMP_EXIT: ret .even LCMP_B_AND_LT: - dec ax | clear ov, set mi and ne for less than + dec ax ! clear ov, set mi and ne for less than ret #endasm #endif @@ -93,7 +93,7 @@ LCMP_B_AND_LT: #ifdef L___lcomb #asm -| lcomb.s +! lcomb.s .globl lcomb .globl lcomub @@ -112,7 +112,7 @@ lcomub: #ifdef L___ldecb #asm -| ldecb.s +! ldecb.s .globl ldecb .globl ldecub @@ -139,8 +139,8 @@ LDEC_BOTH: #ifdef L___ldivb #asm -| ldivb.s -| ax:bx / (di):2(di), quotient ax:bx, remainder cx:di, dx not preserved +! ldivb.s +! ax:bx / (di):2(di), quotient ax:bx, remainder cx:di, dx not preserved .globl ldivb .extern ldivmod @@ -149,7 +149,7 @@ ldivb: xchg ax,bx mov cx,2(di) mov di,(di) - call ldivmod | bx:ax / di:cx, quot di:cx, rem bx:ax + call ldivmod ! bx:ax / di:cx, quot di:cx, rem bx:ax xchg ax,di xchg bx,cx ret @@ -162,8 +162,8 @@ ldivb: #ifdef L___ldivub #asm -| ldivub.s -| unsigned ax:bx / (di):2(di), quotient ax:bx,remainder cx:di, dx not preserved +! ldivub.s +! unsigned ax:bx / (di):2(di), quotient ax:bx,remainder cx:di, dx not preserved .globl ldivub .extern ludivmod @@ -172,7 +172,7 @@ ldivub: xchg ax,bx mov cx,2(di) mov di,(di) - call ludivmod | unsigned bx:ax / di:cx, quot di:cx, rem bx:ax + call ludivmod ! unsigned bx:ax / di:cx, quot di:cx, rem bx:ax xchg ax,di xchg bx,cx ret @@ -185,7 +185,7 @@ ldivub: #ifdef L___leorb #asm -| leorb.s +! leorb.s .globl leorb .globl leorub @@ -204,7 +204,7 @@ leorub: #ifdef L___lincb #asm -| lincb.s +! lincb.s .globl lincb .globl lincub @@ -229,8 +229,8 @@ LINC_HIGH_WORD: #ifdef L___lmodb #asm -| lmodb.s -| ax:bx % (di):2(di), remainder ax:bx, quotient cx:di, dx not preserved +! lmodb.s +! ax:bx % (di):2(di), remainder ax:bx, quotient cx:di, dx not preserved .globl lmodb .extern ldivmod @@ -239,7 +239,7 @@ lmodb: xchg ax,bx mov cx,2(di) mov di,(di) - call ldivmod | bx:ax / di:cx, quot di:cx, rem bx:ax + call ldivmod ! bx:ax / di:cx, quot di:cx, rem bx:ax xchg ax,bx xchg cx,di ret @@ -252,8 +252,8 @@ lmodb: #ifdef L___lmodub #asm -| lmodub.s -| unsigned ax:bx / (di):2(di), remainder ax:bx,quotient cx:di, dx not preserved +! lmodub.s +! unsigned ax:bx / (di):2(di), remainder ax:bx,quotient cx:di, dx not preserved .globl lmodub .extern ludivmod @@ -262,7 +262,7 @@ lmodub: xchg ax,bx mov cx,2(di) mov di,(di) - call ludivmod | unsigned bx:ax / di:cx, quot di:cx, rem bx:ax + call ludivmod ! unsigned bx:ax / di:cx, quot di:cx, rem bx:ax xchg ax,bx xchg cx,di ret @@ -275,8 +275,8 @@ lmodub: #ifdef L___lmulb #asm -| lmulb.s -| lmulb, lmulub don`t preserve cx, dx +! lmulb.s +! lmulb, lmulub don`t preserve cx, dx .globl lmulb .globl lmulub @@ -302,7 +302,7 @@ lmulub: #ifdef L___lnegb #asm -| lnegb.s +! lnegb.s .globl lnegb .globl lnegub @@ -322,7 +322,7 @@ lnegub: #ifdef L___lorb #asm -| lorb.s +! lorb.s .globl lorb .globl lorub @@ -341,8 +341,8 @@ lorub: #ifdef L___lslb #asm -| lslb.s -| lslb, lslub don`t preserve cx +! lslb.s +! lslb, lslub don`t preserve cx .globl lslb .globl lslub @@ -375,8 +375,8 @@ LSL_ZERO: #ifdef L___lsrb #asm -| lsrb.s -| lsrb doesn`t preserve cx +! lsrb.s +! lsrb doesn`t preserve cx .globl lsrb @@ -395,7 +395,7 @@ LSR_EXIT: .even LSR_SIGNBIT: - mov cx,*32 | equivalent to +infinity in this context + mov cx,*32 ! equivalent to +infinity in this context j LSR_LOOP #endasm #endif @@ -406,8 +406,8 @@ LSR_SIGNBIT: #ifdef L___lsrub #asm -| lsrub.s -| lsrub doesn`t preserve cx +! lsrub.s +! lsrub doesn`t preserve cx .globl lsrub @@ -438,7 +438,7 @@ LSRU_ZERO: #ifdef L___lsubb #asm -| lsubb.s +! lsubb.s .globl lsubb .globl lsubub @@ -457,8 +457,8 @@ lsubub: #ifdef L___ltstb #asm -| ltstb.s -| ltstb, ltstub don`t preserve ax +! ltstb.s +! ltstb, ltstub don`t preserve ax .globl ltstb .globl ltstub @@ -479,7 +479,7 @@ LTST_NOT_SURE: .even LTST_FIX_SIGN: - inc ax | clear ov and mi, set ne for greater than + inc ax ! clear ov and mi, set ne for greater than ret #endasm #endif diff --git a/libc/bcc/bcc_int.c b/libc/bcc/bcc_int.c index 028a3f1..ae02a8a 100644 --- a/libc/bcc/bcc_int.c +++ b/libc/bcc/bcc_int.c @@ -17,8 +17,8 @@ #ifdef L___idiv #asm -| idiv.s -| idiv_ doesn`t preserve dx (returns remainder in it) +! idiv.s +! idiv_ doesn`t preserve dx (returns remainder in it) .globl idiv_ @@ -35,8 +35,8 @@ idiv_: #ifdef L___idivu #asm -| idivu.s -| idiv_u doesn`t preserve dx (returns remainder in it) +! idivu.s +! idiv_u doesn`t preserve dx (returns remainder in it) .globl idiv_u @@ -53,8 +53,8 @@ idiv_u: #ifdef L___imod #asm -| imod.s -| imod doesn`t preserve dx (returns quotient in it) +! imod.s +! imod doesn`t preserve dx (returns quotient in it) .globl imod @@ -72,8 +72,8 @@ imod: #ifdef L___imodu #asm -| imodu.s -| imodu doesn`t preserve dx (returns quotient in it) +! imodu.s +! imodu doesn`t preserve dx (returns quotient in it) .globl imodu @@ -91,8 +91,8 @@ imodu: #ifdef L___imul #asm -| imul.s -| imul_, imul_u don`t preserve dx +! imul.s +! imul_, imul_u don`t preserve dx .globl imul_ .globl imul_u @@ -110,8 +110,8 @@ imul_u: #ifdef L___isl #asm -| isl.s -| isl, islu don`t preserve cl +! isl.s +! isl, islu don`t preserve cl .globl isl .globl islu @@ -130,8 +130,8 @@ islu: #ifdef L___isr #asm -| isr.s -| isr doesn`t preserve cl +! isr.s +! isr doesn`t preserve cl .globl isr @@ -148,8 +148,8 @@ isr: #ifdef L___isru #asm -| isru.s -| isru doesn`t preserve cl +! isru.s +! isru doesn`t preserve cl .globl isru diff --git a/libc/bcc/bcc_io.c b/libc/bcc/bcc_io.c index d7af86f..8f7285e 100644 --- a/libc/bcc/bcc_io.c +++ b/libc/bcc/bcc_io.c @@ -19,8 +19,8 @@ #ifdef L___inport #asm -| int inport( int port ); -| reads a word from the i/o port port and returns it +! int inport( int port ); +! reads a word from the i/o port port and returns it .globl _inport _inport: @@ -39,8 +39,8 @@ _inport: #ifdef L___inportb #asm -| int inportb( int port ); -| reads a byte from the i/o port port and returns it +! int inportb( int port ); +! reads a byte from the i/o port port and returns it .globl _inportb _inportb: @@ -60,8 +60,8 @@ _inportb: #ifdef L___outport #asm -| void outport( int port, int value ); -| writes the word value to the i/o port port +! void outport( int port, int value ); +! writes the word value to the i/o port port .globl _outport _outport: @@ -80,9 +80,9 @@ _outport: #ifdef L___outportb #asm -| void oportb( int port, char value ); -| writes the byte value to the i/o port port -| this would be outportb except for feeble linkers +! void oportb( int port, char value ); +! writes the byte value to the i/o port port +! this would be outportb except for feeble linkers .globl _oportb _oportb: @@ -101,8 +101,8 @@ _oportb: #ifdef L___peekb #asm -| int peekb( unsigned segment, char *offset ); -| returns the (unsigned) byte at the far pointer segment:offset +! int peekb( unsigned segment, char *offset ); +! returns the (unsigned) byte at the far pointer segment:offset .define _peekb _peekb: @@ -124,8 +124,8 @@ _peekb: #ifdef L___peekw #asm -| int peekw( unsigned segment, int *offset ); -| returns the word at the far pointer segment:offset +! int peekw( unsigned segment, int *offset ); +! returns the word at the far pointer segment:offset .define _peekw _peekw: @@ -146,8 +146,8 @@ _peekw: #ifdef L___pokeb #asm -| void pokeb( unsigned segment, char *offset, char value ); -| writes the byte value at the far pointer segment:offset +! void pokeb( unsigned segment, char *offset, char value ); +! writes the byte value at the far pointer segment:offset .define _pokeb _pokeb: @@ -169,8 +169,8 @@ _pokeb: #ifdef L___pokew #asm -| void pokew( unsigned segment, int *offset, int value ); -| writes the word value at the far pointer segment:offset +! void pokew( unsigned segment, int *offset, int value ); +! writes the word value at the far pointer segment:offset .define _pokew _pokew: diff --git a/libc/bcc/bcc_long.c b/libc/bcc/bcc_long.c index 4d1f7d8..3d59457 100644 --- a/libc/bcc/bcc_long.c +++ b/libc/bcc/bcc_long.c @@ -19,7 +19,7 @@ #ifdef L___laddl #asm -| laddl.s +! laddl.s .globl laddl .globl laddul @@ -38,7 +38,7 @@ laddul: #ifdef L___landl #asm -| landl.s +! landl.s .globl landl .globl landul @@ -57,8 +57,8 @@ landul: #ifdef L___lcmpl #asm -| lcmpl.s -| lcmpl, lcmpul don`t preserve bx +! lcmpl.s +! lcmpl, lcmpul don`t preserve bx .globl lcmpl .globl lcmpul @@ -94,7 +94,7 @@ LCMP_B_AND_LT: #ifdef L___lcoml #asm -| lcoml.s +! lcoml.s .globl lcoml .globl lcomul @@ -113,7 +113,7 @@ lcomul: #ifdef L___ldecl #asm -| ldecl.s +! ldecl.s .globl ldecl .globl ldecul @@ -140,8 +140,8 @@ LDEC_BOTH: #ifdef L___ldivl #asm -| ldivl.s -| bx:ax / 2(di):(di), quotient bx:ax, remainder di:cx, dx not preserved +! ldivl.s +! bx:ax / 2(di):(di), quotient bx:ax, remainder di:cx, dx not preserved .globl ldivl .extern ldivmod @@ -163,8 +163,8 @@ ldivl: #ifdef L___ldivul #asm -| ldivul.s -| unsigned bx:ax / 2(di):(di), quotient bx:ax,remainder di:cx, dx not preserved +! ldivul.s +! unsigned bx:ax / 2(di):(di), quotient bx:ax,remainder di:cx, dx not preserved .globl ldivul .extern ludivmod @@ -185,7 +185,7 @@ ldivul: #ifdef L___leorl #asm -| leorl.s +! leorl.s .globl leorl .globl leorul @@ -204,7 +204,7 @@ leorul: #ifdef L___lincl #asm -| lincl.s +! lincl.s .globl lincl .globl lincul @@ -229,8 +229,8 @@ LINC_HIGH_WORD: #ifdef L___lmodl #asm -| lmodl.s -| bx:ax % 2(di):(di), remainder bx:ax, quotient di:cx, dx not preserved +! lmodl.s +! bx:ax % 2(di):(di), remainder bx:ax, quotient di:cx, dx not preserved .globl lmodl .extern ldivmod @@ -249,8 +249,8 @@ lmodl: #ifdef L___lmodul #asm -| lmodul.s -| unsigned bx:ax / 2(di):(di), remainder bx:ax,quotient di:cx, dx not preserved +! lmodul.s +! unsigned bx:ax / 2(di):(di), remainder bx:ax,quotient di:cx, dx not preserved .globl lmodul .extern ludivmod @@ -269,8 +269,8 @@ lmodul: #ifdef L___lmull #asm -| lmull.s -| lmull, lmulul don`t preserve cx, dx +! lmull.s +! lmull, lmulul don`t preserve cx, dx .globl lmull .globl lmulul @@ -295,7 +295,7 @@ lmulul: #ifdef L___lnegl #asm -| lnegl.s +! lnegl.s .globl lnegl .globl lnegul @@ -315,7 +315,7 @@ lnegul: #ifdef L___lorl #asm -| lorl.s +! lorl.s .globl lorl .globl lorul @@ -334,8 +334,8 @@ lorul: #ifdef L___lsll #asm -| lsll.s -| lsll, lslul don`t preserve cx +! lsll.s +! lsll, lslul don`t preserve cx .globl lsll .globl lslul @@ -368,8 +368,8 @@ LSL_ZERO: #ifdef L___lsrl #asm -| lsrl.s -| lsrl doesn`t preserve cx +! lsrl.s +! lsrl doesn`t preserve cx .globl lsrl @@ -399,8 +399,8 @@ LSR_SIGNBIT: #ifdef L___lsrul #asm -| lsrul.s -| lsrul doesn`t preserve cx +! lsrul.s +! lsrul doesn`t preserve cx .globl lsrul @@ -431,7 +431,7 @@ LSRU_ZERO: #ifdef L___lsubl #asm -| lsubl.s +! lsubl.s .globl lsubl .globl lsubul @@ -450,8 +450,8 @@ lsubul: #ifdef L___ltstl #asm -| ltstl.s -| ltstl, ltstul don`t preserve bx +! ltstl.s +! ltstl, ltstul don`t preserve bx .globl ltstl .globl ltstul diff --git a/libc/bios/Makefile b/libc/bios/Makefile index b617e50..8436846 100644 --- a/libc/bios/Makefile +++ b/libc/bios/Makefile @@ -4,13 +4,13 @@ ifeq ($(LIB_OS),BIOS) ASRC=bios.c -AOBJ=bios_start.o bios_isatty.o \ +AOBJ=bios_start.o bios_isatty.o bios_nofiles.o \ bios_open.o bios_read.o bios_write.o bios_lseek.o bios_close.o BSRC=bios_vid.c BOBJ=bios_putc.o bios_getc.o bios_khit.o bios_rdline.o -OBJ=$(AOBJ) $(BOBJ) time.o +OBJ=$(AOBJ) $(BOBJ) time.o fileops.o fs_dos.o rawio.o CFLAGS=$(ARCH) $(CCFLAGS) $(DEFS) diff --git a/libc/bios/bios.c b/libc/bios/bios.c index a8d2079..2290472 100644 --- a/libc/bios/bios.c +++ b/libc/bios/bios.c @@ -7,13 +7,14 @@ #ifdef __AS386_16__ #ifdef __STANDALONE__ -#include <dos.h> +#include <bios.h> #include <fcntl.h> #include <errno.h> -int errno; #ifdef L_bios_start + char ** environ = { 0 }; +int errno; void (*__cleanup)() = 0; @@ -119,27 +120,6 @@ reti_ins: /****************************************************************************/ -#ifdef L___file_3 - -/* If the block function does track buffering this should be ok ... */ -struct { - int (*block_rw)(); /* Args (rwoc, &buffer, blockno) 1k blocks */ - /* 0 = read, 1 = write */ - /* 2 = open, buffer is fname ptr */ - /* 3 = close, other args ignored */ - long offset; - - int flags; - long block_num; - char buffer[1024]; -} __file_3_data; - -#define FILE3_OPEN 1 /* File is open */ -#define FILE3_DATA 2 /* buffer has valid contents */ -#define FILE3_DIRTY 4 /* buffer has been modified */ - -#endif - #ifdef L_bios_write write(fd,buf,len) int fd,len; @@ -155,9 +135,8 @@ char * buf; bios_putc(c); } return len; - } - errno = EBADF; - return -1; + } + return (*__files)(CMD_WRITE, fd, buf, len); } #endif @@ -169,8 +148,7 @@ int fd,len; char * buf; { if(fd == 0) return bios_rdline(buf, len); - errno = EBADF; - return -1; + return (*__files)(CMD_READ, fd, buf, len); } #endif @@ -183,33 +161,41 @@ int fd, whence; long offt; { if( fd >= 0 && fd <= 2 ) errno = ESPIPE; - else errno = EBADF; + else + { + if( (*__files)(CMD_LSEEK, fd, &offt, whence) >= 0 ) + return offt; + } return -1L; } #endif /****************************************************************************/ -#ifdef L_bios_open -open(name, flags, mode) -char * name; -int flags, mode; +#ifdef L_bios_close +close(fd) +int fd; { - errno = ENOENT; + if( fd >= 0 && fd <= 2 ) errno = ENOSYS; + else + return (*__files)(CMD_CLOSE, fd); return -1; } #endif /****************************************************************************/ -#ifdef L_bios_close -close(fd) -int fd; -{ - if( fd >= 0 && fd <= 2 ) errno = ENOSYS; - else errno = EBADF; +#ifdef L_bios_nofiles +int (*__files)() = __nofiles; + +int __nofiles(cmd, fd, buf, len) +int cmd, fd, len; +char * buf; +{ + errno = EBADF; return -1; } + #endif /****************************************************************************/ @@ -225,6 +211,21 @@ int fd; /****************************************************************************/ +#ifdef L_bios_open +extern int __fileops(); + +open(name, flags, mode) +char * name; +int flags, mode; +{ + __files = __fileops; + return (*__files)(CMD_OPEN, flags, name, mode); +} + +#endif + +/****************************************************************************/ + #endif #endif #endif diff --git a/libc/bios/bios_vid.c b/libc/bios/bios_vid.c index cc49736..8bf375a 100644 --- a/libc/bios/bios_vid.c +++ b/libc/bios/bios_vid.c @@ -4,7 +4,7 @@ */ /* Various possible console types */ -#define VT52_CON /* IMO the best, no clear to EOS/EOL yet */ +#define VT52_CON /* IMO the best, no clear to EOS/EOL tho */ #define XANSI_CON /* Largest but still not complete */ #define XDUMB_CON /* Can't do much */ #define XSPEC_CON /* Incomplete, best for slow links */ @@ -13,7 +13,7 @@ #ifdef __AS386_16__ #ifdef __STANDALONE__ -#include <dos.h> +#include <bios.h> #include <errno.h> int errno; diff --git a/libc/bios/cprintf.c b/libc/bios/cprintf.c new file mode 100644 index 0000000..5f8beaa --- /dev/null +++ b/libc/bios/cprintf.c @@ -0,0 +1,128 @@ + +#include <stdarg.h> +#define wchar(ch) putch(ch) + +cprintf(char * fmt, va_list ap) +{ + register int c; + int count = 0; + int type, base; + long val; + char * cp; + char padch=' '; + int minsize = 0; + + while(c=*fmt++) + { + if(c!='%') + { + wchar(c); + count++; + } + else + { + type=1; + do { c=*fmt++; } while( c>='0' && c<='9'); + + padch = *fmt; + minsize=0; + if(padch == '-') fmt++; + + for(;;) + { + c=*fmt++; + if( c<'0' || c>'9' ) break; + minsize*=10; minsize+=c-'0'; + } + + while( c=='.' || (c>='0' && c<='9')) { c=*fmt++; } + + if( padch == '-' ) minsize = -minsize; + else + if( padch == '0' ) padch='0'; else padch=' '; + + if( c == 0 ) break; + if(c=='h') + { + c=*fmt++; + type = 0; + } + else if(c=='l') + { + c=*fmt++; + type = 2; + } + + switch(c) + { + case 'x': base=16; if(0) { + case 'o': base= 8; } if(0) { + case 'd': base=10; } + val=0; + switch(type) + { + case 0: val=va_arg(ap, short); break; + case 1: val=va_arg(ap, int); break; + case 2: val=va_arg(ap, long); break; + } + cp = __numout(val,base); + if(0) { + case 's': + cp=va_arg(ap, char *); + } + if( minsize > 0 ) + { + minsize -= strlen(cp); + while(minsize>0) { wchar(padch); minsize--; } + minsize=0; + } + if( minsize < 0 ) minsize= -minsize-strlen(cp); + while(*cp) + wchar(*cp++); + while(minsize>0) { wchar(' '); minsize--; } + break; + case 'c': + wchar(va_arg(ap, int)); + break; + default: + wchar(c); + break; + } + } + } + return count; +} + + + +static char nstring[]="0123456789ABCDEF"; + +static unsigned char * +__numout(long i, int base) +{ + static unsigned char out[16]; + int n; + int flg = 0; + unsigned long val; + + if (i<0 && base==10) + { + flg = 1; + i = -i; + } + val = i; + + for (n = 0; n < 15; n++) + out[n] = ' '; + out[15] = '\0'; + n = 14; + do + { + out[n] = nstring[val % base]; + n--; + val /= base; + } + while(val); + if(flg) out[n--] = '-'; + return &out[n+1]; +} diff --git a/libc/bios/fileops.c b/libc/bios/fileops.c new file mode 100644 index 0000000..5c71a37 --- /dev/null +++ b/libc/bios/fileops.c @@ -0,0 +1,168 @@ + +#include <bios.h> +#include <fcntl.h> +#include <errno.h> + +#include "io.h" +#include "rawio.h" + +static int op_open(); +static int op_close(); +static int op_read(); +static int op_write(); +static long op_lseek(); + +int +__fileops(cmd, fd, buf, len) +int cmd, fd, len; +char * buf; +{ + switch(cmd) + { + case CMD_OPEN: return op_open(buf, fd, len); + case CMD_READ: return op_read(fd, buf, len); +/* + case CMD_WRITE: return op_write(fd, buf, len); + case CMD_LSEEK: rv = op_lseek(fd, *(long*)buf, len); + (*(long*)buf) = rv; + if( rv == -1 ) return -1; + else return 0; + */ + case CMD_CLOSE: return op_close(fd); + } + + errno=EINVAL; + return -1; +} + +#define MAX_OPEN_FILES 5 +ioblock _iob[MAX_OPEN_FILES]; + +static int +op_read(fd,buf,len) +int fd,len; +char * buf; +{ + ioblock* cur = &_iob[fd]; + int amount_read = 0; + int amount_left_in_buffer; + int amount_to_copy; + + if (fd >= MAX_OPEN_FILES || _iob[fd].block_read == 0) + { + errno = EBADF; + return -1; + } + + while (len > 0) + { + /* pull in next block as required */ + if (cur->amount_left <= 0) + { + int read_len = cur->block_read(cur, + cur->buffer, + (long) cur->offset / sizeof(cur->buffer) + ); +#ifdef DEBUG + fprintf(stderr, "br: returned %d\n", read_len); +#endif + if (read_len <= 0) + break; + cur->amount_left = read_len; + } + if (cur->amount_left > len) + amount_to_copy = len; + else + amount_to_copy = cur->amount_left; + +#ifdef DEBUG + fprintf(stderr, "r: len=%d, amount_left=%ld, offset=%ld, buf=%x\n", + len, cur->amount_left, cur->offset, + (int) cur->buffer[cur->offset % sizeof(cur->buffer)]); +#endif + memcpy(buf, + &cur->buffer[cur->offset % sizeof(cur->buffer)], + amount_to_copy); + amount_read += amount_to_copy; + len -= amount_to_copy; + cur->offset += amount_to_copy; + buf += amount_to_copy; + cur->amount_left -= amount_to_copy; + } + return amount_read; +} + +/****************************************************************************/ + +static int +op_open(name, flags, mode) +char * name; +int flags, mode; +{ + int fd; + ioblock* cur; + + /* + * discover whether the iob has been initialised or not + */ + if (_iob[0].flags == 0) + { + _iob[0].flags = O_RDONLY; + _iob[1].flags = O_WRONLY; + _iob[2].flags = O_WRONLY; + } + /* + * discover next free iob + */ + for (fd = 3; fd < MAX_OPEN_FILES; ++fd) + { + if (_iob[fd].block_read == NULL && _iob[fd].block_write == NULL) + break; + } + if (fd >= MAX_OPEN_FILES) + { + errno = EMFILE; /* too many open files */ + return -1; + } + + /* + * try and find the file + */ + cur = &_iob[fd]; + if (fsdos_open_file(cur, name, flags, mode) >= 0) + { + cur->amount_left = 0; + cur->offset = 0; + return fd; + } + cur->block_read = NULL; /* ensure that the file is closed */ + cur->block_write = NULL; + errno = ENOENT; + return -1; +} + +/****************************************************************************/ + +static int +op_close(fd) +int fd; +{ + if (fd >= MAX_OPEN_FILES || _iob[0].flags == 0) + { + errno = EBADF; + return -1; + } + else + { + ioblock* cur = &_iob[fd]; + cur->close(cur); + cur->block_read = NULL; + cur->block_write = NULL; + cur->close = NULL; + cur->flags = 0; + return 0; + } +} + +/****************************************************************************/ + diff --git a/libc/bios/fs_dos.c b/libc/bios/fs_dos.c new file mode 100644 index 0000000..28ee962 --- /dev/null +++ b/libc/bios/fs_dos.c @@ -0,0 +1,421 @@ + +#include <stdio.h> +#include <ctype.h> +#include <malloc.h> +#include <errno.h> +#include "io.h" +#include "rawio.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) +#define DOS_NFAT(P) get_byte(P,0x10) +#define DOS_NROOT(P) get_uint(P,0x11) +#define DOS_MAXSECT(P) get_uint(P,0x13) +#define DOS_MEDIA(P) get_byte(P,0x15) +#define DOS_FATLEN(P) get_uint(P,0x16) +#define DOS_SPT(P) get_uint(P,0x18) +#define DOS_HEADS(P) get_uint(P,0x1A) +#define DOS_HIDDEN(P) get_long(P,0x1C) +#define DOS4_MAXSECT(P) get_long(P,0x20) +#define DOS4_PHY_DRIVE(P) get_byte(P,0x24) +#define DOS4_SERIAL(P) get_long(P,0x27) + +/* These assume alignment is not a problem */ +#define get_byte(P,Off) *((unsigned char*)((char*)(P)+(Off))) +#define get_uint(P,Off) *((unsigned short*)((char*)(P)+(Off))) +#define get_long(P,Off) *((long*)((char*)(P)+(Off))) + +static int read_bootblock(); +static int dir_nentry, dir_sect; +static int dos_clust0, dos_spc, dos_fatpos; +static int last_serial = 0; + +#ifdef BUFFER_FAT +static char * fat_buf = 0; +#endif + +struct filestatus { + char fname[12]; + unsigned short first_cluster; + unsigned short cur_cluster; + unsigned short sector_no; + long file_length; +}; + +static int fsdos_read_block(); +static int fsdos_close_file(); + +/* buffer to read into */ +static char sect[512]; + +fsdos_open_file(iob, fname, flags, mode) +ioblock* iob; +char * fname; +int flags; +int mode; +{ + extern union REGS __argr; + char conv_name[12]; + char *d, *s; + int i; + int dodir = 0; + struct filestatus* cur_file; + +#ifdef DEBUG + printf("fsdos_open_file(%x, %s, %d, %d, %d)\n", + iob, fname, flags, mode, sizeof(iob)); +#endif + iob->block_read = fsdos_read_block; + iob->close = fsdos_close_file; + + /* Get the superblock */ + if( read_bootblock() < 0 ) return -1; + + if(strcmp(fname, ".") == 0) + dodir = 1; + else + { + /* Convert the name to MSDOS directory format */ + strcpy(conv_name, " "); + for(s=fname, d=conv_name; *s && *d && *s != '.' && *s != ' '; s++) + { + if( islower(*s) ) *d++ = toupper(*s); + else *d++ = *s; + } + while( *s && *s != '.' ) s++; + strcpy(d=(conv_name+8), " "); + if( *s == '.' ) + { + for(s++; *s && *d; s++) + { + if( islower(*s) ) *d++ = toupper(*s); + else *d++ = *s; + } + } + } +#ifdef DEBUG + printf("fsdos_open_file: converted filename=<%s>\n", conv_name); +#endif + +#ifdef BUFFER_FAT + rawio_read_sector(0, sect); + + if( !dodir ) + { + /* Read in and buffer the FAT */ + if( fat_buf ) free(fat_buf); + fat_buf = malloc(DOS_FATLEN(sect) * 512); + if( fat_buf == 0 ) + { + errno = ENOMEM; + return -1; + } + else + { + int fatsec = DOS_RESV(sect); + int nsec = DOS_FATLEN(sect); + + for(i=0; i<nsec; i++) + { + if (rawio_read_sector(fatsec+i, sect) == 0) + { + errno = EIO; + return -1; + } + memcpy(fat_buf+i*512, sect, 512); + } + } + } +#endif + + /* Scan the root directory for the file */ + s = sect; + for(i=0; i<dir_nentry; i++) + { + if (rawio_read_sector(dir_sect+i/16, sect) == 0) + { + errno = EIO; + return -1; + } + d = s + (i%16)*32; + 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), + ((get_uint(d,24)>>9)&0x7F)+1980, + ((get_uint(d,22)>>11)&0x1F), + ((get_uint(d,22)>>5)&0x3F) + ); + if( *d > ' ' && *d <= '~' ) switch(d[11]&0x18) + { + case 0: + printf("%-8.8s %-3.3s %10ld%s\n", d, d+8, get_long(d,28), dtime); + break; + case 0x10: + printf("%-8.8s %-3.3s <DIR> %s\n", d, d+8, dtime); + break; + case 8: + if( (d[11] & 7) == 0 ) + printf("%-11.11s <LBL> %s\n", d, dtime); + break; + } +#if 0 + if( more_strn(lbuf, sizeof(lbuf)) < 0 ) break; +#endif + } + else if( memcmp(d, conv_name, 11) == 0 && (d[11]&0x18) == 0 ) + { /* Name matches and is normal file */ + +#ifdef DEBUG + fprintf(stderr, "dos_open_file: %s worked\n", fname); +#endif + cur_file = malloc(sizeof(*cur_file)); + + iob->context = cur_file; + if (iob->context == NULL) + { + errno = ENOMEM; + return -1; + } + memset(cur_file, '\0', sizeof(*cur_file)); + strcpy(cur_file->fname, conv_name); + cur_file->first_cluster = get_uint(d,26); + cur_file->file_length = get_long(d,28); + + cur_file->cur_cluster = cur_file->first_cluster; + cur_file->sector_no = 0; + + return 0; + } + } + return -1; +} + +fsdos_rewind_file(iob) +ioblock* iob; +{ + struct filestatus* cur_file; + + if (iob == NULL || iob->context == NULL) + { + errno = EBADF; + return -1; + } + + cur_file = (struct filestatus*) iob->context; + /* Is there an opened file ? */ + if( cur_file->fname[0] == 0 ) return -1; + + cur_file->sector_no = 0; + cur_file->cur_cluster = cur_file->first_cluster; + return 0; +} + +static int fsdos_close_file(iob) +ioblock* iob; +{ + struct filestatus* cur_file; + + if (iob == NULL || iob->context == NULL) + { + errno = EBADF; + return -1; + } + cur_file = (struct filestatus*) iob->context; + free(cur_file); + iob->context = NULL; + +#ifdef BUFFER_FAT + if( fat_buf ) free(fat_buf); + fat_buf = 0; +#endif + + rawio_reset_disk(); + return 0; +} + +long +fsdos_file_length(iob) +ioblock* iob; +{ + struct filestatus* cur_file; + + if (iob == NULL || iob->context == NULL) + { + errno = EBADF; + return -1; + } + cur_file = (struct filestatus*) iob->context; + + /* Is there an opened file ? */ + if( cur_file->fname[0] == 0 ) return -1; + + return cur_file->file_length; +} + +static int fsdos_read_block(iob, buffer, block) +ioblock* iob; +char * buffer; +long block; /* ignored for now */ +{ + int s; + char * ptr = buffer; + struct filestatus* cur_file; + long amount_left_in_file; + long amount_to_read; + +#ifdef DEBUG + fprintf(stderr, "rb: iob = %x, buf = %x, block = %ld\n", + iob, buffer, block); +#endif + if (iob == NULL || iob->context == NULL) + { + fprintf(stderr, "rb: no context\n"); + errno = EBADF; + return -1; + } + cur_file = (struct filestatus*) iob->context; + + /* Is there an opened file ? */ + if( cur_file->fname[0] == 0 ) + { +#ifdef DEBUG + fprintf(stderr, "fsdos_read_block: File is not currently open!\n"); +#endif + errno = EBADF; + return -1; + } + + amount_left_in_file = cur_file->file_length - block * 1024; + + if (amount_left_in_file < 0) + { +#ifdef DEBUG + fprintf(stderr, "EOF\n"); +#endif + return 0; + } + + /* Are we before the EOF ? NB: FAT12 ONLY! */ + if( cur_file->cur_cluster >= 0xFF0 || cur_file->cur_cluster < 2 ) + { +#ifdef DEBUG + fprintf(stderr, "Hit end of file; cluster 0x%03x\n", + cur_file->cur_cluster); +#endif + return 0; + } + + for(s=0; s<2; s++) + { + unsigned int sectno; + + if (amount_left_in_file <= 0) + { +#ifdef DEBUG + fprintf(stderr, "r2: Hit end of file\n"); +#endif + break; + } + + sectno = dos_clust0 + + cur_file->cur_cluster * dos_spc + + cur_file->sector_no % dos_spc; + + if (rawio_read_sector(sectno, ptr) <= 0) + { +#ifdef DEBUG + fprintf(stderr, "r2: rawio failed\n"); +#endif + return -1; + } + + cur_file->sector_no++; + if( cur_file->sector_no % dos_spc == 0 ) + { + int odd = (cur_file->cur_cluster&1); + unsigned int val, val2; + + val = cur_file->cur_cluster + (cur_file->cur_cluster>>1); +#ifdef BUFFER_FAT + val2 = get_uint(fat_buf, val); +#else + if (rawio_read_sector(dos_fatpos+(val/512), sect) <= 0) return -1; + if( val%512 == 511 ) + { + val2 = sect[511] & 0xFF; + if (rawio_read_sector(dos_fatpos+(val/512)+1, sect) <= 0) return -1; + val2 |= (sect[0]<<8); + } + else + val2 = get_uint(sect, (val%512)); +#endif + + if( odd ) val2>>=4; + + val2 &= 0xFFF; + + cur_file->cur_cluster = val2; + } + + amount_to_read = amount_left_in_file; + if (amount_to_read > 512) amount_to_read = 512; + ptr += amount_to_read; + amount_left_in_file -= amount_to_read; + } + + return ptr - buffer; +} + +static int read_bootblock() +{ + int rv, media_byte = 0; + +#ifdef DEBUG + printf("fs_dos:read_bootblock:\n"); +#endif + if (rawio_read_sector(1, sect) <= 0) return -1; + media_byte = *(unsigned char*)sect; + + /* Valid media byte ? */ + if( (media_byte & 0xF0) != 0xF0 ) return -1; + if (rawio_read_sector(0, sect) <= 0) return -1; + + if( DOS_MEDIA(sect) != media_byte ) return -1; + if( DOS_SPT(sect) > 63 ) return -1; + if( DOS_SECT(sect) != 512 ) return -1; + + if( last_serial != DOS4_SERIAL(sect) ) fsdos_close_file(); + last_serial = DOS4_SERIAL(sect); + + /* Collect important data */ + dir_sect = DOS_RESV(sect) + DOS_NFAT(sect)*DOS_FATLEN(sect); + dir_nentry = DOS_NROOT(sect); + + dos_fatpos = DOS_RESV(sect); + dos_spc = DOS_CLUST(sect); + if( dos_spc < 1 ) dos_spc = 1; + dos_clust0 = dir_sect + (dir_nentry+15)/16 - 2*dos_spc; + + if( rawio_disk_cyls == 0 ) + { + rawio_disk_spt = DOS_SPT(sect); + rawio_disk_heads = DOS_HEADS(sect); + } + +#ifdef DEBUG + printf("read_bootblock: heads(%d), spt(%d), dir_sect(%d)\n", + rawio_disk_heads, + rawio_disk_spt, + dir_sect); +#endif + return 0; +} diff --git a/libc/bios/io.h b/libc/bios/io.h new file mode 100644 index 0000000..a098e03 --- /dev/null +++ b/libc/bios/io.h @@ -0,0 +1,22 @@ +#ifndef __io_h__ +#define __io_h__ + +typedef struct { + /* + * both block_read/block_write should be defined as + * int x(ioblock* iob, char* buffer, int blockno) + * and it reads/writes 1k blocks + * + * close should be defined as int x(ioblock* ioblock); + */ + int (*block_read)(); /* read routine */ + int (*block_write)(); /* write routine - not supported yet*/ + int (*close)(); /* close routine */ + long offset; /* current offset in file to read/write */ + int flags; + long amount_left; /* amount left in buffer */ + char buffer[1024]; + void* context; +} ioblock; + +#endif diff --git a/libc/bios/rawio.c b/libc/bios/rawio.c new file mode 100644 index 0000000..1bb0e4d --- /dev/null +++ b/libc/bios/rawio.c @@ -0,0 +1,327 @@ +/* + * rawio.c - plagiarised from ../../bootblocks/trk_buf.c + */ + +#include <stdio.h> +#include <bios.h> +#include <ctype.h> +#include <malloc.h> +#include "rawio.h" + +int rawio_disk_drive = 0; +int rawio_disk_spt = 7; +int rawio_disk_heads = 2; +int rawio_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 rawio_get_dpt(); + +void rawio_reset_disk() +{ + if( data_buf1 ) free(data_buf1); + if( data_buf2 ) free(data_buf2); + data_buf1 = data_buf2 = 0; + last_drive = rawio_disk_drive; + + if( !(rawio_disk_drive & 0x80 ) ) + { + rawio_disk_spt = 7; /* Defaults for reading Boot area. */ + rawio_disk_heads = 2; + rawio_disk_cyls = 0; +#ifdef DEBUG + fprintf(stderr, "reset_disk (hard): spt = %d, heads = %d, cyls = %d\n", + rawio_disk_spt, + rawio_disk_heads, + rawio_disk_cyls); +#endif + } +#if defined(__MSDOS__) || defined(__STANDALONE__) + else + { + /* Hard disk, get parameters from bios */ + long dpt; + int v; + + rawio_disk_spt = 17; /* Defaults for reading Boot area. */ + rawio_disk_heads = 1; + rawio_disk_cyls = 0; + + dpt = rawio_get_dpt(rawio_disk_drive); + v = ((dpt>>16) & 0xFF); + if( v == 0xFF || v <= (rawio_disk_drive&0x7F) ) return; /* Bad dpt */ + + rawio_disk_spt = (dpt & 0x3F); /* Max sector number 1-63 */ + if( rawio_disk_spt == 0 ) rawio_disk_spt = 64; /* 1-64 ? */ + rawio_disk_heads = ((dpt>>24) & 0xFF) + 1; /* Head count 1-256 */ + rawio_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. + */ +#ifdef DEBUG + fprintf(stderr, "reset_disk (soft): spt = %d, heads = %d, cyls = %d\n", + rawio_disk_spt, + rawio_disk_heads, + rawio_disk_cyls); +#endif + } +#endif +} + +int rawio_read_lsector(sectno, buffer) +long sectno; +char* buffer; +{ + int tries = 6; + int rv; + + int phy_s = 1; + int phy_h = 0; + int phy_c = 0; + + if( rawio_disk_drive != last_drive ) rawio_reset_disk(); + + if( rawio_disk_spt < 0 || rawio_disk_spt > 63 || rawio_disk_heads < 1 ) + { + phy_s = sectno; + rawio_reset_disk(); + +#ifdef DEBUG + fprintf(stderr, "read_sector(%ld = %d,%d,%d)\n", + sectno, phy_c, phy_h, phy_s+1); +#endif + } + else + { + phy_s = sectno%rawio_disk_spt; + phy_h = sectno/rawio_disk_spt%rawio_disk_heads; + phy_c = sectno/rawio_disk_spt/rawio_disk_heads; + +#ifdef DEBUG + fprintf(stderr, "read_sector(%ld = %d,%d,%d)\n", + sectno, phy_c, phy_h, phy_s+1); +#endif + if( rawio_fetch_track_buf(phy_c, phy_h, phy_s) >= 0 ) + { +#ifdef DEBUG + fprintf(stderr, "read_sector: ftb worked\n"); +#endif + memcpy(buffer, data_buf1 + (phy_s % data_len) * 512, 512); + return 512; + } + } + + data_len = -1; /* Zap the cache */ + if( data_buf1 == 0 ) + data_buf1 = malloc(512); + if( data_buf1 == 0 ) + { + fprintf(stderr, "Cannot allocate memory for disk read!!!\n"); + return 0; + } + + fprintf(stderr, "WARNING: Single sector read\n"); + + do + { + rv = rawio_phy_read(rawio_disk_drive, phy_c, phy_h, phy_s+1, 1, data_buf1); + tries--; + if( rv ) fprintf(stderr, "Error in phy_read(%d,%d,%d,%d,%d,%d);\n", + rawio_disk_drive, phy_c, phy_h, phy_s+1, 1, data_buf1); + } + while(rv && tries > 0); + + if(rv) + { +#ifdef DEBUG + fprintf(stderr, "rawio failed\n"); +#endif + return 0; + } + else + { +#ifdef DEBUG + fprintf(stderr, "rawio worked\n"); +#endif + memcpy(buffer, data_buf1, 512); + return 512; + } +} + +rawio_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 = (rawio_disk_spt-1)/22; + nlen = (rawio_disk_spt+nlen)/(nlen+1); + trk_no = (long)phy_c*rawio_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 = rawio_disk_spt; + } +#ifdef DEBUG + fprintf(stderr, + "ftb: trk_no=%ld, data_trk1=%ld, data_buf1=%x\n", + trk_no, + data_trk1, + data_buf1); +#endif + 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; + +#ifdef DEBUG + fprintf(stderr, "ftb swap: trk_no=%ld, data_trk1=%ld, data_buf1=%x\n", + trk_no, + data_trk1, + data_buf1); +#endif + /* 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(rawio_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; + +#ifdef DEBUG + fprintf(stderr, "ftb buf: trk_no=%ld, data_trk1=%ld, data_buf1=%x\n", + trk_no, + data_trk1, + data_buf1); +#endif + /* Not enough memory for track read. */ + if( data_buf1 == 0 ) return -1; + + do /* the physical read */ + { + rv = rawio_phy_read(rawio_disk_drive, phy_c, phy_h, phy_s/data_len+1, data_len, + data_buf1); + tries--; + if( rv ) fprintf(stderr, "Error in phy_read(%d,%d,%d,%d,%d,%d);\n", + rawio_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__) +rawio_phy_read(drive, cyl, head, sect, length, buffer) +{ +#asm + push bp + mov bp,sp + + push es + push ds + pop es + + mov dl,[bp+2+_rawio_phy_read.drive] + mov ch,[bp+2+_rawio_phy_read.cyl] + mov dh,[bp+2+_rawio_phy_read.head] + mov bx,[bp+2+_rawio_phy_read.buffer] + + mov ax,[bp+2+_rawio_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+_rawio_phy_read.sect] + and cl,#$3F + mov ax,[bp+2+_rawio_phy_read.cyl] ! Bits 8-9 of cylinder. + sar ax,#1 + sar ax,#1 + and al,#$C0 + or cl,al + + mov al,[bp+2+_rawio_phy_read.length] + mov ah,#$02 + int $13 + jc read_err + mov ax,#0 +read_err: + + pop es + pop bp +#endasm +} + +long +rawio_get_dpt(drive) +{ +#asm + push bp + mov bp,sp + + push di + push es + + mov dl,[bp+2+_rawio_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/libc/bios/rawio.h b/libc/bios/rawio.h new file mode 100644 index 0000000..3e378d7 --- /dev/null +++ b/libc/bios/rawio.h @@ -0,0 +1,16 @@ +#ifndef __readfs_h__ /* multi-inclusion protection */ +#define __readfs_h__ + +#ifdef __STDC__ +#define P(x) x +#else +#define P(x) () +#endif + +#define rawio_read_sector(__sect, __buffer) rawio_read_lsector((unsigned long)__sect, __buffer) +int rawio_read_lsector P((long sector, char* buffer)); + +extern int rawio_disk_cyls; +extern int rawio_disk_heads; +extern int rawio_disk_spt; +#endif diff --git a/libc/include/bios.h b/libc/include/bios.h new file mode 100644 index 0000000..4cfcd6a --- /dev/null +++ b/libc/include/bios.h @@ -0,0 +1,39 @@ + +#ifndef __BIOS_H +#define __BIOS_H +#include <features.h> + +union REGS +{ + struct { unsigned int ax, bx, cx, dx, si, di, cflag; } x; + struct { unsigned char al, ah, bl, bh, cl, ch, dl, dh; } h; +}; + +struct SREGS +{ + unsigned int es, cs, ss, ds; +}; + +unsigned int __get_cs __P((void)); +unsigned int __get_ds __P((void)); +unsigned int __get_es __P((void)); +void __set_es __P((unsigned int seg)); +int __peek_es __P((unsigned int off)); +int __deek_es __P((unsigned int off)); + +#define movedata __movedata + +#ifdef __LIBC__ + +extern int __nofiles(); +extern int (*__files)(); + +#define CMD_OPEN 0 +#define CMD_READ 1 +#define CMD_WRITE 2 +#define CMD_LSEEK 3 +#define CMD_CLOSE 4 + +#endif +#endif + diff --git a/libc/include/dos.h b/libc/include/dos.h index d67e27f..4ff9e6e 100644 --- a/libc/include/dos.h +++ b/libc/include/dos.h @@ -2,17 +2,7 @@ #ifndef __DOS_H #define __DOS_H #include <features.h> - -union REGS -{ - struct { unsigned int ax, bx, cx, dx, si, di, cflag; } x; - struct { unsigned char al, ah, bl, bh, cl, ch, dl, dh; } h; -}; - -struct SREGS -{ - unsigned int es, cs, ss, ds; -}; +#include <bios.h> #ifdef __MSDOS__ extern unsigned int __envseg; @@ -24,14 +14,5 @@ void __setvect __P((int i, long j)); long __getvect __P((int vecno)); #endif -unsigned int __get_cs __P((void)); -unsigned int __get_ds __P((void)); -unsigned int __get_es __P((void)); -void __set_es __P((unsigned int seg)); -int __peek_es __P((unsigned int off)); -int __deek_es __P((unsigned int off)); - -#define movedata __movedata - #endif diff --git a/libc/msdos/TODO b/libc/msdos/TODO index 7d3eb12..f2664a2 100644 --- a/libc/msdos/TODO +++ b/libc/msdos/TODO @@ -1 +1,3 @@ #define remove(x) unlink(x) + +See also the other files, many parts are incomplete. diff --git a/libc/msdos/msdos.c b/libc/msdos/msdos.c index 99e8835..77100ae 100644 --- a/libc/msdos/msdos.c +++ b/libc/msdos/msdos.c @@ -190,8 +190,12 @@ char ** __argv; for(i=0; i<length; i++) /* Copy it in. */ { ptr[i] = __peek_es(0x81+i); +/* Replaced because freedos adds \r to args. if( ptr[i] != ' ' && s == 0 ) { argc++; s=1; } if( ptr[i] == ' ' && s == 1 ) s=0; + */ + if( (ptr[i]&0xE0) != 0 && s == 0 ) { argc++; s=1; } + if( (ptr[i]&0xE0) == 0 && s == 1 ) s=0; } ptr[length]=0; diff --git a/libc/stdio2/printf.c b/libc/stdio2/printf.c index 45c4aa7..e41eca4 100644 --- a/libc/stdio2/printf.c +++ b/libc/stdio2/printf.c @@ -1,11 +1,15 @@ /* * This file based on printf.c from 'Dlibs' on the atari ST (RdeBath) * - * + * 19-OCT-88: Dale Schumacher + * > John Stanley has again been a great help in debugging, particularly + * > with the printf/scanf functions which are his creation. + * * Dale Schumacher 399 Beacon Ave. * (alias: Dalnefre') St. Paul, MN 55104 * dal@syntel.UUCP United States of America * "It's not reality that's important, but how you perceive things." + * */ /* Altered to use stdarg, made the core function vfprintf. diff --git a/libc/stdio2/scanf.c b/libc/stdio2/scanf.c index 2d61ab2..1e0f282 100644 --- a/libc/stdio2/scanf.c +++ b/libc/stdio2/scanf.c @@ -1,3 +1,17 @@ +/* + * This file based on scanf.c from 'Dlibs' on the atari ST (RdeBath) + * + * 19-OCT-88: Dale Schumacher + * > John Stanley has again been a great help in debugging, particularly + * > with the printf/scanf functions which are his creation. + * + * Dale Schumacher 399 Beacon Ave. + * (alias: Dalnefre') St. Paul, MN 55104 + * dal@syntel.UUCP United States of America + * "It's not reality that's important, but how you perceive things." + * + */ + #include <stdio.h> #include <ctype.h> #include <string.h> @@ -519,3 +533,4 @@ va_list ap; } #endif + diff --git a/libc/stdio2/stdio.c b/libc/stdio2/stdio.c index bc96100..c317859 100644 --- a/libc/stdio2/stdio.c +++ b/libc/stdio2/stdio.c @@ -130,11 +130,11 @@ FILE *fp; register int v; Inline_init; - v = fp->mode; - /* If last op was a read ... */ - if ((v & __MODE_READING) && fflush(fp)) + /* If last op was a read ... note fflush may change fp->mode and ret OK */ + if ((fp->mode & __MODE_READING) && fflush(fp)) return EOF; + v = fp->mode; /* Can't write if there's been an EOF or error then return EOF */ if ((v & (__MODE_WRITE | __MODE_EOF | __MODE_ERR)) != __MODE_WRITE) return EOF; @@ -304,7 +304,7 @@ FILE *f; register int ch; ret = s; - for (i = count; i > 0; i--) + for (i = count-1; i > 0; i--) { ch = getc(f); if (ch == EOF) @@ -456,11 +456,11 @@ FILE *fp; int len; unsigned bytes, put; - v = fp->mode; - /* If last op was a read ... */ - if ((v & __MODE_READING) && fflush(fp)) + /* If last op was a read ... note fflush may change fp->mode and ret OK */ + if ((fp->mode & __MODE_READING) && fflush(fp)) return 0; + v = fp->mode; /* Can't write or there's been an EOF or error then return 0 */ if ((v & (__MODE_WRITE | __MODE_EOF | __MODE_ERR)) != __MODE_WRITE) return 0; @@ -537,7 +537,6 @@ int ref; { #if 1 /* if __MODE_READING and no ungetc ever done can just move pointer */ - /* This needs testing! */ if ( (fp->mode &(__MODE_READING | __MODE_UNGOT)) == __MODE_READING && ( ref == SEEK_SET || ref == SEEK_CUR )) @@ -823,6 +822,7 @@ size_t size; { fp->bufstart = buf; fp->bufend = buf+size; + fp->mode &= ~__MODE_BUF; fp->mode |= mode; } } @@ -137,7 +137,8 @@ Address of the start of the current line. .TP .B ; ! Either of these marks the start of a comment. In addition any 'unexpected' -character at the start of a line is assumed to be a comment. +character at the start of a line is assumed to be a comment (but it's also +displayed to the terminal). .TP .B $ Prefix for hexadecimal numbers, the 'C' syntax, eg\ 0x1234, is also accepted. diff --git a/man/index.bt b/man/index.bt Binary files differindex 7f83633..e295941 100644 --- a/man/index.bt +++ b/man/index.bt diff --git a/tests/Makefile b/tests/Makefile index ceb884e..f2dc16b 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -4,7 +4,7 @@ BCC=bcc CC=$(BCC) -CFLAGS=-O -s +CFLAGS=-O SRC=env.c ft.c hd.c size.c sync.c compr.c ucomp.c ouch.c lines.c \ wc.c line2.c rand.c grab.c diff --git a/tests/xx b/tests/xx new file mode 100644 index 0000000..5451b81 --- /dev/null +++ b/tests/xx @@ -0,0 +1,27 @@ +# Reconstructed via infocmp from file: /etc/terminfo/x/xterm +xterm|xterm with color support, + am, km, mir, msgr, xenl, xon, + colors#8, cols#80, it#8, lines#65, ncv#3, pairs#64, + acsc=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~..--++\,\,II00, + bel=^G, bold=\E[1m, clear=\E[H\E[2J, cr=^M, + csr=\E[%i%p1%d;%p2%dr, cub=\E[%p1%dD, cub1=^H, + cud=\E[%p1%dB, cud1=^J, cuf=\E[%p1%dC, cuf1=\E[C, + cup=\E[%i%p1%d;%p2%dH, cuu=\E[%p1%dA, cuu1=\E[A, + dch=\E[%p1%dP, dch1=\E[P, dl=\E[%p1%dM, dl1=\E[M, ed=\E[J, + el=\E[K, enacs=\E(B\E)0, home=\E[H, ht=^I, ich=\E[%p1%d@, + ich1=\E[@, il=\E[%p1%dL, il1=\E[L, ind=^J, + is2=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l\E[4l, kbs=^H, + kcub1=\EOD, kcud1=\EOB, kcuf1=\EOC, kcuu1=\EOA, kend=\EOe, + kent=\EOM, kf1=\EOP, kf10=\E[21~, kf11=\E[23~, kf12=\E[24~, + kf2=\EOQ, kf3=\EOR, kf4=\EOS, kf5=\E[15~, kf6=\E[17~, + kf7=\E[18~, kf8=\E[19~, kf9=\E[20~, khome=\EO\200, + kich1=\E[2~, kmous=\E[M, knp=\E[6~, kpp=\E[5~, + op=\E[49;39m, rc=\E8, rev=\E[7m, ri=\EM, rmacs=^O, + rmam=\E[?7l, rmcup=\E[2J\E[?47l\E8, rmir=\E[4l, + rmkx=\E[?1l\E>, rmso=\E[m, rmul=\E[m, rs1=^O, + rs2=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l\E[4l\E<, + sc=\E7, setab=\E[4%p1%dm, setaf=\E[3%p1%dm, + setb=\E[%p1%{40}%+%dm, setf=\E[%p1%{30}%+%dm, + sgr0=\E[m, smacs=^N, smam=\E[?7h, smcup=\E7\E[?47h, + smir=\E[4h, smkx=\E[?1h\E=, smso=\E[7m, smul=\E[4m, + tbc=\E[3k, u6=\E[%i%d;%dR, u7=\E[6n, u8=\E[?1;2c, u9=\E[c, |