📄 dsk.c
字号:
}
COUNT
blk_driver (rqptr rp)
{
if(rp -> r_unit >= nUnits && rp-> r_command != C_INIT)
return failure(E_UNIT);
if(rp -> r_command > NENTRY)
{
return failure(E_FAILURE); /* general failure */
}
else
return ((*dispatch[rp -> r_command])(rp));
}
static WORD
init (rqptr rp)
{
COUNT HardDrive, Unit;
/* Reset the drives */
fl_reset();
/* Initial number of disk units */
nUnits = 2;
/* Initial number of DOS partitions */
nPartitions = 0;
/* Setup media info and BPBs arrays */
for (Unit = 0; Unit < NDEV; Unit++)
{
miarray[Unit].mi_size = 720l;
miarray[Unit].mi_heads = 2;
miarray[Unit].mi_cyls = 40;
miarray[Unit].mi_sectors = 9;
miarray[Unit].mi_offset = 0l;
miarray[Unit].mi_drive = Unit;
bpbarray[Unit].bpb_nbyte = SEC_SIZE;
bpbarray[Unit].bpb_nsector = 2;
bpbarray[Unit].bpb_nreserved = 1;
bpbarray[Unit].bpb_nfat = 2;
bpbarray[Unit].bpb_ndirent = 112;
bpbarray[Unit].bpb_nsize = 720l;
bpbarray[Unit].bpb_mdesc = 0xfd;
bpbarray[Unit].bpb_nfsect = 2;
bpbptrs[Unit] = &bpbarray[Unit];
};
for(HardDrive = 0; HardDrive <= 0; HardDrive++) /* only one hard drive for now */
{
/* Process primary partition table */
if (!processtable ((HardDrive | 0x80), 0, 0l, 1, 0l))
/* Exit if no hard drive */
break;
};
rp -> r_nunits = nUnits;
rp -> r_bpbptr = bpbptrs;
rp -> r_endaddr = device_end();
return S_DONE;
}
static WORD
mediachk (rqptr rp)
{
if(hd(miarray[rp -> r_unit].mi_drive))
rp -> r_mcretcode = M_NOT_CHANGED;
else
rp -> r_mcretcode = tdelay((LONG)37) ? M_DONT_KNOW : M_NOT_CHANGED;
return S_DONE;
}
static WORD
bldbpb (rqptr rp)
{
REG retry = N_RETRY;
ULONG count;
byteptr trans;
WORD local_word;
if(hd(miarray[rp -> r_unit].mi_drive))
{
COUNT partidx = miarray[rp -> r_unit].mi_partidx;
head = dos_partition[partidx].peBeginHead;
sector = dos_partition[partidx].peBeginSector;
track = dos_partition[partidx].peBeginCylinder;
}
else
{
head = 0;
sector = 1;
track = 0;
}
do
{
ret = fl_read((WORD)miarray[rp -> r_unit].mi_drive,
(WORD)head, (WORD)track, (WORD)sector, (WORD)1, (byteptr)&buffer);
} while (ret != 0 && --retry > 0);
if(ret != 0)
return(dskerr(ret));
getword(&((((BYTE *)&buffer.bytes[BT_BPB]))[BPB_NBYTE]), &bpbarray[rp -> r_unit].bpb_nbyte);
getbyte(&((((BYTE *)&buffer.bytes[BT_BPB]))[BPB_NSECTOR]), &bpbarray[rp -> r_unit].bpb_nsector);
getword(&((((BYTE *)&buffer.bytes[BT_BPB]))[BPB_NRESERVED]), &bpbarray[rp -> r_unit].bpb_nreserved);
getbyte(&((((BYTE *)&buffer.bytes[BT_BPB]))[BPB_NFAT]), &bpbarray[rp -> r_unit].bpb_nfat);
getword(&((((BYTE *)&buffer.bytes[BT_BPB]))[BPB_NDIRENT]), &bpbarray[rp -> r_unit].bpb_ndirent);
getword(&((((BYTE *)&buffer.bytes[BT_BPB]))[BPB_NSIZE]), &bpbarray[rp -> r_unit].bpb_nsize);
getword(&((((BYTE *)&buffer.bytes[BT_BPB]))[BPB_NSIZE]), &bpbarray[rp -> r_unit].bpb_nsize);
getbyte(&((((BYTE *)&buffer.bytes[BT_BPB]))[BPB_MDESC]), &bpbarray[rp -> r_unit].bpb_mdesc);
getword(&((((BYTE *)&buffer.bytes[BT_BPB]))[BPB_NFSECT]), &bpbarray[rp -> r_unit].bpb_nfsect);
getword(&((((BYTE *)&buffer.bytes[BT_BPB]))[BPB_NSECS]), &bpbarray[rp -> r_unit].bpb_nsecs);
getword(&((((BYTE *)&buffer.bytes[BT_BPB]))[BPB_NHEADS]), &bpbarray[rp -> r_unit].bpb_nheads);
getlong(&((((BYTE *)&buffer.bytes[BT_BPB])[BPB_HIDDEN])), &bpbarray[rp -> r_unit].bpb_hidden);
getlong(&((((BYTE *)&buffer.bytes[BT_BPB])[BPB_HUGE])), &bpbarray[rp -> r_unit].bpb_huge);
#ifdef DSK_DEBUG
printf("BPB_NBYTE = %04x\n", bpbarray[rp -> r_unit].bpb_nbyte);
printf("BPB_NSECTOR = %02x\n", bpbarray[rp -> r_unit].bpb_nsector);
printf("BPB_NRESERVED = %04x\n", bpbarray[rp -> r_unit].bpb_nreserved);
printf("BPB_NFAT = %02x\n", bpbarray[rp -> r_unit].bpb_nfat);
printf("BPB_NDIRENT = %04x\n", bpbarray[rp -> r_unit].bpb_ndirent);
printf("BPB_NSIZE = %04x\n", bpbarray[rp -> r_unit].bpb_nsize);
printf("BPB_MDESC = %02x\n", bpbarray[rp -> r_unit].bpb_mdesc);
printf("BPB_NFSECT = %04x\n", bpbarray[rp -> r_unit].bpb_nfsect);
#endif
rp -> r_bpptr = &bpbarray[rp -> r_unit];
count = miarray[rp -> r_unit].mi_size =
bpbarray[rp -> r_unit].bpb_nsize == 0 ?
bpbarray[rp -> r_unit].bpb_huge :
bpbarray[rp -> r_unit].bpb_nsize;
getword((&(((BYTE *)&buffer.bytes[BT_BPB])[BPB_NHEADS])), &miarray[rp -> r_unit].mi_heads);
head = miarray[rp -> r_unit].mi_heads;
getword((&(((BYTE *)&buffer.bytes[BT_BPB])[BPB_NSECS])), &miarray[rp -> r_unit].mi_sectors);
if(miarray[rp -> r_unit].mi_size == 0)
getlong(&((((BYTE *)&buffer.bytes[BT_BPB])[BPB_HUGE])), &miarray[rp -> r_unit].mi_size);
sector = miarray[rp -> r_unit].mi_sectors;
if(head == 0 || sector == 0)
{
tmark();
return failure(E_FAILURE);
}
miarray[rp -> r_unit].mi_cyls = count / (head * sector);
tmark();
#ifdef DSK_DEBUG
printf("BPB_NSECS = %04x\n", sector);
printf("BPB_NHEADS = %04x\n", head);
printf("BPB_HIDDEN = %08lx\n", bpbarray[rp -> r_unit].bpb_hidden);
printf("BPB_HUGE = %08lx\n", bpbarray[rp -> r_unit].bpb_huge);
#endif
return S_DONE;
}
static WORD
blockio (rqptr rp)
{
REG retry = N_RETRY, remaining;
UWORD cmd, total;
ULONG start;
byteptr trans;
cmd = rp -> r_command;
total = 0;
trans = rp -> r_trans;
tmark();
for
(
remaining = rp -> r_count,
start = (rp -> r_start != HUGECOUNT ? rp -> r_start : rp -> r_huge)
+ miarray[rp -> r_unit].mi_offset;
remaining > 0;
remaining -= count, trans += count * SEC_SIZE, start += count
)
{
if(ltop(&track, §or, &head, rp -> r_unit, 1, start, trans) != 1)
{
/* printf("split sector at 0x%lx", trans);*/
}
count = ltop(&track, §or, &head, rp -> r_unit, remaining, start, trans);
total += count;
do
{
switch(cmd)
{
case C_INPUT:
ret = fl_read((WORD)miarray[rp -> r_unit].mi_drive, (WORD)head, (WORD)track, (WORD)sector, (WORD)count, trans);
break;
case C_OUTPUT:
case C_OUTVFY:
ret = fl_write((WORD)miarray[rp -> r_unit].mi_drive, (WORD)head, (WORD)track, (WORD)sector, (WORD)count, trans);
break;
default:
return failure(E_FAILURE);
}
} while (ret != 0 && --retry > 0);
if(ret != 0)
{
rp -> r_count = 0;
return dskerr(ret);
}
if(cmd == C_OUTVFY)
{
ret = fl_verify((WORD)miarray[rp -> r_unit].mi_drive, (WORD)head, (WORD)track, (WORD)sector, (WORD)count, rp -> r_trans);
if(ret != 0)
{
rp -> r_count = 0;
return dskerr(ret);
}
}
}
rp -> r_count = total;
return S_DONE;
}
static WORD
blk_error (rqptr rp)
{
rp -> r_count = 0;
return failure(E_FAILURE); /* general failure */
}
static WORD
dskerr (COUNT code)
{
/* printf("diskette error:\nhead = %d\ntrack = %d\nsector = %d\ncount = %d\n",
head, track, sector, count);*/
switch(code & 0x03)
{
case 1: /* invalid command - general failure */
if(code & 0x08)
return(E_FAILURE);
else
return failure(E_CMD);
case 2: /* address mark not found - general failure */
return failure(E_FAILURE);
case 3: /* write protect */
return failure(E_WRPRT);
default:
if(code & 0x80) /* time-out */
return failure(E_NOTRDY);
else if(code & 0x40) /* seek error */
return failure(E_SEEK);
else if(code & 0x10) /* CRC error */
return failure(E_CRC);
else if(code & 0x04)
return failure(E_NOTFND);
else
return failure(E_FAILURE);
}
}
/* */
/* Do logical block number to physical head/track/sector mapping */
/* */
static COUNT
ltop (WORD *trackp, WORD *sectorp, WORD *headp, REG COUNT unit, COUNT count, LONG strt_sect, byteptr strt_addr)
{
#ifdef I86
ULONG ltemp;
#endif
REG ls, ps;
#ifdef I86
/* Adjust for segmented architecture */
ltemp = (((ULONG)mk_segment(strt_addr) << 4) + mk_offset(strt_addr)) & 0xffff;
/* Test for 64K boundary crossing and return count large */
/* enough not to exceed the threshold. */
count = (((ltemp + SEC_SIZE * count) & 0xffff0000l) != 0l)
? (0xffffl - ltemp) / SEC_SIZE
: count;
#endif
*trackp = strt_sect / (miarray[unit].mi_heads * miarray[unit].mi_sectors);
*sectorp = strt_sect % miarray[unit].mi_sectors + 1;
*headp = (strt_sect % (miarray[unit].mi_sectors * miarray[unit].mi_heads))
/ miarray[unit].mi_sectors;
if(((ls = *headp * miarray[unit].mi_sectors + *sectorp - 1) + count) >
(ps = miarray[unit].mi_heads * miarray[unit].mi_sectors))
count = ps - ls;
return count;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -