diff options
author | Robert de Bath <rdebath@poboxes.com> | 2000-10-07 15:35:09 +0200 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2013-10-23 23:46:41 +0200 |
commit | dfab97edd018b8904568bce77536037dd76b7507 (patch) | |
tree | fb45be914dda1e47c3d28eab6a4fc23a14c7b587 | |
parent | 65da95772de1633acd1bfcc7f579067bac3249af (diff) | |
download | dev86-dfab97edd018b8904568bce77536037dd76b7507.tar.gz |
Import Dev86src-0.15.3.tar.gzv0.15.3
-rw-r--r-- | Changes | 10 | ||||
-rw-r--r-- | Libc_version | 2 | ||||
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | as/as.c | 6 | ||||
-rw-r--r-- | as/assemble.c | 19 | ||||
-rw-r--r-- | as/error.c | 2 | ||||
-rw-r--r-- | as/globvar.h | 2 | ||||
-rw-r--r-- | as/mops.c | 11 | ||||
-rw-r--r-- | as/pops.c | 19 | ||||
-rw-r--r-- | as/readsrc.c | 4 | ||||
-rw-r--r-- | bcc/bcc.c | 2 | ||||
-rw-r--r-- | bootblocks/makeboot.c | 366 | ||||
-rw-r--r-- | bootblocks/mbr.s | 358 | ||||
-rw-r--r-- | bootblocks/msdos.s | 29 | ||||
-rw-r--r-- | bootblocks/sysboot.s | 3 | ||||
-rw-r--r-- | libc/Makefile | 2 | ||||
-rw-r--r-- | makefile.in | 4 | ||||
-rw-r--r-- | man/as86.1 | 21 |
18 files changed, 656 insertions, 206 deletions
@@ -1,3 +1,13 @@ +For version 0.16.0. + +> Seperated the multi-pass optimisation from the jump extension. We now have + the -j back to it's old meaning and -O added to help shorten instructions. + +> Fix for nested conditionals. + +> Fix for listing to unusual locations; assembler tried to list non-existant + lines. + For version 0.15.0. > Added support for archives to nm86/objdump86 and size86. diff --git a/Libc_version b/Libc_version index e815b86..1985d91 100644 --- a/Libc_version +++ b/Libc_version @@ -1 +1 @@ -0.15.1 +0.15.3 @@ -70,7 +70,7 @@ Uninstall: @# TO HERE distribution: - @[ `id -u` -eq 0 ] || fakeroot --nomixedlibhack -c $(MAKE) do_dist + @[ `id -u` -eq 0 ] || fakeroot -- $(MAKE) do_dist @[ `id -u` -ne 0 ] || $(MAKE) do_dist do_dist: @@ -221,7 +221,9 @@ char **argv; #ifdef I80386 case 'j': jumps_long = flag_state; - if( jumps_long ) ++last_pass; + break; + case 'O': + if( flag_state ) last_pass = 2; else last_pass = 1; break; #endif @@ -328,7 +330,7 @@ PRIVATE void usage() { as_abort( #ifdef I80386 -"usage: as [-03agjuw] [-b [bin]] [-lm [list]] [-n name] [-o obj] [-s sym] src"); +"usage: as [-03agjuwO] [-b [bin]] [-lm [list]] [-n name] [-o obj] [-s sym] src"); #else "usage: as [-guw] [-b [bin]] [-lm [list]] [-n name] [-o obj] [-s sym] src"); #endif diff --git a/as/assemble.c b/as/assemble.c index 2b92c76..062ec6d 100644 --- a/as/assemble.c +++ b/as/assemble.c @@ -9,7 +9,6 @@ #include "scan.h" PRIVATE bool_t nocolonlabel; /* set for labels not followed by ':' */ -PRIVATE offset_t oldlabel = 0; PRIVATE void (*routine) P((void)); PRIVATE pfv rout_table[] = { @@ -164,7 +163,7 @@ PUBLIC void assemble() if (nocolonlabel) error(NEEDENDLABEL); #endif - if( label->value_reg_or_op.value != oldlabel) + if(pass && label->value_reg_or_op.value != oldlabel) { dirty_pass = TRUE; if( pass == last_pass ) @@ -246,21 +245,7 @@ PRIVATE void asline() labelerror(RELAB); label = symptr; -#if 0 -if(pass==last_pass) -{ - if( ((label->data^lcdata)&~FORBIT) || label->value_reg_or_op.value != lc) - { - printf("Movement %x:%d -> %x:%d\n", - label->data, - label->value_reg_or_op.value, - lcdata, - lc); - } -} -#endif - /* This is a bit dodgy, I think it's ok but ... */ - if (pass && (label->data & RELBIT)) + if (pass /* && last_pass>1 */) { label->data = (label->data & FORBIT) | lcdata; label->value_reg_or_op.value = lc; @@ -84,7 +84,7 @@ PRIVATE char *errormessage[] = "illegal FP register pair", "junk after operands", "already defined", - "label moved in last pass, add -j?", + "label moved in last pass, add -O?", "instruction illegal for current cpu", "short branch would do", "unknown error", diff --git a/as/globvar.h b/as/globvar.h index d22f6a5..1ea385e 100644 --- a/as/globvar.h +++ b/as/globvar.h @@ -65,6 +65,8 @@ EXTERN unsigned char lcdata; /* shows how lc is bound */ /* FORBIT is set if lc is forward referenced */ /* RELBIT is is if lc is relocat. (not ASEG) */ EXTERN offset_t lcjump; /* lc jump between lines */ + +EXTERN offset_t oldlabel; /* Used for checking for moving labels */ #ifdef LOW_BYTE #define mcount (((unsigned char *) &lcjump)[LOW_BYTE]) /* low byte of lcjump */ @@ -1068,7 +1068,8 @@ int backamount; if (!(lastexp.data & (RELBIT | UNDBIT))) { lastexp.offset = lastexp.offset - lc - lcjump; - if (backamount != 0x0 && !(lastexp.data & IMPBIT) && + if ( last_pass<2 && backamount != 0x0 && + !(lastexp.data & IMPBIT) && lastexp.offset + backamount < 0x80 + backamount) error(SHORTB); /* -0x8? to 0x7F, warning */ } @@ -1206,7 +1207,8 @@ PUBLIC void mcall() else if (opcode == JMP_SHORT_OPCODE) { if (jumps_long && - (pass!=0 && !is8bitsignedoffset(lastexp.offset - lc - 2))) + ((pass!=0 && !is8bitsignedoffset(lastexp.offset - lc - 2)) || + (last_pass==1))) { opcode = JMP_OPCODE; lbranch(0x83); @@ -1945,7 +1947,8 @@ PUBLIC void mjcc() getea(&target); lastexp = target.displ; - if (pass!=0 && !is8bitsignedoffset(lastexp.offset - lc - 2)) + if ( (pass!=0 && !is8bitsignedoffset(lastexp.offset - lc - 2)) || + last_pass==1) { if (target.indcount >= 0x2 || target.base != NOREG) kgerror(REL_REQ); @@ -2749,7 +2752,7 @@ PUBLIC void mlong() if (!(lastexp.data & (RELBIT | UNDBIT))) { lastexp.offset = lastexp.offset - lc - lcjump; - if (!(lastexp.data & IMPBIT) && + if ( last_pass<2 && !(lastexp.data & IMPBIT) && lastexp.offset + 0x81 < 0x101) error(SHORTB); /* -0x81 to 0x7F, warning */ } @@ -175,6 +175,12 @@ pfv func; elseflag = FALSE; } } + else + { + /* Skip to EOL */ + while (sym != EOLSYM) + getsym(); + } } } @@ -213,6 +219,13 @@ unsigned char labits; labptr->data = lastexp.data; labptr->value_reg_or_op.value = lastexp.offset; showlabel(); + + if(pass && !(labits & VARBIT) && labptr->value_reg_or_op.value != oldlabel) + { + dirty_pass = TRUE; + if( pass == last_pass ) + error(UNSTABLE_LABEL); + } } /* common routine for ENTRY/EXPORT */ @@ -398,6 +411,12 @@ pfv func; elseflag = TRUE;/* but ELSE will change that */ } } + else + { + /* Skip to EOL */ + while (sym != EOLSYM) + getsym(); + } } } diff --git a/as/readsrc.c b/as/readsrc.c index 6cfbaf5..819efb8 100644 --- a/as/readsrc.c +++ b/as/readsrc.c @@ -15,7 +15,7 @@ /* * Ok, lots of hack & slash here. * 1) Added BIG buffer to load entire _primary_ file into memory. - * 2) This means primay file can be standard input. + * 2) This means the primary file can be standard input. * 3) Fixed so 'get/include' processing now works. * 4) Altered for a 'normal' style buffer otherwise (MINIBUF) * 5) Have the option of completely unbuffered if you need the last Kb. @@ -244,7 +244,7 @@ PUBLIC void pproceof() else if (pass!=last_pass) { pass++; - if( last_pass>2 && last_pass<30 && dirty_pass && pass==last_pass ) + if( last_pass>1 && last_pass<30 && dirty_pass && pass==last_pass ) last_pass++; if( pass==last_pass ) @@ -572,6 +572,8 @@ char **argv; addarg(&ldargs, DEFAULT_LIBDIR0); } + if (optimize) + addarg(&asargs, "-O"); addarg(&optargs, OPTIM_RULES); temp=optflags; optflags=stralloc2(optflags,",end"); free(temp); for(temp=strtok(optflags,","); temp; temp=strtok((char*)0,",")) diff --git a/bootblocks/makeboot.c b/bootblocks/makeboot.c index e45fa4a..77403c3 100644 --- a/bootblocks/makeboot.c +++ b/bootblocks/makeboot.c @@ -17,11 +17,11 @@ unsigned char buffer[1024]; #define FS_NONE 0 /* Bootsector is complete */ -#define FS_ADOS 1 /* Bootsector needs 'normal' DOS FS */ -#define FS_DOS 2 /* Bootsector needs any DOS FS */ +#define FS_DOS 1 /* Bootsector needs 'normal' DOS FS */ +#define FS_ADOS 2 /* Bootsector likes any DOS FS */ #define FS_TAR 3 /* Bootsector needs GNU-tar volume label */ -#define FS_STAT 4 /* DOS bootsector is checked */ -#define FS_ZERO 5 /* Boot sector must be Zapped */ +#define FS_STAT 4 /* Any bootsector is checked */ +#define FS_ZERO 5 /* Boot sector must be already Zapped */ #define FS_MBR 6 /* Boot sector is an MBR */ #ifndef __MSDOS__ @@ -40,29 +40,35 @@ struct bblist { } bblocks[] = { { "tar", "Bootable GNU tar volume lable", tarboot_data, tarboot_size, 0, 0, FS_TAR}, -{ "dosfs","Boot file BOOTFILE.SYS from dos floppy", +{ "dos12","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 filesystem", +{ "dos16","Boot file BOOTFILE.SYS from FAT16 hard disk or floppy", msdos16_data, msdos16_size, 1, msdos16_boot_name-msdos16_start, FS_DOS, 16}, -{ "none", "No OS bootblock, just message", +{ "none", "No OS bootblock, just display message", noboot_data, noboot_size, - 2, noboot_boot_message-noboot_start, FS_DOS}, + 2, noboot_boot_message-noboot_start, FS_ADOS}, { "skip", "Bypasses floppy boot with message", skip_data, skip_size, - 2, skip_mesg-skip_start, FS_DOS}, + 2, skip_mesg-skip_start, FS_ADOS}, { "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}, +#ifdef mbr_Banner +{ "mbr", "Master boot record for HD (with optional message)", + mbr_data,mbr_size, + 2, mbr_Banner-mbr_start, FS_MBR}, +#else { "mbr", "Master boot record for HD", mbr_data,mbr_size, 0, 0, FS_MBR}, +#endif { "stat", "Display dosfs superblock", 0, 0, 0, 0, FS_STAT}, -{ "copy", "Copy boot block to makeboot.sav", +{ "copy", "Copy boot block to makeboot.sav or named file", 0, 0, 0, 0, FS_STAT}, { "Zap", "Clear boot block to NULs", 0, 1024, 0, 0, FS_NONE}, @@ -121,9 +127,10 @@ char ** argv; switch(ptr->fstype) { case FS_NONE: /* override */ - break; - case FS_DOS: case FS_STAT: + case FS_ADOS: + break; + case FS_DOS: check_msdos(); if(ptr->fsmod) check_simpledos(ptr->fsmod); break; @@ -145,12 +152,14 @@ char ** argv; switch(ptr->fstype) { case FS_STAT: - print_super(buffer); if( strcmp(ptr->name, "copy") == 0 ) save_super(buffer); + else + print_super(buffer); close_disk(); exit(0); case FS_DOS: + case FS_ADOS: for(i=0; i<sysboot_dosfs_stat; i++) buffer[i] = ptr->data[i]; for(i=sysboot_codestart; i<512; i++) @@ -186,7 +195,7 @@ char ** argv; set_asciz(ptr->boot_name); break; default: - fprintf(stderr, "Cannot specify boot file for this block\n"); + fprintf(stderr, "Cannot specify boot name for this block\n"); exit(1); } @@ -212,11 +221,12 @@ Usage() progname = "makeboot"; #ifdef __MSDOS__ - fprintf(stderr, "Usage: %s [-f] bootblock[=bootname] a:\n", progname); + fprintf(stderr, "Usage: %s [-f] bootblock[=bootname] a:\n\n", progname); + fprintf(stderr, "The 'a:' can be any drive or file or @: for the MBR.\n"); #else - fprintf(stderr, "Usage: %s [-f] bootblock[=bootname] /dev/fd0\n", progname); + fprintf(stderr, "Usage: %s [-f] bootblock[=bootname] /dev/fd0\n\n", progname); #endif - fprintf(stderr, "\nThe bootname is a filename to use with the block,\n"); + fprintf(stderr, "The bootname is a filename or message 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); @@ -233,14 +243,22 @@ char * diskname; /* 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; } - if( strcmp("B:", diskname) == 0 ) { disktype = 2; return 0; } + if( diskname[2] == 0 && diskname[1] == ':' ) + { + if (isalpha(diskname[0])) { + disktype = toupper(diskname[0])-'A'+1; + return 0; + } + if (diskname[0] =='@') { + disktype = 129; + return 0; + } + } #endif disktype = 0; - diskfd = fopen(diskname, "r+"); - if( diskfd == 0 ) diskfd = fopen(diskname, "r"); + diskfd = fopen(diskname, "r+b"); + if( diskfd == 0 ) diskfd = fopen(diskname, "rb"); + if( diskfd == 0 && force ) diskfd = fopen(diskname, "w+b"); if( diskfd == 0 ) { fprintf(stderr, "Cannot open '%s'\n", diskname); @@ -262,7 +280,7 @@ int sectno; char * loadaddr; { #ifdef __MSDOS__ - if( disktype == 1 || disktype == 2 ) + if( disktype == 1 || disktype == 2 || disktype == 129 ) { int tries, rv; int s,h,c; @@ -271,11 +289,29 @@ char * loadaddr; c = sectno/disk_sect/disk_head; for(tries=0; tries<6; tries++) - if( (rv = dos_sect_write(disktype-1, c, h, s, loadaddr)) == 0 ) + if( (rv = bios_sect_write(disktype-1, c, h, s, loadaddr)) == 0 ) + break; + if( rv ) + { + if (rv/256 == 3) + fprintf(stderr, "Write protect error writing sector %d\n", sectno); + else + fprintf(stderr, "Error writing sector %d, (%d)\n", sectno, rv/256); + return -1; + } + return 0; + } + if( disktype ) + { + int tries, rv; + + for(tries=0; tries<6; tries++) + if( (rv = dos_sect_write(disktype-1, sectno, loadaddr)) == 0 ) break; if( rv ) { - fprintf(stderr, "Error writing sector %d, (%d)\n", sectno, rv/256); + fprintf(stderr, "Error writing sector %d, (0x%04d)\n", sectno, rv); + memset(loadaddr, '\0', 512); return -1; } return 0; @@ -303,7 +339,7 @@ char * loadaddr; { int cc; #ifdef __MSDOS__ - if( disktype == 1 || disktype == 2 ) + if( disktype == 1 || disktype == 2 || disktype == 129 ) { int tries, rv; int s,h,c; @@ -312,7 +348,7 @@ char * loadaddr; c = sectno/disk_sect/disk_head; for(tries=0; tries<6; tries++) - if( (rv = dos_sect_read(disktype-1, c, h, s, loadaddr)) == 0 ) + if( (rv = bios_sect_read(disktype-1, c, h, s, loadaddr)) == 0 ) break; if( rv ) { @@ -322,6 +358,21 @@ char * loadaddr; } return 0; } + if( disktype ) + { + int tries, rv; + + for(tries=0; tries<6; tries++) + if( (rv = dos_sect_read(disktype-1, sectno, loadaddr)) == 0 ) + break; + if( rv ) + { + fprintf(stderr, "Error reading sector %d, (0x%04d)\n", sectno, rv); + memset(loadaddr, '\0', 512); + return -1; + } + return 0; + } #endif if( disktype ) { @@ -337,10 +388,11 @@ char * loadaddr; } return 0; } + /**************************************************************************/ #ifdef __MSDOS__ -dos_sect_read(drv, track, head, sector, loadaddr) +bios_sect_read(drv, track, head, sector, loadaddr) { #asm push bp @@ -349,26 +401,24 @@ dos_sect_read(drv, track, head, sector, loadaddr) push ds pop es - mov dh,[bp+2+_dos_sect_read.head] - mov dl,[bp+2+_dos_sect_read.drv] - mov cl,[bp+2+_dos_sect_read.sector] - mov ch,[bp+2+_dos_sect_read.track] + mov dh,[bp+2+_bios_sect_read.head] + mov dl,[bp+2+_bios_sect_read.drv] + mov cl,[bp+2+_bios_sect_read.sector] + mov ch,[bp+2+_bios_sect_read.track] - mov bx,[bp+2+_dos_sect_read.loadaddr] + mov bx,[bp+2+_bios_sect_read.loadaddr] mov ax,#$0201 int $13 - jc read_err + jc bios_read_err mov ax,#0 -read_err: +bios_read_err: pop bp #endasm } -#endif -#ifdef __MSDOS__ -dos_sect_write(drv, track, head, sector, loadaddr) +bios_sect_write(drv, track, head, sector, loadaddr) { #asm push bp @@ -377,18 +427,18 @@ dos_sect_write(drv, track, head, sector, loadaddr) push ds pop es - mov dh,[bp+2+_dos_sect_write.head] - mov dl,[bp+2+_dos_sect_write.drv] - mov cl,[bp+2+_dos_sect_write.sector] - mov ch,[bp+2+_dos_sect_write.track] + mov dh,[bp+2+_bios_sect_write.head] + mov dl,[bp+2+_bios_sect_write.drv] + mov cl,[bp+2+_bios_sect_write.sector] + mov ch,[bp+2+_bios_sect_write.track] - mov bx,[bp+2+_dos_sect_write.loadaddr] + mov bx,[bp+2+_bios_sect_write.loadaddr] mov ax,#$0301 int $13 - jc write_err + jc bios_write_err mov ax,#0 -write_err: +bios_write_err: pop bp #endasm @@ -397,6 +447,112 @@ write_err: /**************************************************************************/ +#ifdef __MSDOS__ + +/* All this mess just to read one sector!! */ + +struct disk_packet { + long sector; + int count; + long addr; +} disk_packet; + +dos_sect_read(drv, sector, loadaddr) +{ +#asm + push bp + mov bp,sp + + mov al,[bp+2+_dos_sect_read.drv] + mov cx,#1 + mov dx,[bp+2+_dos_sect_read.sector] + mov bx,[bp+2+_dos_sect_read.loadaddr] + + int $25 + pop bx + jnc dos_read_ok + + mov bp,sp + + ! Fill the disk packet + mov ax,[bp+2+_dos_sect_read.sector] + mov [_disk_packet],ax + xor ax,ax + mov [_disk_packet+2],ax + inc ax + mov [_disk_packet+4],ax + mov ax,[bp+2+_dos_sect_read.loadaddr] + mov [_disk_packet+6],ax + mov ax,ds + mov [_disk_packet+8],ax + + mov dl,[bp+2+_dos_sect_read.drv] + inc dl + mov bx,#_disk_packet + mov cx,#0xFFFF + mov si,#0 + mov ax,#0x7305 + + int $21 + + jc dos_read_err +dos_read_ok: + mov ax,#0 +dos_read_err: + + pop bp +#endasm +} + +dos_sect_write(drv, sector, loadaddr) +{ +#asm + push bp + mov bp,sp + + mov al,[bp+2+_dos_sect_write.drv] + mov cx,#1 + mov dx,[bp+2+_dos_sect_write.sector] + mov bx,[bp+2+_dos_sect_write.loadaddr] + + int $26 + pop bx + jnc dos_write_ok + + mov bp,sp + + ! Fill the disk packet + mov ax,[bp+2+_dos_sect_write.sector] + mov [_disk_packet],ax + xor ax,ax + mov [_disk_packet+2],ax + inc ax + mov [_disk_packet+4],ax + mov ax,[bp+2+_dos_sect_write.loadaddr] + mov [_disk_packet+6],ax + mov ax,ds + mov [_disk_packet+8],ax + + mov dl,[bp+2+_dos_sect_write.drv] + inc dl + mov bx,#_disk_packet + mov cx,#0xFFFF + mov si,#1 + mov ax,#0x7305 + + int $21 + + jc dos_write_err +dos_write_ok: + mov ax,#0 +dos_write_err: + + pop bp +#endasm +} +#endif +/**************************************************************************/ + check_zapped() { int i; @@ -551,12 +707,21 @@ copy_tarblock() #define DOS_SPT 9 #define DOS_HEADS 10 #define DOS_HIDDEN 11 + #define DOS4_MAXSECT 12 #define DOS4_PHY_DRIVE 13 #define DOS4_SERIAL 14 #define DOS4_LABEL 15 #define DOS4_FATTYPE 16 +#define DOS7_MAXSECT 17 +#define DOS7_FAT32LEN 18 +#define DOS7_FLAGS 19 +#define DOS7_VERSION 20 +#define DOS7_ROOT_CLUST 21 +#define DOS7_INFO_SECT 22 +#define DOS7_BOOT2 23 + struct bootfields { int offset; int length; @@ -577,11 +742,21 @@ struct bootfields { { 0x18, 2, 0}, { 0x1A, 2, 0}, { 0x1C, 4, 0}, - { 0x20, 4, 0}, + + { 0x20, 4, 0}, /* DOS4+ */ { 0x24, 1, 0}, { 0x27, 4, 0}, { 0x2B, 11, 0}, { 0x36, 8, 0}, + + { 0x20, 4, 0}, /* DOS7 FAT32 */ + { 0x24, 4, 0}, + { 0x28, 2, 0}, + { 0x2A, 2, 0}, + { 0x2C, 4, 0}, + { 0x30, 2, 0}, + { 0x32, 2, 0}, + { -1,0,0} }; @@ -595,24 +770,39 @@ static char * fieldnames[] = { "Reserved sectors", "FAT count", "Root dir entries", - "Sector count (=0 if large FS)", + "Sector count", "Media code", "FAT length", "Sect/Track", "Heads", "Hidden sectors (Partition offset)", + "Large FS sector count", "Phys drive", "Serial number", "Disk Label (DOS 4+)", "FAT type", + + "FAT32 FS sector count", + "FAT32 FAT length", + "FAT32 Flags", + "FAT32 version", + "FAT32 Root Cluster", + "FAT32 Info Sector", + "FAT32 Backup Boot", + 0 }; int i; + long numclust = 0xFFFF; + int fatbits = 0; + int fat_len = -1; for(i=0; dosflds[i].offset >= 0; i++) { - printf("%-35s", fieldnames[i]); + if( i>= DOS4_MAXSECT && (fat_len==0) != (i>=DOS7_MAXSECT) ) + continue; + if( dosflds[i].length <= 4 ) { long v = 0; int j; @@ -620,11 +810,23 @@ static char * fieldnames[] = { { v = v*256 + (0xFF&( bootsect[dosflds[i].offset+j] )); } - printf("%ld\n", v); + + if( i==DOS_FATLEN ) + fat_len = v; + + if (v==0 && + (i==DOS_FATLEN || i==DOS_MAXSECT || i==DOS4_MAXSECT || i==DOS_NROOT)) + continue; + + printf("%-35s%ld\n", fieldnames[i], v); + + if (i==DOS_SECT && v!=512 && v!=1024 && v!=2048) + break; } else { int ch, j; + printf("%-35s", fieldnames[i]); for(j=0; j<dosflds[i].length; j++) { ch = bootsect[dosflds[i].offset+j]; @@ -643,6 +845,13 @@ char * bootsect; for(i=0; dosflds[i].offset >= 0; i++) { + if( i>= DOS4_MAXSECT && + (dosflds[DOS_FATLEN].value==0) != (i>=DOS7_MAXSECT) ) + { + dosflds[i].lvalue = dosflds[i].value = 0; + continue; + } + if( dosflds[i].length <= 4 ) { long v = 0; int j; @@ -654,7 +863,7 @@ char * bootsect; dosflds[i].lvalue = v; } else - dosflds[i].value = 0; + dosflds[i].lvalue = dosflds[i].value = 0; } } @@ -680,7 +889,10 @@ check_msdos() dosflds[DOS_CLUST].value = 1; if( dosflds[DOS_MEDIA].value < 0xF0 ) - fprintf(stderr, "Dos media descriptor is invalid\n"); + { + if (!force) + fprintf(stderr, "Dos media descriptor is invalid\n"); + } else if( dosflds[DOS_MEDIA].value != (0xFF&buffer[512]) && dosflds[DOS_RESV].value == 1 ) fprintf(stderr, "Dos media descriptor check failed\n"); @@ -728,7 +940,7 @@ check_msdos() check_simpledos(bb_fatbits) int bb_fatbits; { - unsigned numclust = 0xFFFF; + long numclust = 0xFFFF; char * err = 0; int fatbits = 0; @@ -739,19 +951,24 @@ int bb_fatbits; - dosflds[DOS_NFAT].value * dosflds[DOS_FATLEN].value - ((dosflds[DOS_NROOT].value+15)/16) ) / dosflds[DOS_CLUST].value + 2; - else + else if( dosflds[DOS4_MAXSECT].value > 0 ) 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; + else + numclust = ( dosflds[DOS7_MAXSECT].lvalue + - dosflds[DOS_RESV].value + - dosflds[DOS_NFAT].value * dosflds[DOS7_FAT32LEN].value + ) / dosflds[DOS_CLUST].value; 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); + fatbits=12+4*(numclust > 0xFF0) + 16*(numclust > 0xFFF0L); if( dosflds[DOS_NFAT].value > 2 ) err = "Too many fat copies on disk"; @@ -759,15 +976,19 @@ int bb_fatbits; 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( fatbits == 16 && numclust < 0xFF0 ) + err = "Weirdness, FAT16 but less than $FF0 clusters"; 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"; + err = "Boot sector untested with more than 65535 tracks"; if( !err && bb_fatbits == 12 ) { - if( (0x7C00-msdos_start-512)/512 < dosflds[DOS_FATLEN].value ) + if( dosflds[DOS4_PHY_DRIVE].value != 0 ) + err = "This boot sector is only for floppies"; + else 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 ) @@ -819,7 +1040,7 @@ int boot_name; if( strlen(boot_id) > i ) { - fprintf(stderr, "Filename '%s' is too long for bootblock\n"); + fprintf(stderr, "Name '%s' is too long for bootblock\n"); exit(1); } else @@ -840,6 +1061,10 @@ int boot_name; default: buffer[j++] = boot_id[i]; break; } } +#ifdef __MSDOS__ + else if(boot_id[i] == '_') buffer[j++] = ' '; + else if(boot_id[i] == '^') { buffer[j++] = '\r'; buffer[j++] = '\n'; } +#endif else buffer[j++] = boot_id[i]; } buffer[j] = 0; @@ -857,28 +1082,37 @@ check_mbr() if( buffer[i] ) break; + /* Check for Disk Manager partition tables */ + if( buffer[252] == 0xAA && buffer[253] == 0x55 ) + { + if( (unsigned char)mbr_data[252] != 0xAA || mbr_data[253] != 0x55 ) + i = 252; + } + if( i != 512 ) { if(force) - fprintf(stderr, "That doesn't look like an MBR zapping\n"); + fprintf(stderr, "That doesn't look like a compatible MBR but ...\n"); else { - fprintf(stderr, "That doesn't look like an MBR, -f will zap\n"); + fprintf(stderr, "That doesn't look like a compatible MBR\n"); exit(1); } - - memset(buffer, '\0', 512); } } copy_mbr(mbr_data) char * mbr_data; { - if( buffer[252] != 0xAA || buffer[253] != 0x55 ) + if( buffer[252] != 0xAA || buffer[253] != 0x55 || + (unsigned char)mbr_data[252] != 0xAA || mbr_data[253] != 0x55 ) memcpy(buffer, mbr_data, 446); else memcpy(buffer, mbr_data, 254); - memcpy(buffer+510, mbr_data+510, 2); + + buffer[510] = 0x55; + buffer[511] = 0xAA; + write_zero = 1; } /**************************************************************************/ @@ -1142,7 +1376,7 @@ do_2m_write() #ifdef HAS_2M20 else if( disk_trck != 82 || disk_sect != 22 ) { - fprintf(stderr, "To be bootable a 2M disk must be 22 sectors 82 tracks or formatted with 2m20.\n"); + fprintf(stderr, "To be bootable a 2M disk must be 22 sectors 82 tracks or formatted with DOS 2m.\n"); if( !force ) exit(1); fprintf(stderr, "But I'll try it\n"); } @@ -1166,7 +1400,7 @@ do_2m_write() write_sector(bs_offset+i/512+1, program_2m_vsn_20+i); } #else - fprintf(stderr, "To be bootable a 2M disk must be formatted with the 2m20 device driver.\n"); + fprintf(stderr, "To be bootable a 2M disk must be formatted with the DOS 2m driver.\n"); exit(1); #endif } diff --git a/bootblocks/mbr.s b/bootblocks/mbr.s index 3a22984..113bb51 100644 --- a/bootblocks/mbr.s +++ b/bootblocks/mbr.s @@ -3,37 +3,38 @@ ! This BB successfully boots MSDOS or Linux. ! ! In addition it has the facility to load and execute a small program -! (of 8 extents) before the boot blocks are checked. +! before the boot blocks are checked. ! ! Or ! -! Space for 12 extra partitions in a form that Linux _does_ understand. +! Space for 12 extra partitions in the 'DiskManager' form that Linux +! _does_ understand. ! +! NB: This needs Dev86 0.15.2 or later ! Lowest available is $0500, MSDOS appears to use $0600 ... I wonder why? ORGADDR=$0500 preboot=0 ! Include the pre-boot loader. -diskman=1 ! Disk manager partitions, allows 16 partitions but +mbrkey=0 ! Option to choose the boot record base on keystroke +message=0 ! Display boot message +diskman=0 ! Disk manager partitions, allows 16 partitions but ! don't overwrite this with a LILO BB. -! Include standard layout -org ORGADDR -include sysboot.s - -public partition_1 -public partition_2 -public partition_3 -public partition_4 +linear=0 ! Use the linear addresses not the CHS ones - if diskman=0 -org ORGADDR+$3 -.ascii "ELKS MBR Copyright 1996, Robert de Bath" +partition_start=ORGADDR+0x1BE +partition_size=0x10 +partition_end=ORGADDR+0x1FE -! Start after dos fsstat data, not strictly required. -org codestart + if diskman + ! Partition table start ... + table_start=ORGADDR+0xFC + low_partition=table_start+2 else -org ORGADDR + table_start=partition_start endif + +org ORGADDR cli ! Assume _nothing_! cld mov bx,#$7C00 ! Pointer to start of BB. @@ -51,52 +52,38 @@ org ORGADDR cont: sti ! Let the interrupts back in. -! -! Next check for a pre-boot load. - +! Next check for a pre-boot load or a keypress + if message + call disp_message + endif if preboot - push bx - mov si,#pre_boot_table - lodsw - mov di,ax ! First word is execute address -more_boot: - lodsw - test ax,ax - jz load_done - mov bx,ax ! word 1 address - lodsw - mov cx,ax ! word 2 CX, head/sector - lodsw - mov dx,ax ! word 3 DX, drive, cylinder - lodsw ! word 4 AX, $02, sector count - int $13 - jnc more_boot ! This doesn't retry, with a HD it shouldn't be bad. - jc disk_error -load_done: - call di -exec_done: - pop bx + call preboot_code + endif + if mbrkey + call key_wait endif ! Now check the partition table, must use SI as pointer cause that's what the ! partition boot blocks expect. - mov si,#partition_1 + mov si,#partition_start check_active: cmp byte [si],#$80 ! Flag for activated partition jz found_active + if mbrkey=0 bad_boot: - add si,#partition_2-partition_1 - cmp si,#bootblock_magic + endif + add si,#partition_size + cmp si,#partition_end jnz check_active - ! Check for Disk manager partitions (12 more!) + ! Check for Disk manager partitions in the order that Linux numbers them. if diskman cmp word ptr diskman_magic,#$55AA jnz no_diskman - mov si,#partition_1 + mov si,#partition_start check_next: - sub si,#partition_2-partition_1 + sub si,#partition_size cmp byte [si],#$80 ! Flag for activated partition jz found_active cmp si,#low_partition @@ -109,10 +96,14 @@ no_diskman: jmp no_boot found_active: + if linear + call linearise + else mov di,#6 ! Max retries, int list says 3 ... double it mov dx,[si] ! dh = Drive head, dl = $80 ie HD drive 0 mov cx,[si+2] ! cx = Sector & head encoded for int $13 - ! bx is correct + ! bx is correct at $7C00 + endif retry: movb [$7DFE],#0 ! Clear magic for dosemu mov ax,#$0201 ! Read 1 sector @@ -126,9 +117,8 @@ retry: dec di jnz retry ! Try again -disk_error: mov si,#disk_read_error - jmp no_boot ! Sorry it ain't gonna work. + jmp no_boot ! Sorry it ain't gonna work. sector_loaded: mov di,#$7DFE ! End of sector loaded @@ -139,6 +129,19 @@ sector_loaded: jmpi #$7C00,#0 ! Go! ! Fatal errors ........... + if mbrkey +bad_boot: + mov si,#no_bootpart +no_boot: ! SI now has pointer to error message + call puts + mov si,#crlf + call puts +tick: + call key_wait + j tick + + else + no_boot: ! SI now has pointer to error message lodsb cmp al,#0 @@ -156,65 +159,242 @@ EOS: keyboot: ! Wait for a key then reboot xor ax,ax int $16 - int $19 ! This should be OK as we haven't touched anything. +! int $19 ! This rarely does anything useful... jmpi $0,$FFFF ! Wam! Try or die! -no_bootpart: - .asciz "No bootable partition" -disk_read_error: - .asciz "Error loading system" press_key: - .asciz "\r\nPress a key to reboot" + .asciz "\r\nPress return:" press_end: + endif + +no_bootpart: + .asciz "No active partition" +disk_read_error: + .asciz "Disk read error" + +!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +! Instead of loading using the CHS data in the ptbl use the linear addr +! + if linear +linearise: + mov di,#6 ! Max retries, int list says 3 ... double it + mov dx,[si] ! dh = Drive head, dl = $80 ie HD drive 0 + mov cx,[si+2] ! cx = Sector & head encoded for int $13 + ! bx is correct at $7C00 + + fail! Todo ... + ret + endif + +!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +! Choose the partition based on a pressed key ... + + if mbrkey +key_wait: + mov si,#Prompt + call puts + mov di,#19 ! Wait for 18-19 ticks + +next_loop: + mov ah,#1 + int $16 + jnz Got_key + mov ah,#0 + int $1A ! Get current tick + cmp dx,si ! If changed DEC our counter. + jz next_loop + mov si,dx + dec di + jnz next_loop + + mov si,#Unprompt ! Nothing has happened, return. + call puts + +bad_key: + ret + +Got_key: + cmp al,#$20 + jnz not_space + mov si,#Pause + j showit +not_space: + mov Showkey,al + mov si,#Showkey +showit: + call puts + + mov ah,#0 ! Clean the kbd buffer. + int $16 + + ! ... Now we use our key ... + ! 0 => Floppy + ! 1 .. 4 => Hard disk partition. + + mov di,#-1 + cmp al,#$20 + jz next_loop + and ax,#0xF + + jnz not_floppy + mov si,#floppy_part + br found_active + +not_floppy: + dec ax + test ax,#0xC + jnz bad_key + + mov cl,#4 + shl ax,cl + add ax,#partition_start + mov si,ax + +! Set active flag for disk interrupt. + or byte [si],#$80 + + br found_active + +puts: + lodsb + cmp al,#0 + jz EOS + push bx + mov bx,#7 + mov ah,#$E ! Can't use $13 cause that's AT+ only! + int $10 + pop bx + jmp puts +EOS: + ret + +Prompt: + .asciz "MBR: " +Unprompt: + .asciz "\b\b\b\b\b \b\b\b\b\b" +Pause: + .asciz "\b\b> " +Showkey: + .ascii " " +crlf: + .asciz "\r\n" +floppy_part: + .word 0,1 + + endif + +!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +! + if message +disp_message: + mov si,#Banner + + if mbrkey + br puts + else + +puts: + lodsb + cmp al,#0 + jz .EOS + push bx + mov bx,#7 + mov ah,#$E ! Can't use $13 cause that's AT+ only! + int $10 + pop bx + jmp puts +.EOS: + ret + endif +export Banner +Banner: + .asciz "" + endif +!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +! This is the pre-boot loader it uses CHS but that's ok for track 0 +! if preboot +public preboot_code +preboot_code: + push bx + mov si,#pre_boot_table + lodsw + mov di,ax ! First word is execute address +more_boot: + lodsw + test ah,ah + jz load_done + mov bx,ax ! word 1 address + lodsw + mov cx,ax ! word 2 CX, head/sector + lodsw + mov dx,ax ! word 3 DX, drive, cylinder + lodsw ! word 4 AX, $02, sector count + int $13 + jnc more_boot ! This doesn't retry, with a HD it shouldn't be bad. + + mov si,#disk_read_error + br no_boot ! Sorry it ain't gonna work. +load_done: + call di +exec_done: + pop bx + return: ret export pre_boot_table pre_boot_table: + ! Example: Do nothing. + .word return,0 + + ! Labels + ! .word <execute address> + ! Then repeat .. + ! .word <BX>, <CX>, <DX>, <AX> + ! Finally + ! .word 0 + ! Example: Load rest of H0,C0 into mem at $7C00 (8k). - ! .word $7C00, $7C00,$0002,$0000,$0210, $0000 - .word return - .word 0 + ! .word $7C00, $7C00,$0002,$8000,$0210, $0000 + + ! Example: Use single LBA call + ! .word <execute address> + ! .word 0,0,$8000,$4200, $0010 + ! .word <number of blocks> + ! .long <transfer buffer> + ! .long <start block number> + ! .long <start block number high 4 bytes> endif - if diskman +!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +! Now make sure this isn't too big! + if *>table_start + fail! Partition table overlaps + endif +!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +! The diskman magic number and empty DM partitions. + if diskman org ORGADDR+0xFC public diskman_magic diskman_magic: .word 0xAA55 -low_partition: -public partition_16 -partition_16 = low_partition+0x00 -public partition_15 -partition_15 = low_partition+0x10 -public partition_14 -partition_14 = low_partition+0x20 -public partition_13 -partition_13 = low_partition+0x30 -public partition_12 -partition_12 = low_partition+0x40 -public partition_11 -partition_11 = low_partition+0x50 -public partition_10 -partition_10 = low_partition+0x60 -public partition_9 -partition_9 = low_partition+0x70 -public partition_8 -partition_8 = low_partition+0x80 -public partition_7 -partition_7 = low_partition+0x90 -public partition_6 -partition_6 = low_partition+0xA0 -public partition_5 -partition_5 = low_partition+0xB0 + .blkb 12*partition_size-1 + .byte 0 + endif + +!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +! And finally a copyright message if there's room. + if *<ORGADDR+0x180 + org ORGADDR+0x180 +.asciz "ELKS MBR " +.asciz "Robert de Bath," +.asciz "Copyright 1996-2000." + org partition_start-1 + .byte 0xFF endif -! Now make sure this isn't to big! - if *>partition_1 - fail! Partition overlap - endif !THE END diff --git a/bootblocks/msdos.s b/bootblocks/msdos.s index f291b6b..b9f02a9 100644 --- a/bootblocks/msdos.s +++ b/bootblocks/msdos.s @@ -19,10 +19,9 @@ ! ! All these are true for mtools created floppies on normal PC drives. ! -! In addition this now has a compile time option for 16 bit FAT floppies -! TODO: Hard partition (dos_hidden != 0) -! Zip disks (floppy with dos_hidden != 0) -! Auto detect disk type +! In addition this now has a compile time option for FAT16 partitions. +! TODO: Auto detect disk type +! FAT32 ! !--------------------------------------------------------------------------- ORGADDR=$0500 @@ -37,6 +36,13 @@ fatbits=12 ! Set to 12 or 16 (16 for LS-120 disks) export heads heads=0 ! This can be 0,1 or 2. 0 is dynamic. +export harddisk + if fatbits=12 +harddisk=0 + else +harddisk=1 ! Allow for hard disks, but will only work with + endif ! disks formatted >= MSDOS 4.0 + !--------------------------------------------------------------------------- ! Absolute position macro, fails if code before it is too big. macro locn @@ -185,6 +191,9 @@ linsect2: and al,#$C0 or cl,al endif + if harddisk + mov dl,[dos4_phy_drive] + endif ret !--------------------------------------------------------------------------- @@ -332,13 +341,18 @@ got_fsect: !--------------------------------------------------------------------------- ! File is now loaded, execute it. maincode: + if harddisk=0 mov bx,#7 mov ax,#$0E3E int $10 ! Marker printed to say bootblock succeeded. + endif xor dx,dx ! DX=0 => floppy drive + if harddisk + mov dl,[dos4_phy_drive] + endif push dx ! CX=0 => partition offset = 0 - mov si,[dos_spt] ! SI=Sectors pet track + mov si,[dos_spt] ! SI=Sectors per track mov bx,#LOADSEG mov ds,bx ! DS = loadaddress @@ -390,12 +404,9 @@ boot_name: name_end: ! NNNNNNNNEEE -if fatbits =16 locn(510) - .word 0 ! This is a floppy so it should not need the magic _but_ + .word $AA55 ! 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 if 12 bit. diff --git a/bootblocks/sysboot.s b/bootblocks/sysboot.s index 558d02e..baac806 100644 --- a/bootblocks/sysboot.s +++ b/bootblocks/sysboot.s @@ -35,12 +35,13 @@ dos_heads: .blkw 1 ! Heads dos_hidden: .blkw 2 ! Hidden sectors ! Here down is DOS 4+ and probably not needed for floppy boots. -floppy_temp: dos4_maxsect: .blkw 2 ! Large FS sector count dos4_phy_drive: .blkb 1 ! Phys drive .blkb 1 ! Reserved .blkb 1 ! DOS 4 + +floppy_temp: dos4_serial: .blkw 2 ! Serial number dos4_label: .blkb 11 ! Disk Label (DOS 4+) dos4_fattype: .blkb 8 ! FAT type diff --git a/libc/Makefile b/libc/Makefile index d7a451c..2e3406f 100644 --- a/libc/Makefile +++ b/libc/Makefile @@ -11,7 +11,7 @@ endif VERMAJOR=0 VERMINOR=15 -VERPATCH=1 +VERPATCH=3 VER=$(VERMAJOR).$(VERMINOR).$(VERPATCH) CC=bcc diff --git a/makefile.in b/makefile.in index f53e6ef..19828a2 100644 --- a/makefile.in +++ b/makefile.in @@ -39,12 +39,8 @@ WALL =-Wtraditional -Wshadow -Wid-clash-14 -Wpointer-arith \ WALL =-Wstrict-prototypes CC =gcc -#ifdef __i386__ -CFLAGS =$(GCCFLAG) -Wall $(WALL) -O2 -m486 -g -#else CFLAGS =$(GCCFLAG) -Wall $(WALL) -O6 -g #endif -#endif #ifndef GNUMAKE MAKEC=sh makec @@ -83,17 +83,22 @@ a valid instruction) only put global symbols in object or symbol file .TP .B -j -replace short jumps that don't reach with 5 byte sequences, this causes the -assembler to add an extra pass to try to determine if the long jump is -really needed. If you add a second -.B -j -the assembler will keep adding passes until the labels all stabilise (to -a maximum of 30 passes) -Don't use this with hand written assembler use the explicit +replace all short jumps with similar 16 or 32 bit jumps, the 16 bit +conditional branches are encoded as a short conditional and a long +unconditional branch. +.TP +.B -O +this causes the assembler to add extra passes to try to use forward +references to reduce the bytes needed for some instructions. +If the labels move on the last pass the assembler will keep adding passes +until the labels all stabilise (to a maximum of 30 passes) +It's probably not a good idea to use this with hand written assembler +use the explicit .B br\ bmi\ bcc style opcodes for 8086 code or the .B jmp\ near -style for conditional i386 instructions. +style for conditional i386 instructions and make sure all variables are +defined before they are used. .TP .B -l produce list file, filename may follow |