GAS LISTING /tmp/cck0ihkU.s page 1 GNU assembler version 2.39 (ia16-elf) using BFD version (GNU Binutils) 2.39. options passed : -a=dsk.lst --listing-cont-lines=9999 --listing-rhs-width=9999 --listing-lhs-width=2 -ag input file : /tmp/cck0ihkU.s output file : dsk.obj target : ia16-unknown-elf time stamp : 2026-04-23T12:04:08.000+0200 GAS LISTING /tmp/cck0ihkU.s page 2 1 .arch i8086,jumps 2 .code16 3 .intel_syntax noprefix 4 #NO_APP 5 .text 6 _.Ltext0: 7 .type _blk_Open, @function 8 _blk_Open: 9 _.LFB14: 10 .file 1 "dsk.c" 1:dsk.c **** /****************************************************************/ 2:dsk.c **** /* */ 3:dsk.c **** /* dsk.c */ 4:dsk.c **** /* */ 5:dsk.c **** /* Copyright (c) 1995 */ 6:dsk.c **** /* Pasquale J. Villani */ 7:dsk.c **** /* All Rights Reserved */ 8:dsk.c **** /* */ 9:dsk.c **** /* This file is part of DOS-C. */ 10:dsk.c **** /* */ 11:dsk.c **** /* DOS-C is free software; you can redistribute it and/or */ 12:dsk.c **** /* modify it under the terms of the GNU General Public License */ 13:dsk.c **** /* as published by the Free Software Foundation; either version */ 14:dsk.c **** /* 2, or (at your option) any later version. */ 15:dsk.c **** /* */ 16:dsk.c **** /* DOS-C is distributed in the hope that it will be useful, but */ 17:dsk.c **** /* WITHOUT ANY WARRANTY; without even the implied warranty of */ 18:dsk.c **** /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ 19:dsk.c **** /* the GNU General Public License for more details. */ 20:dsk.c **** /* */ 21:dsk.c **** /* You should have received a copy of the GNU General Public */ 22:dsk.c **** /* License along with DOS-C; see the file COPYING. If not, */ 23:dsk.c **** /* write to the Free Software Foundation, 675 Mass Ave, */ 24:dsk.c **** /* Cambridge, MA 02139, USA. */ 25:dsk.c **** /****************************************************************/ 26:dsk.c **** 27:dsk.c **** #include "portab.h" 28:dsk.c **** #include "globals.h" 29:dsk.c **** #include "dyndata.h" 30:dsk.c **** 31:dsk.c **** #ifdef VERSION_STRINGS 32:dsk.c **** static BYTE *dskRcsId = 33:dsk.c **** "$Id: dsk.c 1702 2012-02-04 08:46:16Z perditionc $"; 34:dsk.c **** #endif 35:dsk.c **** 36:dsk.c **** #if defined(DEBUG) 37:dsk.c **** #define DebugPrintf(x) printf x 38:dsk.c **** #else 39:dsk.c **** #define DebugPrintf(x) 40:dsk.c **** #endif 41:dsk.c **** 42:dsk.c **** /* #define STATIC */ 43:dsk.c **** 44:dsk.c **** BOOL ASMPASCAL fl_reset(WORD); 45:dsk.c **** COUNT ASMPASCAL fl_diskchanged(WORD); 46:dsk.c **** 47:dsk.c **** COUNT ASMPASCAL fl_format(WORD, WORD, WORD, WORD, WORD, UBYTE FAR *); GAS LISTING /tmp/cck0ihkU.s page 3 48:dsk.c **** COUNT ASMPASCAL fl_read(WORD, WORD, WORD, WORD, WORD, UBYTE FAR *); 49:dsk.c **** COUNT ASMPASCAL fl_write(WORD, WORD, WORD, WORD, WORD, UBYTE FAR *); 50:dsk.c **** COUNT ASMPASCAL fl_verify(WORD, WORD, WORD, WORD, WORD, UBYTE FAR *); 51:dsk.c **** COUNT ASMPASCAL fl_setdisktype(WORD, WORD); 52:dsk.c **** COUNT ASMPASCAL fl_setmediatype(WORD, WORD, WORD); 53:dsk.c **** VOID ASMPASCAL fl_readkey(VOID); 54:dsk.c **** extern COUNT ASMPASCAL fl_lba_ReadWrite(BYTE drive, WORD mode, 55:dsk.c **** struct _bios_LBA_address_packet FAR 56:dsk.c **** * dap_p); 57:dsk.c **** UWORD ASMPASCAL floppy_change(UWORD); 58:dsk.c **** #ifdef __WATCOMC__ 59:dsk.c **** #pragma aux (__pascal) fl_reset __modify __exact [__ax __dx] 60:dsk.c **** #pragma aux (__pascal) fl_diskchanged __modify __exact [__ax __dx] 61:dsk.c **** #pragma aux (__pascal) fl_setdisktype __modify __exact [__ax __bx __dx] 62:dsk.c **** #pragma aux (__pascal) fl_readkey __modify __exact [__ax] 63:dsk.c **** #pragma aux (__pascal) fl_lba_ReadWrite __modify __exact [__ax __dx] 64:dsk.c **** #pragma aux (__pascal) floppy_change __modify __exact [__ax __cx __dx] 65:dsk.c **** #endif 66:dsk.c **** 67:dsk.c **** STATIC int LBA_Transfer(ddt * pddt, UWORD mode, VOID FAR * buffer, 68:dsk.c **** ULONG LBA_address, unsigned total, UWORD * transferred); 69:dsk.c **** 70:dsk.c **** #define NENTRY 26 /* total size of dispatch table */ 71:dsk.c **** 72:dsk.c **** #define LBA_READ 0x4200 73:dsk.c **** #define LBA_WRITE 0x4300 74:dsk.c **** UWORD LBA_WRITE_VERIFY = 0x4302; 75:dsk.c **** #define LBA_VERIFY 0x4400 76:dsk.c **** #define LBA_FORMAT 0xffff /* fake number for FORMAT track 77:dsk.c **** (only for NON-LBA floppies now!) */ 78:dsk.c **** 79:dsk.c **** /* this buffer must not overlap a 64K boundary 80:dsk.c **** due to DMA transfers 81:dsk.c **** this is certainly true, if located somewhere 82:dsk.c **** at 0xf+1000 and must hold already during BOOT time 83:dsk.c **** */ 84:dsk.c **** UBYTE DiskTransferBuffer[MAX_SEC_SIZE]; 85:dsk.c **** 86:dsk.c **** struct FS_info { 87:dsk.c **** ULONG serialno; 88:dsk.c **** BYTE volume[11]; 89:dsk.c **** BYTE fstype[8]; 90:dsk.c **** }; 91:dsk.c **** 92:dsk.c **** extern struct DynS ASM Dyn; 93:dsk.c **** 94:dsk.c **** /*TE - array access functions */ 95:dsk.c **** ddt *getddt(int dev) 96:dsk.c **** { 97:dsk.c **** return &(((ddt *) Dyn.Buffer)[dev]); 98:dsk.c **** } 99:dsk.c **** 100:dsk.c **** STATIC VOID tmark(ddt *pddt) 101:dsk.c **** { 102:dsk.c **** pddt->ddt_fh.ddt_lasttime = ReadPCClock(); 103:dsk.c **** } 104:dsk.c **** GAS LISTING /tmp/cck0ihkU.s page 4 105:dsk.c **** STATIC BOOL tdelay(ddt *pddt, ULONG ticks) 106:dsk.c **** { 107:dsk.c **** return ReadPCClock() - pddt->ddt_fh.ddt_lasttime >= ticks; 108:dsk.c **** } 109:dsk.c **** 110:dsk.c **** #define N_PART 4 /* number of partitions per 111:dsk.c **** table partition */ 112:dsk.c **** 113:dsk.c **** #define PARTOFF 0x1be 114:dsk.c **** 115:dsk.c **** #ifdef PROTO 116:dsk.c **** typedef WORD dsk_proc(rqptr rq, ddt * pddt); 117:dsk.c **** #else 118:dsk.c **** typedef WORD dsk_proc(); 119:dsk.c **** #endif 120:dsk.c **** 121:dsk.c **** STATIC dsk_proc mediachk, bldbpb, blockio, IoctlQueblk, 122:dsk.c **** Genblkdev, Getlogdev, Setlogdev, blk_Open, blk_Close, 123:dsk.c **** blk_Media, blk_noerr, blk_nondr, blk_error; 124:dsk.c **** 125:dsk.c **** STATIC WORD getbpb(ddt * pddt); 126:dsk.c **** #ifdef PROTO 127:dsk.c **** STATIC WORD dskerr(COUNT); 128:dsk.c **** #else 129:dsk.c **** STATIC WORD dskerr(); 130:dsk.c **** #endif 131:dsk.c **** 132:dsk.c **** /* */ 133:dsk.c **** /* the function dispatch table */ 134:dsk.c **** /* */ 135:dsk.c **** 136:dsk.c **** static dsk_proc * const dispatch[NENTRY] = 137:dsk.c **** { 138:dsk.c **** /* disk init is done in diskinit.c, so this should never be called */ 139:dsk.c **** blk_error, /* Initialize */ 140:dsk.c **** mediachk, /* Media Check */ 141:dsk.c **** bldbpb, /* Build BPB */ 142:dsk.c **** blk_error, /* Ioctl In */ 143:dsk.c **** blockio, /* Input (Read) */ 144:dsk.c **** blk_nondr, /* Non-destructive Read */ 145:dsk.c **** blk_noerr, /* Input Status */ 146:dsk.c **** blk_noerr, /* Input Flush */ 147:dsk.c **** blockio, /* Output (Write) */ 148:dsk.c **** blockio, /* Output with verify */ 149:dsk.c **** blk_noerr, /* Output Status */ 150:dsk.c **** blk_noerr, /* Output Flush */ 151:dsk.c **** blk_error, /* Ioctl Out */ 152:dsk.c **** blk_Open, /* Device Open */ 153:dsk.c **** blk_Close, /* Device Close */ 154:dsk.c **** blk_Media, /* Removable Media */ 155:dsk.c **** blk_noerr, /* Output till busy */ 156:dsk.c **** blk_error, /* undefined */ 157:dsk.c **** blk_error, /* undefined */ 158:dsk.c **** Genblkdev, /* Generic Ioctl Call */ 159:dsk.c **** blk_error, /* undefined */ 160:dsk.c **** blk_error, /* undefined */ 161:dsk.c **** blk_error, /* undefined */ GAS LISTING /tmp/cck0ihkU.s page 5 162:dsk.c **** Getlogdev, /* Get Logical Device */ 163:dsk.c **** Setlogdev, /* Set Logical Device */ 164:dsk.c **** IoctlQueblk /* Ioctl Query */ 165:dsk.c **** }; 166:dsk.c **** 167:dsk.c **** #define hd(x) ((x) & DF_FIXED) 168:dsk.c **** 169:dsk.c **** /* ----------------------------------------------------------------------- */ 170:dsk.c **** /* F U N C T I O N S --------------------------------------------------- */ 171:dsk.c **** /* ----------------------------------------------------------------------- */ 172:dsk.c **** 173:dsk.c **** COUNT ASMCFUNC FAR blk_driver(rqptr rp) 174:dsk.c **** { 175:dsk.c **** if (rp->r_unit >= blk_dev.dh_name[0] && rp->r_command != C_INIT) 176:dsk.c **** return failure(E_UNIT); 177:dsk.c **** if (rp->r_command > NENTRY) 178:dsk.c **** { 179:dsk.c **** return failure(E_FAILURE); /* general failure */ 180:dsk.c **** } 181:dsk.c **** else 182:dsk.c **** return ((*dispatch[rp->r_command]) (rp, getddt(rp->r_unit))); 183:dsk.c **** } 184:dsk.c **** 185:dsk.c **** STATIC char template_string[] = "Remove diskette in drive X:\n"; 186:dsk.c **** #define DRIVE_POS (sizeof(template_string) - 4) 187:dsk.c **** 188:dsk.c **** STATIC WORD play_dj(ddt * pddt) 189:dsk.c **** { 190:dsk.c **** /* play the DJ ... */ 191:dsk.c **** if ((pddt->ddt_descflags & (DF_MULTLOG | DF_CURLOG)) == DF_MULTLOG) 192:dsk.c **** { 193:dsk.c **** int i; 194:dsk.c **** ddt *pddt2 = getddt(0); 195:dsk.c **** for (i = 0; i < blk_dev.dh_name[0]; i++, pddt2++) 196:dsk.c **** { 197:dsk.c **** if (pddt->ddt_driveno == pddt2->ddt_driveno && 198:dsk.c **** (pddt2->ddt_descflags & (DF_MULTLOG | DF_CURLOG)) == 199:dsk.c **** (DF_MULTLOG | DF_CURLOG)) 200:dsk.c **** break; 201:dsk.c **** } 202:dsk.c **** if (i == blk_dev.dh_name[0]) 203:dsk.c **** { 204:dsk.c **** put_string("Error in the DJ mechanism!\n"); /* should not happen! */ 205:dsk.c **** } 206:dsk.c **** else 207:dsk.c **** { 208:dsk.c **** xreg dx; 209:dsk.c **** dx.b.l = pddt->ddt_logdriveno; 210:dsk.c **** dx.b.h = pddt2->ddt_logdriveno; 211:dsk.c **** /* call int2f/ax=4a00 */ 212:dsk.c **** if (floppy_change(dx.x) != 0xffff) { 213:dsk.c **** /* if someone else does not make a nice dialog... */ 214:dsk.c **** template_string[DRIVE_POS] = 'A' + pddt2->ddt_logdriveno; 215:dsk.c **** put_string(template_string); 216:dsk.c **** put_string("Insert"); 217:dsk.c **** template_string[DRIVE_POS] = 'A' + pddt->ddt_logdriveno; 218:dsk.c **** put_string(template_string + 6); GAS LISTING /tmp/cck0ihkU.s page 6 219:dsk.c **** put_string("Press any key to continue ... \n"); 220:dsk.c **** fl_readkey(); 221:dsk.c **** } 222:dsk.c **** pddt2->ddt_descflags &= ~DF_CURLOG; 223:dsk.c **** pddt->ddt_descflags |= DF_CURLOG; 224:dsk.c **** pokeb(0, 0x504, pddt->ddt_logdriveno); 225:dsk.c **** } 226:dsk.c **** return M_CHANGED; 227:dsk.c **** } 228:dsk.c **** return M_NOT_CHANGED; 229:dsk.c **** } 230:dsk.c **** 231:dsk.c **** STATIC WORD diskchange(ddt * pddt) 232:dsk.c **** { 233:dsk.c **** COUNT result; 234:dsk.c **** 235:dsk.c **** /* if it's a hard drive, media never changes */ 236:dsk.c **** if (hd(pddt->ddt_descflags)) 237:dsk.c **** return M_NOT_CHANGED; 238:dsk.c **** 239:dsk.c **** if (play_dj(pddt) == M_CHANGED) 240:dsk.c **** return M_CHANGED; 241:dsk.c **** 242:dsk.c **** if (pddt->ddt_descflags & DF_CHANGELINE) /* if we can detect a change ... */ 243:dsk.c **** { 244:dsk.c **** if ((result = fl_diskchanged(pddt->ddt_driveno)) == 1) 245:dsk.c **** /* check if it has changed... */ 246:dsk.c **** return M_CHANGED; 247:dsk.c **** else if (result == 0) 248:dsk.c **** return M_NOT_CHANGED; 249:dsk.c **** } 250:dsk.c **** 251:dsk.c **** /* can not detect or error... */ 252:dsk.c **** return tdelay(pddt, 37ul) ? M_DONT_KNOW : M_NOT_CHANGED; 253:dsk.c **** } 254:dsk.c **** 255:dsk.c **** STATIC WORD mediachk(rqptr rp, ddt * pddt) 256:dsk.c **** { 257:dsk.c **** /* check floppy status */ 258:dsk.c **** if (pddt->ddt_descflags & DF_REFORMAT) 259:dsk.c **** { 260:dsk.c **** pddt->ddt_descflags &= ~DF_REFORMAT; 261:dsk.c **** rp->r_mcretcode = M_CHANGED; 262:dsk.c **** } 263:dsk.c **** else if (pddt->ddt_descflags & DF_DISKCHANGE) 264:dsk.c **** { 265:dsk.c **** pddt->ddt_descflags &= ~DF_DISKCHANGE; 266:dsk.c **** rp->r_mcretcode = M_DONT_KNOW; 267:dsk.c **** } 268:dsk.c **** else 269:dsk.c **** { 270:dsk.c **** rp->r_mcretcode = diskchange(pddt); 271:dsk.c **** if (rp->r_mcretcode == M_DONT_KNOW) 272:dsk.c **** { 273:dsk.c **** /* don't know but can check serial number ... */ 274:dsk.c **** ULONG serialno = pddt->ddt_serialno; 275:dsk.c **** COUNT result = getbpb(pddt); GAS LISTING /tmp/cck0ihkU.s page 7 276:dsk.c **** if (result != 0) 277:dsk.c **** return (result); 278:dsk.c **** if (serialno != pddt->ddt_serialno) 279:dsk.c **** rp->r_mcretcode = M_CHANGED; 280:dsk.c **** } 281:dsk.c **** } 282:dsk.c **** return S_DONE; 283:dsk.c **** } 284:dsk.c **** 285:dsk.c **** /* 286:dsk.c **** * Read Write Sector Zero or Hard Drive Dos Bpb 287:dsk.c **** */ 288:dsk.c **** STATIC WORD RWzero(ddt * pddt, UWORD mode) 289:dsk.c **** { 290:dsk.c **** UWORD done; 291:dsk.c **** 292:dsk.c **** return LBA_Transfer(pddt, mode, 293:dsk.c **** (UBYTE FAR *) DiskTransferBuffer, 294:dsk.c **** pddt->ddt_offset, 1, &done); 295:dsk.c **** } 296:dsk.c **** 297:dsk.c **** /* 298:dsk.c **** 0 if not set, 1 = a, 2 = b, etc, assume set. 299:dsk.c **** page 424 MS Programmer's Ref. 300:dsk.c **** */ 301:dsk.c **** STATIC WORD Getlogdev(rqptr rp, ddt * pddt) 302:dsk.c **** { 303:dsk.c **** int i; 304:dsk.c **** ddt *pddt2; 305:dsk.c **** 306:dsk.c **** if (!(pddt->ddt_descflags & DF_MULTLOG)) { 307:dsk.c **** rp->r_unit = 0; 308:dsk.c **** return S_DONE; 309:dsk.c **** } 310:dsk.c **** 311:dsk.c **** pddt2 = getddt(0); 312:dsk.c **** for (i = 0; i < blk_dev.dh_name[0]; i++, pddt2++) 313:dsk.c **** { 314:dsk.c **** if (pddt->ddt_driveno == pddt2->ddt_driveno && 315:dsk.c **** (pddt2->ddt_descflags & (DF_MULTLOG | DF_CURLOG)) == 316:dsk.c **** (DF_MULTLOG | DF_CURLOG)) 317:dsk.c **** break; 318:dsk.c **** } 319:dsk.c **** 320:dsk.c **** rp->r_unit = i+1; 321:dsk.c **** return S_DONE; 322:dsk.c **** } 323:dsk.c **** 324:dsk.c **** STATIC WORD Setlogdev(rqptr rp, ddt * pddt) 325:dsk.c **** { 326:dsk.c **** unsigned char unit = rp->r_unit; 327:dsk.c **** Getlogdev(rp, pddt); 328:dsk.c **** if (rp->r_unit == 0) 329:dsk.c **** return S_DONE; 330:dsk.c **** getddt(rp->r_unit - 1)->ddt_descflags &= ~DF_CURLOG; 331:dsk.c **** pddt->ddt_descflags |= DF_CURLOG; 332:dsk.c **** rp->r_unit = unit + 1; GAS LISTING /tmp/cck0ihkU.s page 8 333:dsk.c **** return S_DONE; 334:dsk.c **** } 335:dsk.c **** 336:dsk.c **** STATIC WORD blk_Open(rqptr rp, ddt * pddt) 337:dsk.c **** { 11 .loc 1 337 0 12 _.LVL0: 13 0000 89E3 mov bx, sp 14 _.LCFI0: 15 0002 8B5F06 mov bx, word ptr [bx+6] 338:dsk.c **** UNREFERENCED_PARAMETER(rp); 339:dsk.c **** 340:dsk.c **** pddt->ddt_FileOC++; 16 .loc 1 340 0 17 0005 FF4730 inc word ptr [bx+48] 341:dsk.c **** return S_DONE; 342:dsk.c **** } 18 .loc 1 342 0 19 0008 B80001 mov ax, 256 20 000b C20600 ret 6 21 _.LFE14: 22 .size _blk_Open, .-_blk_Open 23 .type _blk_Close, @function 24 _blk_Close: 25 _.LFB15: 343:dsk.c **** 344:dsk.c **** STATIC WORD blk_Close(rqptr rp, ddt * pddt) 345:dsk.c **** { 26 .loc 1 345 0 27 _.LVL1: 28 000e 89E3 mov bx, sp 29 _.LCFI1: 30 0010 8B5F06 mov bx, word ptr [bx+6] 346:dsk.c **** UNREFERENCED_PARAMETER(rp); 347:dsk.c **** 348:dsk.c **** pddt->ddt_FileOC--; 31 .loc 1 348 0 32 0013 FF4F30 dec word ptr [bx+48] 349:dsk.c **** return S_DONE; 350:dsk.c **** } 33 .loc 1 350 0 34 0016 B80001 mov ax, 256 35 0019 C20600 ret 6 36 _.LFE15: 37 .size _blk_Close, .-_blk_Close 38 .type _blk_nondr, @function 39 _blk_nondr: 40 _.LFB16: 351:dsk.c **** 352:dsk.c **** STATIC WORD blk_nondr(rqptr rp, ddt * pddt) 353:dsk.c **** { 41 .loc 1 353 0 42 _.LVL2: 354:dsk.c **** UNREFERENCED_PARAMETER(rp); 355:dsk.c **** UNREFERENCED_PARAMETER(pddt); 356:dsk.c **** 357:dsk.c **** return S_BUSY | S_DONE; GAS LISTING /tmp/cck0ihkU.s page 9 358:dsk.c **** } 43 .loc 1 358 0 44 001c B80003 mov ax, 768 45 001f C20600 ret 6 46 _.LFE16: 47 .size _blk_nondr, .-_blk_nondr 48 .type _blk_Media, @function 49 _blk_Media: 50 _.LFB17: 359:dsk.c **** 360:dsk.c **** STATIC WORD blk_Media(rqptr rp, ddt * pddt) 361:dsk.c **** { 51 .loc 1 361 0 52 _.LVL3: 53 0022 89E3 mov bx, sp 54 _.LCFI2: 362:dsk.c **** UNREFERENCED_PARAMETER(rp); 363:dsk.c **** 364:dsk.c **** if (hd(pddt->ddt_descflags)) 55 .loc 1 364 0 56 0024 8B5F06 mov bx, word ptr [bx+6] 57 0027 F6473301 test byte ptr [bx+51], 1 58 002b 7506 jne _.L9 365:dsk.c **** return S_BUSY | S_DONE; /* Hard Drive */ 366:dsk.c **** else 367:dsk.c **** return S_DONE; /* Floppy */ 59 .loc 1 367 0 60 002d B80001 mov ax, 256 61 _.L7: 368:dsk.c **** } 62 .loc 1 368 0 63 0030 C20600 ret 6 64 _.L9: 365:dsk.c **** return S_BUSY | S_DONE; /* Hard Drive */ 65 .loc 1 365 0 66 0033 B80003 mov ax, 768 67 0036 EBF8 jmp _.L7 68 _.LFE17: 69 .size _blk_Media, .-_blk_Media 70 .type _IoctlQueblk, @function 71 _IoctlQueblk: 72 _.LFB20: 369:dsk.c **** 370:dsk.c **** STATIC WORD getbpb(ddt * pddt) 371:dsk.c **** { 372:dsk.c **** ULONG count; 373:dsk.c **** bpb *pbpbarray = &pddt->ddt_bpb; 374:dsk.c **** unsigned secs_per_cyl; 375:dsk.c **** WORD ret; 376:dsk.c **** 377:dsk.c **** /* pddt->ddt_descflags |= DF_NOACCESS; 378:dsk.c **** * disabled for now - problems with FORMAT ?? */ 379:dsk.c **** 380:dsk.c **** /* set drive to not accessible and changed */ 381:dsk.c **** if (diskchange(pddt) != M_NOT_CHANGED) 382:dsk.c **** pddt->ddt_descflags |= DF_DISKCHANGE; 383:dsk.c **** GAS LISTING /tmp/cck0ihkU.s page 10 384:dsk.c **** ret = RWzero(pddt, LBA_READ); 385:dsk.c **** if (ret != 0) 386:dsk.c **** return (dskerr(ret)); 387:dsk.c **** 388:dsk.c **** pbpbarray->bpb_nbyte = getword(&DiskTransferBuffer[BT_BPB]); 389:dsk.c **** 390:dsk.c **** if (DiskTransferBuffer[0x1fe] != 0x55 391:dsk.c **** || DiskTransferBuffer[0x1ff] != 0xaa || pbpbarray->bpb_nbyte % 512) 392:dsk.c **** { 393:dsk.c **** /* copy default bpb to be sure that there is no bogus data */ 394:dsk.c **** memcpy(pbpbarray, &pddt->ddt_defbpb, sizeof(bpb)); 395:dsk.c **** return 0; 396:dsk.c **** } 397:dsk.c **** 398:dsk.c **** pddt->ddt_descflags &= ~DF_NOACCESS; /* set drive to accessible */ 399:dsk.c **** 400:dsk.c **** /*TE ~ 200 bytes*/ 401:dsk.c **** 402:dsk.c **** memcpy(pbpbarray, &DiskTransferBuffer[BT_BPB], sizeof(bpb)); 403:dsk.c **** 404:dsk.c **** /*?? */ 405:dsk.c **** /* 2b is fat16 volume label. if memcmp, then offset 0x36. 406:dsk.c **** if (fstrncmp((BYTE *) & DiskTransferBuffer[0x36], "FAT16",5) == 0 || 407:dsk.c **** fstrncmp((BYTE *) & DiskTransferBuffer[0x36], "FAT12",5) == 0) { 408:dsk.c **** TE: I'm not sure, what the _real_ decision point is, however MSDN 409:dsk.c **** 'A_BF_BPB_SectorsPerFAT 410:dsk.c **** The number of sectors per FAT. 411:dsk.c **** Note: This member will always be zero in a FAT32 BPB. 412:dsk.c **** Use the values from A_BF_BPB_BigSectorsPerFat... 413:dsk.c **** */ 414:dsk.c **** { 415:dsk.c **** struct FS_info *fs = (struct FS_info *)&DiskTransferBuffer[0x27]; 416:dsk.c **** register BYTE extended_BPB_signature; 417:dsk.c **** #ifdef WITHFAT32 418:dsk.c **** if (pbpbarray->bpb_nfsect == 0) 419:dsk.c **** { 420:dsk.c **** /* FAT32 boot sector */ 421:dsk.c **** fs = (struct FS_info *)&DiskTransferBuffer[0x43]; 422:dsk.c **** /* Extended BPB signature, offset differs for FAT32 vs FAT12/16 */ 423:dsk.c **** extended_BPB_signature = DiskTransferBuffer[0x42]; 424:dsk.c **** } 425:dsk.c **** else 426:dsk.c **** #endif 427:dsk.c **** extended_BPB_signature = DiskTransferBuffer[0x26]; 428:dsk.c **** 429:dsk.c **** /* 0x29 is usual signature value for serial#,vol label,& fstype; 430:dsk.c **** 0x28 older EBPB signature indicating only serial# is valid */ 431:dsk.c **** if ((extended_BPB_signature == 0x29) || (extended_BPB_signature == 0x28)) 432:dsk.c **** { 433:dsk.c **** pddt->ddt_serialno = getlong(&fs->serialno); 434:dsk.c **** } else { 435:dsk.c **** /* short BPB, no serial # available */ 436:dsk.c **** pddt->ddt_serialno = 0; 437:dsk.c **** } 438:dsk.c **** if (extended_BPB_signature == 0x29) 439:dsk.c **** { 440:dsk.c **** fmemcpy(pddt->ddt_volume, fs->volume, sizeof fs->volume); GAS LISTING /tmp/cck0ihkU.s page 11 441:dsk.c **** fmemcpy(pddt->ddt_fstype, fs->fstype, sizeof fs->fstype); 442:dsk.c **** } else { 443:dsk.c **** /* earlier extended BPB or short BPB, fields not available */ 444:dsk.c **** fmemcpy(pddt->ddt_volume, "NO NAME ", 11); 445:dsk.c **** fmemcpy(pddt->ddt_fstype, "FAT?? ", 8); 446:dsk.c **** } 447:dsk.c **** } 448:dsk.c **** 449:dsk.c **** #ifdef DSK_DEBUG 450:dsk.c **** printf("BPB_NBYTE = %04x\n", pbpbarray->bpb_nbyte); 451:dsk.c **** printf("BPB_NSECTOR = %02x\n", pbpbarray->bpb_nsector); 452:dsk.c **** printf("BPB_NRESERVED = %04x\n", pbpbarray->bpb_nreserved); 453:dsk.c **** printf("BPB_NFAT = %02x\n", pbpbarray->bpb_nfat); 454:dsk.c **** printf("BPB_NDIRENT = %04x\n", pbpbarray->bpb_ndirent); 455:dsk.c **** printf("BPB_NSIZE = %04x\n", pbpbarray->bpb_nsize); 456:dsk.c **** printf("BPB_MDESC = %02x\n", pbpbarray->bpb_mdesc); 457:dsk.c **** printf("BPB_NFSECT = %04x\n", pbpbarray->bpb_nfsect); 458:dsk.c **** #endif 459:dsk.c **** 460:dsk.c **** count = 461:dsk.c **** pbpbarray->bpb_nsize == 0 ? 462:dsk.c **** pbpbarray->bpb_huge : pbpbarray->bpb_nsize; 463:dsk.c **** secs_per_cyl = pbpbarray->bpb_nheads * pbpbarray->bpb_nsecs; 464:dsk.c **** 465:dsk.c **** if (secs_per_cyl == 0) 466:dsk.c **** { 467:dsk.c **** tmark(pddt); 468:dsk.c **** return failure(E_FAILURE); 469:dsk.c **** } 470:dsk.c **** /* this field is problematic for partitions > 65535 cylinders, 471:dsk.c **** in general > 512 GiB. However: we are not using it ourselves. */ 472:dsk.c **** pddt->ddt_ncyl = (UWORD)((count + (secs_per_cyl - 1)) / secs_per_cyl); 473:dsk.c **** 474:dsk.c **** tmark(pddt); 475:dsk.c **** 476:dsk.c **** #ifdef DSK_DEBUG 477:dsk.c **** printf("BPB_NSECS = %04x\n", pbpbarray->bpb_nsecs); 478:dsk.c **** printf("BPB_NHEADS = %04x\n", pbpbarray->bpb_nheads); 479:dsk.c **** printf("BPB_HIDDEN = %08lx\n", pbpbarray->bpb_hidden); 480:dsk.c **** printf("BPB_HUGE = %08lx\n", pbpbarray->bpb_huge); 481:dsk.c **** #endif 482:dsk.c **** 483:dsk.c **** return 0; 484:dsk.c **** } 485:dsk.c **** 486:dsk.c **** STATIC WORD bldbpb(rqptr rp, ddt * pddt) 487:dsk.c **** { 488:dsk.c **** WORD result; 489:dsk.c **** 490:dsk.c **** if ((result = getbpb(pddt)) != 0) 491:dsk.c **** return result; 492:dsk.c **** 493:dsk.c **** rp->r_bpptr = &pddt->ddt_bpb; 494:dsk.c **** return S_DONE; 495:dsk.c **** } 496:dsk.c **** 497:dsk.c **** STATIC WORD IoctlQueblk(rqptr rp, ddt * pddt) GAS LISTING /tmp/cck0ihkU.s page 12 498:dsk.c **** { 73 .loc 1 498 0 74 _.LVL4: 75 0038 55 push bp 76 _.LCFI3: 77 0039 89E5 mov bp, sp 78 _.LCFI4: 79 003b 1E push ds 499:dsk.c **** UNREFERENCED_PARAMETER(pddt); 500:dsk.c **** 501:dsk.c **** #ifdef WITHFAT32 502:dsk.c **** if (rp->r_cat == 8 || rp->r_cat == 0x48) 80 .loc 1 502 0 81 003c C45E04 les bx, dword ptr [bp+4] 82 003f 268A470D mov al, byte ptr es:[bx+13] 83 0043 8846FF mov byte ptr [bp-1], al 84 0046 24BF and al, -65 85 0048 3C08 cmp al, 8 86 004a 7510 jne _.L15 503:dsk.c **** #else 504:dsk.c **** if (rp->r_cat == 8) 505:dsk.c **** #endif 506:dsk.c **** { 507:dsk.c **** switch (rp->r_fun) 87 .loc 1 507 0 88 004c 268A470E mov al, byte ptr es:[bx+14] 89 0050 3C60 cmp al, 96 90 0052 7415 je _.L16 91 0054 770F ja _.L14 92 0056 04BA add al, -70 93 _.L22: 94 0058 3C01 cmp al, 1 95 005a 760D jbe _.L16 96 _.L15: 508:dsk.c **** { 509:dsk.c **** case 0x46: 510:dsk.c **** case 0x47: 511:dsk.c **** case 0x60: 512:dsk.c **** case 0x66: 513:dsk.c **** case 0x67: 514:dsk.c **** return S_DONE; 515:dsk.c **** } 516:dsk.c **** } 517:dsk.c **** return failure(E_CMD); 97 .loc 1 517 0 98 005c B80381 mov ax, -32509 99 _.L11: 518:dsk.c **** } 100 .loc 1 518 0 101 005f 89EC mov sp, bp 102 0061 5D pop bp 103 0062 C20600 ret 6 104 _.L14: