📄 dsk.c
字号:
/****************************************************************//* *//* dsk.c *//* *//* Copyright (c) 1995 *//* Pasquale J. Villani *//* All Rights Reserved *//* *//* This file is part of DOS-C. *//* *//* DOS-C is free software; you can redistribute it and/or *//* modify it under the terms of the GNU General Public License *//* as published by the Free Software Foundation; either version *//* 2, or (at your option) any later version. *//* *//* DOS-C is distributed in the hope that it will be useful, but *//* WITHOUT ANY WARRANTY; without even the implied warranty of *//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See *//* the GNU General Public License for more details. *//* *//* You should have received a copy of the GNU General Public *//* License along with DOS-C; see the file COPYING. If not, *//* write to the Free Software Foundation, 675 Mass Ave, *//* Cambridge, MA 02139, USA. *//****************************************************************/#include "portab.h"#include "globals.h"#include "dyndata.h"#ifdef VERSION_STRINGSstatic BYTE *dskRcsId = "$Id: dsk.c,v 1.44 2004/05/29 09:51:47 bartoldeman Exp $";#endif#if defined(DEBUG)#define DebugPrintf(x) printf x#else#define DebugPrintf(x)#endif/* #define STATIC */BOOL ASMPASCAL fl_reset(WORD);COUNT ASMPASCAL fl_diskchanged(WORD);COUNT ASMPASCAL fl_format(WORD, WORD, WORD, WORD, WORD, UBYTE FAR *);COUNT ASMPASCAL fl_read(WORD, WORD, WORD, WORD, WORD, UBYTE FAR *);COUNT ASMPASCAL fl_write(WORD, WORD, WORD, WORD, WORD, UBYTE FAR *);COUNT ASMPASCAL fl_verify(WORD, WORD, WORD, WORD, WORD, UBYTE FAR *);COUNT ASMPASCAL fl_setdisktype(WORD, WORD);COUNT ASMPASCAL fl_setmediatype(WORD, WORD, WORD);VOID ASMPASCAL fl_readkey(VOID);extern COUNT ASMPASCAL fl_lba_ReadWrite(BYTE drive, WORD mode, struct _bios_LBA_address_packet FAR * dap_p);#ifdef __WATCOMC__#pragma aux (pascal) fl_reset modify exact [ax dx]#pragma aux (pascal) fl_diskchanged modify exact [ax dx]#pragma aux (pascal) fl_setdisktype modify exact [ax bx dx]#pragma aux (pascal) fl_readkey modify exact [ax]#pragma aux (pascal) fl_lba_ReadWrite modify exact [ax dx]#endifSTATIC int LBA_Transfer(ddt * pddt, UWORD mode, VOID FAR * buffer, ULONG LBA_address, unsigned total, UWORD * transferred);#define NENTRY 26 /* total size of dispatch table */#define LBA_READ 0x4200#define LBA_WRITE 0x4300UWORD LBA_WRITE_VERIFY = 0x4302;#define LBA_VERIFY 0x4400#define LBA_FORMAT 0xffff /* fake number for FORMAT track (only for NON-LBA floppies now!) */ /* this buffer must not overlap a 64K boundary due to DMA transfers this is certainly true, if located somewhere at 0xf+1000 and must hold already during BOOT time */UBYTE DiskTransferBuffer[1 * SEC_SIZE];struct FS_info { ULONG serialno; BYTE volume[11]; BYTE fstype[8];};extern struct DynS ASM Dyn;/*TE - array access functions */ddt *getddt(int dev){ return &(((ddt *) Dyn.Buffer)[dev]);}STATIC VOID tmark(ddt *pddt){ pddt->ddt_fh.ddt_lasttime = ReadPCClock();}STATIC BOOL tdelay(ddt *pddt, ULONG ticks){ return ReadPCClock() - pddt->ddt_fh.ddt_lasttime >= ticks;}#define N_PART 4 /* number of partitions per table partition */#define PARTOFF 0x1be#ifdef PROTOtypedef WORD dsk_proc(rqptr rq, ddt * pddt);#elsetypedef WORD dsk_proc();#endifSTATIC dsk_proc mediachk, bldbpb, blockio, IoctlQueblk, Genblkdev, Getlogdev, Setlogdev, blk_Open, blk_Close, blk_Media, blk_noerr, blk_nondr, blk_error;STATIC WORD getbpb(ddt * pddt);#ifdef PROTOSTATIC WORD dskerr(COUNT);#elseSTATIC WORD dskerr();#endif/* *//* the function dispatch table *//* */static dsk_proc * const dispatch[NENTRY] ={ /* disk init is done in diskinit.c, so this should never be called */ blk_error, /* Initialize */ mediachk, /* Media Check */ bldbpb, /* Build BPB */ blk_error, /* Ioctl In */ blockio, /* Input (Read) */ blk_nondr, /* Non-destructive Read */ blk_noerr, /* Input Status */ blk_noerr, /* Input Flush */ blockio, /* Output (Write) */ blockio, /* Output with verify */ blk_noerr, /* Output Status */ blk_noerr, /* Output Flush */ blk_error, /* Ioctl Out */ blk_Open, /* Device Open */ blk_Close, /* Device Close */ blk_Media, /* Removable Media */ blk_noerr, /* Output till busy */ blk_error, /* undefined */ blk_error, /* undefined */ Genblkdev, /* Generic Ioctl Call */ blk_error, /* undefined */ blk_error, /* undefined */ blk_error, /* undefined */ Getlogdev, /* Get Logical Device */ Setlogdev, /* Set Logical Device */ IoctlQueblk /* Ioctl Query */};#define hd(x) ((x) & DF_FIXED)/* ----------------------------------------------------------------------- *//* F U N C T I O N S --------------------------------------------------- *//* ----------------------------------------------------------------------- */COUNT ASMCFUNC FAR blk_driver(rqptr rp){ if (rp->r_unit >= blk_dev.dh_name[0] && 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, getddt(rp->r_unit)));}STATIC char template_string[] = "Remove diskette in drive X:\n";#define DRIVE_POS (sizeof(template_string) - 4)STATIC WORD play_dj(ddt * pddt){ /* play the DJ ... */ if ((pddt->ddt_descflags & (DF_MULTLOG | DF_CURLOG)) == DF_MULTLOG) { int i; ddt *pddt2 = getddt(0); for (i = 0; i < blk_dev.dh_name[0]; i++, pddt2++) { if (pddt->ddt_driveno == pddt2->ddt_driveno && (pddt2->ddt_descflags & (DF_MULTLOG | DF_CURLOG)) == (DF_MULTLOG | DF_CURLOG)) break; } if (i == blk_dev.dh_name[0]) { put_string("Error in the DJ mechanism!\n"); /* should not happen! */ } else { template_string[DRIVE_POS] = 'A' + pddt2->ddt_logdriveno; put_string(template_string); put_string("Insert"); template_string[DRIVE_POS] = 'A' + pddt->ddt_logdriveno; put_string(template_string + 6); put_string("Press the any key to continue ... \n"); fl_readkey(); pddt2->ddt_descflags &= ~DF_CURLOG; pddt->ddt_descflags |= DF_CURLOG; pokeb(0, 0x504, pddt->ddt_logdriveno); } return M_CHANGED; } return M_NOT_CHANGED;}STATIC WORD diskchange(ddt * pddt){ COUNT result; /* if it's a hard drive, media never changes */ if (hd(pddt->ddt_descflags)) return M_NOT_CHANGED; if (play_dj(pddt) == M_CHANGED) return M_CHANGED; if (pddt->ddt_descflags & DF_CHANGELINE) /* if we can detect a change ... */ { if ((result = fl_diskchanged(pddt->ddt_driveno)) == 1) /* check if it has changed... */ return M_CHANGED; else if (result == 0) return M_NOT_CHANGED; } /* can not detect or error... */ return tdelay(pddt, 37ul) ? M_DONT_KNOW : M_NOT_CHANGED;}STATIC WORD mediachk(rqptr rp, ddt * pddt){ /* check floppy status */ if (pddt->ddt_descflags & DF_REFORMAT) { pddt->ddt_descflags &= ~DF_REFORMAT; rp->r_mcretcode = M_CHANGED; } else if (pddt->ddt_descflags & DF_DISKCHANGE) { pddt->ddt_descflags &= ~DF_DISKCHANGE; rp->r_mcretcode = M_DONT_KNOW; } else { rp->r_mcretcode = diskchange(pddt); if (rp->r_mcretcode == M_DONT_KNOW) { /* don't know but can check serial number ... */ ULONG serialno = pddt->ddt_serialno; COUNT result = getbpb(pddt); if (result != 0) return (result); if (serialno != pddt->ddt_serialno) rp->r_mcretcode = M_CHANGED; } } return S_DONE;}/* * Read Write Sector Zero or Hard Drive Dos Bpb */STATIC WORD RWzero(ddt * pddt, UWORD mode){ UWORD done; return LBA_Transfer(pddt, mode, (UBYTE FAR *) & DiskTransferBuffer, pddt->ddt_offset, 1, &done);}/* 0 if not set, 1 = a, 2 = b, etc, assume set. page 424 MS Programmer's Ref. */STATIC WORD Getlogdev(rqptr rp, ddt * pddt){ int i; ddt *pddt2; if (!(pddt->ddt_descflags & DF_MULTLOG)) { rp->r_unit = 0; return S_DONE; } pddt2 = getddt(0); for (i = 0; i < blk_dev.dh_name[0]; i++, pddt2++) { if (pddt->ddt_driveno == pddt2->ddt_driveno && (pddt2->ddt_descflags & (DF_MULTLOG | DF_CURLOG)) == (DF_MULTLOG | DF_CURLOG)) break; } rp->r_unit = i+1; return S_DONE;}STATIC WORD Setlogdev(rqptr rp, ddt * pddt){ unsigned char unit = rp->r_unit; Getlogdev(rp, pddt); if (rp->r_unit == 0) return S_DONE; getddt(rp->r_unit - 1)->ddt_descflags &= ~DF_CURLOG; pddt->ddt_descflags |= DF_CURLOG; rp->r_unit = unit + 1; return S_DONE;}STATIC WORD blk_Open(rqptr rp, ddt * pddt){ UNREFERENCED_PARAMETER(rp); pddt->ddt_FileOC++; return S_DONE;}STATIC WORD blk_Close(rqptr rp, ddt * pddt){ UNREFERENCED_PARAMETER(rp); pddt->ddt_FileOC--; return S_DONE;}STATIC WORD blk_nondr(rqptr rp, ddt * pddt){ UNREFERENCED_PARAMETER(rp); UNREFERENCED_PARAMETER(pddt); return S_BUSY | S_DONE;}STATIC WORD blk_Media(rqptr rp, ddt * pddt){ UNREFERENCED_PARAMETER(rp); if (hd(pddt->ddt_descflags)) return S_BUSY | S_DONE; /* Hard Drive */ else return S_DONE; /* Floppy */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -