TITL "The Free Space Utility" * * * THE FREE SPACE UTILITY * * DETERMINES HOW MANY BLOCKS OF A SPECIFIED SIZE CAN BE * ALLOCATED ON A SPECIFIED UNIT. * * ON ENTRY: HL - DESIRED BLOCK SIZE * A - UNIT # (IN ASCII) * IF A IS 00H THEN THE DEFAULT UNIT IS USED. * * ON EXIT: HL HAS MAXIMUM NUMBER OF BLOCKS THAT COULD BE * ALLOCATED. * ALL OTHER REGISTERS ARE UNDEFINED. * * TRACKS EQU 77 NUMBER OF TRACKS COVERED BY THE FREE SPACE MAP. * * THE PROGRAM ASSUMES THAT THERE ARE 16 SECTORS PER TRACK. * FIRSTSECTOR EQU 100H NUMBER OF DATA BYTES IN THE 1ST SECTOR OF * A BLOCK. OTHERSECTORS EQU 140H NUMBER OF DATA BYTES IN SECTORS OTHER * THAN THE FIRST OF A BLOCK. * BLKMAX EQU 0FFFH MAXIMUM ALLOWABLE BLOCK SIZE. MEMEND EQU 0C000H END OF SYSTEM MEMORY. PROGRAM CANNOT EXTEND * BEYOND THIS ADDRESS. * * COPY NPTDEFS PTDOS SYSTEM DEFINITIONS. * * ORG CXBUF SO AS NOT TO GET IN THE WAY OF OTHER PROGRAMS. XEQ CXBUF START FROM THE TOP. * * * CHECK THE ARGUMENTS FOR VALIDITY AND SET THE UNIT * ORA A SEE IF THE DEFAULT UNIT IS DESIRED ( IS A = 0 ?) JNZ SETUNIT NOPE, ONE OF THEIR OWN CHOOSING. * STA SLASH PUT A ZERO ON TOP OF THE SLASH AFTER "FSMAP" SO JMP CHECKSIZE THAT THE DEFAULT UNIT IS USED. * SETUNIT STA UNIT PUT THE ASCII UNIT DIRECTLY IN THE NAME. * CHECKSIZE MOV A,H CHECK THE BLOCK SIZE FOR LEGAL VALUES. ORA L CAN'T HAVE A SIZE OF 0. JZ ARGERROR * XCHG . PUT BLOCK SIZE IN DE FOR SAFE KEEPING. LXI H,-BLKMAX-1 SUBTRACT THE MAXIMUM BLOCK SIZE, FUDGED. DAD D JC ARGERROR BLOCK SIZE WAS TOO BIG. * * DETERMINE HOW MANY SECTORS FOR A BLOCK OF THIS SIZE * XCHG . PUT THE BLOCK SIZE BACK IN HL. DCX H FUDGE IT SO THAT THE CARRY WILL COME OUT RIGHT. MVI B,1 INTITALIZE THE SECTOR COUNT. LXI D,-FIRSTSECTOR SUBTRACT OFF THE 1ST SECTOR SIZE. DAD D JNC SAVESECT ONLY 1 SECTOR FOR THIS BLOCK. * LXI D,-OTHERSECTORS LOOP SUBTRACTING OUT SECTOR SIZES SUBLOOP DAD D SUBTRACT THROUGH ADDING INR B ADD ANOTHER SECTOR TO OUR COUNT. JC SUBLOOP STILL MORE TO GO. * SAVESECT MOV A,B PUT COUNT OF SECTORS WHERE WE WON'T LOSE IT. STA SECTCOUNT * * READ IN THE FREE SPACE MAP * FSMOPEN LXI D,FSMNAME POINT TO THE NAME. LXI H,0 STATIC BUFFERING CALL SYS OPEN UP! DB OPEOP JMP PTDERROR * STA FINUM SAVE THE FILE NUMBER. LXI B,TRACKS*2 BYTES IN FSMAP (2 BYTES - 16 BITS - PER TRACK) LXI D,MAP WHERE TO READ IT TO. CALL SYS GO GET 'EM! DB RBLOP JMP PTDERROR * LDA FINUM GET THE FILE NUMBER BACK CALL SYS SO THAT WE CAN CLOSE IT. DB CLOOP JMP PTDERROR * * NOW WE LOOK THROUGH THE MAP FOR GROUPS OF CONSECUTIVE SECTORS * ON THE SAME TRACK THAT ARE LARGE ENOUGH TO ACCOMODATE OUR * BLOCK SIZE. * LDA SECTCOUNT PUT THE NUMBER OF SECTORS PER BLOCK MOV B,A INTO B, FOREVER. LXI D,0 * NEWTRACK LHLD POINTER GET THE MAP BYTES FOR THIS TRACK. MOV D,M PUT THEM IN DE FOR NOW. INX H MOV E,M INX H SHLD POINTER UPDATE THE POINTER FOR NEXT TIME. * XCHG . MAP BYTES TO HL, FOR SHIFTING. * TRYAGAIN MOV C,B INTIALIZE THE SECTOR COUNT. * CLEARTEST MOV A,H ANY MORE FREE SECTORS ON THIS TRACK? ORA L CHECK FOR ZERO. JZ NEXTTRACK NO MORE ON THIS TRACK. * DAD H SHIFT THE NEXT BIT INTO THE CARRY. JNC TRYAGAIN BROKE OUR CONSECUTIVE STREAK. * DCR C COUNT DOWN THE NUMBER OF SECTORS NEEDED. JNZ CLEARTEST NOT ENOUGH SECTORS YET. * XCHG . WE GOT ONE! SAVE THE MAP BYTES IN DE. LHLD COUNT KEEP TRACK OF HOW MANY WE FIND. INX H SHLD COUNT XCHG . PUT MAP BYTES BACK INTO HL. JMP TRYAGAIN BACK INTO THE FRAY. * NEXTTRACK LDA LEFT HOW MANY TRACKS LEFT TO CHECK? DCR A ONE LESS NOW. STA LEFT JNZ NEWTRACK MOVE TO THE NEXT TRACK'S MAP BYTES. * * ALL DONE! RETURN WITH COUNT IN HL. * XRA A SET A TO 0 TO INDICATE THAT NO ERROR OCCURED. RETURN POP H ADJUST THE RETURN ADDRESS FOR A GOOD RETURN. INX H MOVE UP TO THE NICE RETURNING POINT. INX H INX H PUSH H PUT THE ADDRESS BACK WHERE WE FOUND IT. * LHLD COUNT WHAT WE FOUND OUT. RET * * * ERRORS COME HERE * ARGERROR MVI A,-1 INDICATE THAT THERE WAS A BAD BLOCK SIZE. JMP RETURN * * PTDOS ERROR * PTDERROR PUSH PSW SAVE THE ERROR NUMBER. LDA FINUM IS THE FSMAP OPEN? CPI 0FFH COMPARE TO INITIAL VALUE. JZ POPERROR * CALL SYS TRY TO CLOSE IT. DB CLOOP NOP . IF WE CAN'T CLOSE IT THEN TOUGH. NOP NOP * POPERROR POP PSW GET ORIGINAL ERROR # BACK. JMP RETURN BACK TO CALLING PROGRAM. * * * STORAGE AREA * POINTER DW MAP INTIALIZE THE MAP POINTER TO THE BEGINNING. COUNT DW 0 WE START OUT WITH NO FREE SPACE. LEFT DB TRACKS ALL OF THE TRACKS ARE STILL LEFT TO CHECK. SECTCOUNT DB 0 HOLDS NUMBER SECTORS TO A BLOCK. FINUM DB 0FFH FILE NUMBER FOR FSMAP. * FSMNAME ASC "FSMAP" OUR SOURCE OF KNOWLEDGE. SLASH DB '/' UNIT SEPARATOR ( MAY GET ZAPPED, HA HA!) UNIT DB 0 THIS GETS OVERWRITTEN BY THE ARGUMENT. DB 0 THE END OF THE NAME. * MAP DS TRACKS*2 THE FREE SPACE MAP LIES HERE. * * IF MEMEND-$/8000H SEE IF THE PROGRAM IS TOO LONG. XXX X PROGRAM IS BIGGER THAN CXBUF! WON'T RUN!!!!!! ENDF . WE GENERATED AN ERROR IF WE ARE TOO LONG. * * END