Системное программное обеспечение персональных ЭВМ

byte drive, flag; union VAR



Пример 18

/*== ПРИМЕР 13.5 ==*/ /*======= Карта буферов дискового ввода/вывода DOS =======*/ #define byte unsigned char #define word unsigned int #define dword unsigned long #include <dos.h> #define V(x) (dos>3)?bcb->var.var5.x:bcb->var.var3.x struct BCB { /* Управляющий блок буфера */ union PTR { struct BCB *next3; struct { word next, prev; } next5; } ptr; byte drive, flag; union VAR { struct VAR3 { word sect; byte copies, sect_off; void *dpb; } var3; struct VAR5 { dword sect; byte copies; word sect_off; void *dpb; } var5; }var; } *bcb, *bcb0; word bbc_seg, bbc_off; /* адрес CVT */ word bseg, boff; /* адрес 1-го буфера */ int nbuf; /* счетчик */ byte dos; /* версия DOS */ union REGS rr; struct SREGS sr; main() { /* получение версии */ rr.h.ah=0x30; intdos(&rr,&rr); dos=rr.h.al; /* получение адреса CVT */ rr.h.ah=0x52; intdosx(&rr,&rr,&sr); bseg=sr.es; boff=rr.x.bx; printf("\nТаблица буферов\n"); printf("Pазмер буфера = %u\n",peek(bseg,boff+16)); /* адрес 1-го буфера */ bbc_off=peek(bseg,boff+0x12); bbc_seg=peek(bseg,boff+0x14); bcb=(struct BCB *)MK_FP(bbc_seg,bbc_off); if (dos>3) /* еще одна адресация */ bcb0=bcb=bcb->ptr.next3; for (nbuf=1;;nbuf++) { printf("\nБУФЕР #%-2d",nbuf); printf(" Адр.BCB=%Fp",bcb); if (dos>3) printf(", след.=%04X, пред.=%04X",bcb->ptr.next5.next,bcb->ptr.next5.prev); printf(", адр.DPB=%Fp\n",V(dpb)); printf(" диск=%d(%c),", bcb->drive,'A'+bcb->drive); printf(" сектор="); if (dos>3) printf("%lu",V(sect)); else printf("%u",V(sect)); printf(", копий=%d, смещение=%u\n",V(copies),V(sect_off)); printf(" флаг состояния=%02X\n",bcb->flag); if (getch()==27) exit(); /* переход к следующему BCB в списке */ if (dos>3) { /* старый сегмент : новое смещение */ bcb=(struct BCB *)MK_FP(FP_SEG(bcb),bcb->ptr.next5.next); /* выход из цикла, если кольцо замкнулось */ if (bcb==bcb0) break; } else { /* полный адрес выбирается из next */ bcb=bcb->ptr.next3; /* выход из цикла по признаку конца списка */ if (FP_OFF(bcb)==0xffff) break; } } }
Применение этой программы "в чистом виде", как и в предыдущем примере, не может дать интересных результатов. Гораздо интереснее оформить ее в виде функции и вызывать эту функцию из программы, работающей с файлом (или с файлами) после каждой операции чтения/записи, что мы и делали в процессе экспериментирования. Особенно показательными будут результаты ее, если включить в ее состав функцию, определяющую по номеру сектора имя файла, которому этот сектор принадлежит - все необходимые для этого средства читатель получил в главе 10, так что, надеемся, он справится с этой задачей самостоятельно.

Содержание раздела