#include #include extern char backup_drive; extern char * baum_array, * baum_ptr; extern int modus, blocksize, sectorsize, filecount; extern int /* vorsicht,*/ drive, version, dir_counter, timestamps; extern unsigned max_bytes; extern struct dpb disk; extern struct knoten *baum; extern struct dir_eintrag **array, *directory; extern FILE datei; struct entry erased={0xe5}; struct entry sfcb={0x21}; int sect_anzahl; /* Anzahl der Directory-Sektoren von read_dir ermittelt */ int enthaltene_eintraege(buffer) char *buffer; { int count=0; int i=0; for (;inext) /* alle extents durchgehen */ { move( &(ptr->eintrag),walker,32); walker+=32; ++a_reg; if (timestamps) { int sfcboffs=64 - ( (walker-32-buffer) MOD 128); char *ziel=walker+sfcboffs+1+10 * (a_reg-1); move( &(ptr->time),ziel,10); if (a_reg==3 ) { *walker=0x21; *(walker+31)=0; walker+=32; a_reg=0; } } if (walker>=(buffer+sectorsize)) { writesector(buffer,nr); ++nr; --dirsektoren; walker=buffer; } } } while(dirsektoren--) /* rest auffuellen mit erased */ { while(walker<(buffer+sectorsize)) { move(erased,walker,32); ++a_reg; if (timestamps && a_reg==4) { a_reg=0; move(sfcb,walker,32); } walker+=32; } writesector(buffer,nr); ++nr; walker=buffer; } cfree(buffer); } read(buffer,blocknr) char *buffer; unsigned int blocknr; { common(buffer,blocknr,0); } write(buffer,blocknr) char *buffer; unsigned int blocknr; { #ifdef vorsicht error ("nicht auf Harddisk !!!"); #endif common(buffer,blocknr,1); } readsector(buffer,sectornummer) char *buffer; unsigned int sectornummer; { common(buffer,sectornummer,2); } writesector(buffer,sectornummer) char *buffer; unsigned int sectornummer; { #ifdef vorsicht error ("nicht auf Harddisk !!!"); #endif common(buffer,sectornummer,3); } common(buffer,blocknr,operation) char *buffer; unsigned int blocknr; int operation; { static int erro,anzahl; static unsigned int track,sector,sectornr,faktor; anzahl= (operation < 2) ? (blocksize DIV sectorsize) : 1; if (version==3) { bios_a(23,0,anzahl,0); /* multisectorcount setzen */ bios_a(28,1,0,0); /* dma-bank=1 */ } sectornr=blocknr*anzahl; faktor=disk.spt/potenz2(disk.psh); while (anzahl--) /* ein block=mehrere Sektoren */ { static int skew_table; static int dph; dph=bios_hl(9,0,drive-1,1); /* select disk */ if (!dph) error("inv sort drive"); skew_table=get_byte(dph)+256*get_byte(dph+1); bios_a(12,0,buffer,0); /* set dma adress */ track=sectornr DIV faktor; sector=sectornr MOD faktor; sector=bios_hl(16,0,sector,skew_table); /* translate sector */ track+=disk.off; bios_a(10,0,track,0); /* set track */ bios_a(11,0,sector,0); /* set sector */ if (operation MOD 2) { if (bios_a(14,0,0,0)) error("write"); } else if (bios_a(13,0,0,0)) error("read"); ++sectornr; buffer+=sectorsize; } if (version==3) bios_a(23,0,1,0); /* multisectorcount=1 */ } int get_byte(adr) /* holt ein Byte aus Bank 0 */ char *adr; { /* Problem beim Bankswitched cpm 3 : von Bank 1 aus ist die Adresse der Sector-translate-tabelle nicht zu bekommen,weil der Disk parameter Header in Bank 0 residiert.Durch einen Trick ist es aber moeglich,mit Hilfe der Routine SECTRN im BIOS einzelne Bytes aus Bank 0 zu lesen... */ if (adr < 0xF000) error ("Disk Parameter Header nicht im Common"); return *adr; /* if (version==3) return bios_hl(16,0,0,adr); * nutzt BIOS - SECTRN -Routine * else return *adr; * fuer cpm2 * */ }