Category : Assembly Language Source Code
Archive   : PDISK.ZIP
Filename : RDPART.C

 
Output of file : RDPART.C contained in archive : PDISK.ZIP
#include "part.h"
#include
#include
#include
#include

BOOT *master_boot_rec, /* master boot record of currently selected disk */
*part_boot_rec[4]; /* boot record of each (active) logical partition */

static word start_mode, start_page;
byte changed_parms; /* if this byte is set, save_tbl (below) has
* a ptr to the original (BIOS or whatever)
* disk table, and must be reset.
*/
DISK_TABLE far *fd_tbl,
far *save_tbl;

byte num_disks,
fixed_disk,
_numsecs;
word _shprod;
extern word sector_size;
PARTDATA part_data[4];
extern int dotrans(dword relsect,word startsec,void *buf,word numsec,word op);

void
init() /* initialize tables from a given physical disk */
{
static byte _init = 0;
static word old_sector_size = 0;
struct diskinfo_t diskinfo;
int i;

/* if first time through, fill num_disks */
if(! _init) {
_init = 1;
diskinfo.drive = fixed_disk;
_bios_disk(8,&diskinfo);
if((num_disks = diskinfo.drive) == 0) {
fprintf(stderr,"No fixed disks attached.\n");
exit(1);
/* NOTREACHED */
}
if(num_disks==1 && fixed_disk==DISK1) {
fprintf(stderr,"Only one disk attached.\n");
exit(2);
/* NOTREACHED */
}
start_page = scr_gapage();
scr_sapage(0);
start_mode = scr_gmode();
switch(start_mode) {
case 0:
case 5:
case 6:
scr_smode(2);
break;
case 1:
case 4:
scr_smode(3);
break;
}
master_boot_rec = (BOOT *)malloc(sector_size);
for(i=0;i<4;i++)
part_boot_rec[i] = (BOOT *)malloc(sector_size);
}
else {
if(old_sector_size != sector_size) {
master_boot_rec = (BOOT *)realloc(master_boot_rec,sector_size);
for(i=0; i<4; i++)
part_boot_rec[i] = (BOOT *)realloc(part_boot_rec[i],sector_size);
}
if(changed_parms) {
/* we cast the table vector as a pointer to a far interrupt handler
* function returning void, since that is what _dos_setvect expects.
*/
_dos_setvect(changed_parms==DISK1 ? 0x46 : 0x41,
(void (interrupt far *)()) save_tbl
);
diskinfo.drive = changed_parms;
_bios_disk(0x09, &diskinfo); /* reset drive pair vector */
diskinfo.drive = changed_parms;
_bios_disk(0, &diskinfo); /* reset drive */
changed_parms = 0;
}
}

old_sector_size = sector_size;
fd_tbl = (DISK_TABLE far *) _dos_getvect(fixed_disk==DISK1 ? 0x46 : 0x41);
_numsecs = fd_tbl->fd_sec_per_track;
_shprod = _numsecs * fd_tbl->fd_heads;
boot_transfer(READ,0);
for(i=0; i<4; i++) {
if((part_data[i].sys_ind = master_boot_rec->ptable[i].sys_ind) != 0) {
part_data[i].s_cylinder=get_cyl(master_boot_rec->ptable[i].s_sec_cyl);
part_data[i].e_cylinder=get_cyl(master_boot_rec->ptable[i].e_sec_cyl);
boot_transfer(READ,i+1);
}
}
}

void
clean_quit()
{
struct diskinfo_t diskinfo;

if(changed_parms) {
_dos_setvect(changed_parms==DISK1 ? 0x46 : 0x41,
(void (interrupt far *)()) save_tbl
);
diskinfo.drive = changed_parms;
_bios_disk(0x09, &diskinfo); /* reset drive pair vector */
diskinfo.drive = changed_parms;
_bios_disk(0, &diskinfo); /* reset drive */
changed_parms = 0;
}
scr_sapage(start_page);
scr_smode(start_mode);
exit(0);
/* NOTREACHED */
}

