📄 blockio.c
字号:
do
{
if (bp->b_unit == dsk)
bp->b_flag = 0;
bp = b_next(bp);
}
while (FP_OFF(bp) != FP_OFF(firstbuf));
}
/* */
/* Flush all buffers for a disk */
/* */
/* returns: */
/* TRUE on success */
/* */
BOOL flush_buffers(REG COUNT dsk)
{
struct buffer FAR *bp = firstbuf;
REG BOOL ok = TRUE;
bp = firstbuf;
do
{
if (bp->b_unit == dsk)
if (!flush1(bp))
ok = FALSE;
bp = b_next(bp);
}
while (FP_OFF(bp) != FP_OFF(firstbuf));
return ok;
}
/* */
/* Write one disk buffer */
/* */
STATIC BOOL flush1(struct buffer FAR * bp)
{
/* All lines with changes on 9/4/00 by BER marked below */
UWORD result; /* BER 9/4/00 */
if ((bp->b_flag & (BFR_VALID | BFR_DIRTY)) == (BFR_VALID | BFR_DIRTY))
{
/* BER 9/4/00 */
result = dskxfer(bp->b_unit, bp->b_blkno, bp->b_buffer, 1, DSKWRITE);
if (bp->b_flag & BFR_FAT)
{
UWORD b_copies = bp->b_copies;
ULONG blkno = bp->b_blkno;
#ifdef WITHFAT32
ULONG b_offset = bp->b_offset;
if (b_offset == 0) /* FAT32 FS */
b_offset = bp->b_dpbp->dpb_xfatsize;
#else
UWORD b_offset = bp->b_offset;
#endif
while (--b_copies > 0)
{
blkno += b_offset;
/* BER 9/4/00 */
result = dskxfer(bp->b_unit, blkno, bp->b_buffer, 1, DSKWRITE);
}
}
}
else
result = 0; /* This negates any error code returned in result...BER */
/* and 0 returned, if no errors occurred - tom */
bp->b_flag &= ~BFR_DIRTY; /* even if error, mark not dirty */
if (result != 0) /* otherwise system has trouble */
bp->b_flag &= ~BFR_VALID; /* continuing. */
return (TRUE); /* Forced to TRUE...was like this before dskxfer() */
/* returned error codes...BER */
}
/* */
/* Write all disk buffers */
/* */
BOOL flush(void)
{
REG struct buffer FAR *bp = firstbuf;
REG BOOL ok;
ok = TRUE;
do
{
if (!flush1(bp))
ok = FALSE;
bp->b_flag &= ~BFR_VALID;
bp = b_next(bp);
}
while (FP_OFF(bp) != FP_OFF(firstbuf));
network_redirector(REM_FLUSHALL);
return (ok);
}
/************************************************************************/
/* */
/* Device Driver Interface Functions */
/* */
/************************************************************************/
/* */
/* Transfer one or more blocks to/from disk */
/* */
UWORD dskxfer(COUNT dsk, ULONG blkno, VOID FAR * buf, UWORD numblocks,
COUNT mode)
{
register struct dpb FAR *dpbp = get_dpb(dsk);
if (dpbp == NULL)
{
return 0x0201; /* illegal command */
}
#if TOM
#define KeyboardShiftState() (*(BYTE FAR *)(MK_FP(0x40,0x17)))
if (KeyboardShiftState() & 0x01)
{
printf("dskxfer:%s %x - %lx %u\n", mode == DSKWRITE ? "write" : "read",
dsk, blkno, numblocks);
if ((KeyboardShiftState() & 0x03) == 3)
dumpBufferCache();
}
#endif
for (;;)
{
IoReqHdr.r_length = sizeof(request);
IoReqHdr.r_unit = dpbp->dpb_subunit;
switch (mode)
{
case DSKWRITE:
if (verify_ena)
{
IoReqHdr.r_command = C_OUTVFY;
break;
}
/* else fall through */
case DSKWRITEINT26:
IoReqHdr.r_command = C_OUTPUT;
break;
case DSKREADINT25:
case DSKREAD:
IoReqHdr.r_command = C_INPUT;
break;
default:
return 0x0100; /* illegal command */
}
IoReqHdr.r_status = 0;
IoReqHdr.r_meddesc = dpbp->dpb_mdb;
IoReqHdr.r_count = numblocks;
if ((dpbp->dpb_device->dh_attr & ATTR_HUGE) || blkno >= MAXSHORT)
{
IoReqHdr.r_start = HUGECOUNT;
IoReqHdr.r_huge = blkno;
}
else
IoReqHdr.r_start = (UWORD)blkno;
/*
* Some drivers normalise transfer address so HMA transfers are disastrous!
* Then transfer block through xferbuf (DiskTransferBuffer doesn't work!)
* (But this won't work for multi-block HMA transfers... are there any?)
*/
if (FP_SEG(buf) >= 0xa000 && numblocks == 1 && bufloc != LOC_CONV)
{
IoReqHdr.r_trans = deblock_buf;
if (mode == DSKWRITE)
fmemcpy(deblock_buf, buf, SEC_SIZE);
execrh((request FAR *) & IoReqHdr, dpbp->dpb_device);
if (mode == DSKREAD)
fmemcpy(buf, deblock_buf, SEC_SIZE);
}
else
{
IoReqHdr.r_trans = (BYTE FAR *) buf;
execrh((request FAR *) & IoReqHdr, dpbp->dpb_device);
}
if ((IoReqHdr.r_status & (S_ERROR | S_DONE)) == S_DONE)
break;
/* INT25/26 (_SEEMS_ TO) return immediately with 0x8002,
if drive is not online,...
normal operations (DIR) wait for ABORT/RETRY
other condition codes not tested
*/
if (mode >= DSKWRITEINT26)
return (IoReqHdr.r_status);
loop:
switch (block_error(&IoReqHdr, dpbp->dpb_unit, dpbp->dpb_device, mode))
{
case ABORT:
case FAIL:
return (IoReqHdr.r_status);
case RETRY:
continue;
case CONTINUE:
break;
default:
goto loop;
}
break;
} /* retry loop */
/* *** Changed 9/4/00 BER */
return 0; /* Success! Return 0 for a successful operation. */
/* End of change */
}
/*
this removes any (additionally allocated) buffers
from the HMA buffer chain, because they get allocated to the 'user'
*/
void AllocateHMASpace (size_t lowbuffer, size_t highbuffer)
{
REG struct buffer FAR *bp = firstbuf;
int n;
if (FP_SEG(bp) != 0xffff)
return;
n = LoL_nbuffers;
do
{
/* check if buffer intersects with requested area */
if (FP_OFF(bp) < highbuffer && FP_OFF(bp+1) > lowbuffer)
{
flush1(bp);
/* unlink bp from buffer chain */
b_prev(bp)->b_next = bp->b_next;
b_next(bp)->b_prev = bp->b_prev;
if (FP_OFF(bp) == FP_OFF(firstbuf))
firstbuf = b_next(bp);
LoL_nbuffers--;
}
bp = b_next(bp);
}
while (--n);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -