/* Searches the buffer at buff of length len for character chr. Returns pointer to first occurrence of chr in buff or NULL if chr is not in buff. NOTE: This could be done with 1 CPIR instruction in machine code. Write one. */ #include char *index(buff,len,chr) char *buff,chr; unsigned len; { char *last; last = buff + len; /* sentinel beyond buffer */ while(*buff != chr) if(++buff == last)return(NULL); return(buff); } /* Searches buffer buff of length len for first character which does not match character chr. Returns a pointer to first such character or NULL if no such character exists. */ char *nindex(buff,len,chr) char *buff,chr; unsigned len; { char *last; last = buff + len; /* sentinel beyond buffer */ while(*buff == chr) if(++buff == last)return(NULL); return(buff); } /* Removes all occurrnces of character chr from the buffer buff of length len, shrinking the buffer. Returns the new buffer length. */ unsigned compress(buff,len,chr) char *buff,chr; unsigned len; { char *tp1,*tp2; unsigned tplen; /* first check if chr exists in buffer */ if((tp1 = index(buff,len,chr)) == NULL) return(len); /* No, return original length */ /* find next non-chr character */ /* if none exists, tp1 is boundary of new buffer */ if((tp2 = nindex(tp1,len-(tp1-buff),chr)) == NULL) return(tp1-buff); /* close gap, recursively compressing the remainder */ /* of buff from tp2 on. Isn't recursion neat? */ movmem(tp2,tp1,tplen=compress(tp2,len-(tp2-buff),chr)); return(tplen + (tp1 - buff)); } /* Reads nsec sectors from drive disk starting at track trk, sector sctr to address buff. Returns number of sectors successfully read. Note: Assumes you have enough space at buff to hold everything. If not, it will write over whatever else is beyond. Use with caution. */ rdsecs(disk,trk,sctr,nsec,buff) char disk,trk,sctr,*buff; int nsec; { int count; count = 0; bios(SELECT_DISK,disk); while(nsec--){ bios(SET_DMA,buff); bios(SET_TRACK,trk); bios(SET_SECTOR,sctr); if(bios(READ_SECTOR) == 255) return(count); count++; if(++sctr > 26){ sctr = 1; trk++; } if(trk > 76)return(count); buff += SECSIZ; } } /* Writes nsec sectors to drive disk starting at track trk, sector sctr from address buff. Returns number of sectors successfully written. Use with caution. */ wrtsecs(disk,trk,sctr,nsec,buff) char disk,trk,sctr,*buff; int nsec; { int count; count = 0; bios(SELECT_DISK,disk); while(nsec--){ bios(SET_DMA,buff); bios(SET_TRACK,trk); bios(SET_SECTOR,sctr); if(bios(WRITE_SECTOR) == 255) return(count); if(++sctr > 26){ sctr = 1; trk++; } if(trk > 76)return(count); count++; buff += SECSIZ; } } /* Cursor positioning for the H19; gotoxy(x,y,c) where 1<=x<=25, 1<=y<=80 and c is a string pointer. This function is also in DEFF.CRL. NOTE: the 25th line must be separately enabled. Also, no attempt is made to ensure that x and y are in the proper range. */ gotoxy(line,column,string) int line,column; char *string; { line--; column--; puts("\033Y"); putchar(line+0x20); putchar(column+0x20); puts(string); }