int
make_fat(partno, fat_size, secs_in_rdir) /* make FAT (two copies) */
int partno,
fat_size;
word secs_in_rdir;
{
int i;
word *fatbuf, numsecs, offset, data_offset, secs_per_clus, secs_in_part;
byte *fatbuf2, *scratch;
BPB *bptr = &part_boot_rec[partno]->bpb;
dword relsec = master_boot_rec->ptable[partno].rel_sect;
extern word lineno;

numsecs = bptr->secs_in_fat;
data_offset = numsecs*2 + secs_in_rdir + bptr->res_sectors;
secs_in_part = bptr->nsectors;
secs_per_clus = (word) bptr->secs_per_au;
scratch = malloc(sector_size*secs_per_clus);
#ifdef DEBUG
printf("numsecs %d, offset %d, part_size %d\n",numsecs,data_offset,secs_in_part);
fflush(stdout);
#endif
if(!(fatbuf = (word *)calloc(numsecs,sector_size))) {
errno = ENOMEM;
return(0);
/* NOTREACHED */
}
fatbuf2 = (byte *)fatbuf;
if(fat_size == 12) {
fatbuf[0] = 0xfff8;
fatbuf[1] = 0x00ff;
}
else {
fatbuf[0] = 0xfff8;
fatbuf[1] = 0xffff;
}
/* get a list of sectors that can't be read -- presumably result of lo
* level formatting. Mark off appropriate cluster as bad.
*/
#ifndef DEBUG
scr_pos(lineno,42);
printf("Sector:");
for(offset=data_offset; offset <= secs_in_part; offset += secs_per_clus) {
word i;

i = (offset+secs_per_clus <= secs_in_part) ? secs_per_clus :
(secs_in_part-offset+1);
scr_pos(lineno,50);
printf("%u",offset-data_offset);
fflush(stdout);
if(dotrans(relsec,offset,scratch, i, READ)) {
/* got a bad sector */
word cnum = (offset - data_offset)/secs_per_clus + 2;

if(fat_size == 12) {
/* byte offset into cluster array is cnum*3/2 */
word *cptr = (word *)(fatbuf2 + ((cnum*3) >> 1));

*cptr |= (cnum & 1) ? 0xff70 : 0xff7;
}
else
fatbuf[cnum] = 0xfff7;
}
}
#endif
for(i=0; i<2; i++)
#ifndef DEBUG
if(dotrans(relsec,(i*numsecs)+1,fatbuf,numsecs,WRITE) < 0) {
errno = EINVAL;
return(0);
/* NOTREACHED */
}
#else
printf("Writing FAT, relsec 0x%lxL, whither 0x%x, count %d\n",
relsec,(i*numsecs)+1,numsecs);
fflush(stdout); (void) getch();
#endif
free(scratch);
free(fatbuf);
return(numsecs);
}

int
make_rdir(partno) /* make the root directory */
int partno;
{
int numsecs, offset;
word *buf, csize, temp;
BPB *bptr = &part_boot_rec[partno]->bpb;
dword relsec = master_boot_rec->ptable[partno].rel_sect;

offset = (bptr->secs_in_fat << 1) + 1;
numsecs = (bptr->nroot_ents+15)/16;
csize = (word) bptr->secs_per_au;
if((temp = numsecs % csize) != 0)
numsecs += csize-temp;
if((buf = (word *)calloc(numsecs,sector_size)) == NULL) {
errno = ENOMEM;
return(0);
/* NOTREACHED */
}
#ifndef DEBUG
if(dotrans(relsec,offset,buf,numsecs, WRITE) < 0) {
errno = EINVAL;
return(0);
/* NOTREACHED */
}
#else
printf("Writing directory, relsec (long) 0x%lx, whither 0x%x, count %d\n", relsec,offset,numsecs);
fflush(stdout); getch();
#endif
free(buf);
return(numsecs);
}

#ifdef BT_IN_C
void
boot_transfer(op, idx)
word op, /* either READ or WRITE */
idx; /* 0=master boot record, 1-5=partition */
{
union REGS fregs;
struct SREGS segreg;

if(idx) {
PARTITION *pptr;

pptr = & master_boot_rec->ptable[--idx];
fregs.x.bx = (unsigned) part_boot_rec[idx];
segreg.es = FP_SEG(part_boot_rec[idx]);
fregs.x.cx = pptr->s_sec_cyl; /* cylinder 0, sector 1 */
fregs.h.dh = pptr->s_head; /* head 0 */
}
else {
fregs.x.bx = (unsigned) master_boot_rec;
segreg.es = FP_SEG(master_boot_rec);
fregs.x.cx = 0x0001; /* cylinder 0, sector 1 */
fregs.h.dh = 0; /* head 0 */
}
fregs.h.ah = op; /* what to do */
fregs.h.al = 1; /* do 1 sector */
fregs.h.dl = fixed_disk;
int86x(0x13,&fregs,&fregs,&segreg);
}
#endif


  3 Responses to “Category : Assembly Language Source Code
Archive   : PDISK.ZIP
Filename : RDPART.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/