PAGE 72,128 TITLE BUFRPOOL - GETMAIN/FREEMAIN ROUTINES PAGE .XLIST INCLUDE CCBBS.MAC INCLUDE CCBBS.DEF .LIST ;----------------------------------------------- ;BUFFER POOL DEFINITIONS ;----------------------------------------------- QENXT EQU 0 ;ADDRESS OF NEXT Q ELEMENT QELEN EQU 2 ;LENGTH OF STORAGE AREA QETSK EQU 4 ;ADDRESS OF OWNING TASK QEDLN EQU 6 ;CURRENT DATA LENGTH QEDTA EQU 8 ;START OF DATA ;----------------------------------------------- ;CODE SEGMENT ;----------------------------------------------- CSEG SEGMENT PARA PUBLIC 'CODE' EXTRN ERROR:NEAR,PRGINX:NEAR PUBLIC GETBUF,GETSBF,FREBUF ASSUME CS:CSEG,DS:NOTHING,ES:NOTHING BUFRPOOL PROC NEAR ;------------------------------------------------------ ;BUFFER MANAGEMENT ROUTINES ;------------------------------------------------------ ;--------------------------------------------------------------------- ;GETBUF GET BUFFER SUBROUTINE ;ENTRY: AX REQUESTED LENGTH ;RETURNS: SI A(BUFFER) ;LOCAL: BP-2 FLAGS ; 1 SYSTEM REQUEST ; 2 INDEX PURGE REQUESTED ;--------------------------------------------------------------------- GETBUF: FRAME 1 MOV WORD PTR [BP-2],0 ;USER REQUEST GETB00: PUSH AX PUSH CX PUSH DX PUSH DI PUSH ES ADD AX,15 ;ALLOW FOR HEADER & ROUNDING AND AX,0FFF8H ;ROUND TO DOUBLEWORD BOUNDRY GETB05: MOV DI,OFFSET FAQEHD ;1ST FAQE POINTER ;SCAN FAQE CHAIN FOR AVAILABLE SPACE GETB10: MOV SI,WORD PTR [DI+QENXT] ;NEXT Q ELEMENT CMP SI,OFFSET BFRHD ;IN BUFFER POOL? JNB GETB12 ;YES GETB11: ERR 204H ;BAD FAQE CHAIN GETB12: CMP SI,DS:BFRTL ;IN BUFFER POOL? JNB GETB11 ;NO CMP WORD PTR [SI+QELEN],AX ;ENOUGH SPACE? JAE GETB20 ;YES MOV DI,SI ;PREVIOUS IN CHAIN CMP WORD PTR [SI+QENXT],0 ;ANY MORE? JNZ GETB10 ;YES TEST WORD PTR [BP-2],2 ;ALREADY TRIED PRGINX? JZ GETB15 ;NO - WORTH A TRY ERR 201H GETB15: CALL PRGINX ;FREE UP SOME SPACE OR WORD PTR [BP-2],2 ;SHOW PURGE CALLED JMP GETB05 ;TRY IT AGAIN ;BUILD ALLOCATED QUEUE AREA HEADER GETB20: MOV CX,WORD PTR [SI+QELEN] ;FREE AREA LENGTH MOV WORD PTR [SI+QELEN],AX ;ALLOCATION LENGTH MOV WORD PTR [SI+QETSK],BX ;MARK OWNERSHIP TEST WORD PTR [BP-2],1 ;SYSTEM REQUEST? JZ GETB30 ;NO MOV WORD PTR [SI+QETSK],-1 ;MARK AS SYSTEM TASK GETB30: MOV DX,WORD PTR [SI+QENXT] ;SAVE CHAIN POINTER MOV WORD PTR [SI+QENXT],0 ;CLEAR CHAIN POINTER MOV WORD PTR [SI+QEDLN],0 ;CLEAR DATA LENGTH SUB CX,AX ;REMAINING SPACE JZ GETB40 ;SKIP BUILDING FAQE ;BUILD FAQE IN REMAINING SPACE PUSH SI ADD SI,AX ;POINT TO REMAINING SPACE JB GETB33 ;OVERFLOW CMP SI,DS:BFRTL ;PAST END OF BUFFER POOL? JB GETB35 ;NO PROBLEM GETB33: ERR 204H GETB35: MOV WORD PTR [SI+QELEN],CX ;SIZE OF FREE AREA MOV WORD PTR [SI+QENXT],DX ;POINTER TO NEXT MOV WORD PTR [SI+QETSK],0 ;SHOW UNOWNED MOV WORD PTR [SI+QEDLN],0 ;SHOW EMPTY MOV DX,SI ;NEW FAQE POP SI ;UPDATE POINTER IN PREVIOUS FAQE GETB40: MOV WORD PTR [DI+QENXT],DX ;CURRENT FAQE MOV CX,WORD PTR [SI+QELEN] ;LENGTH OF AREA SUB CX,QEDTA ;LENGTH OF DATA XOR AX,AX ;ZERO ADD SI,QEDTA ;RETURN START OF DATA MOV DI,SI ;START OF DATA PUSH DS POP ES ;TAKE NO CHANCES REP STOSB ;CLEAR ALLOCATED AREA POP ES POP DI POP DX POP CX POP AX CLC ;SHOW GOOD RETURN EXITF ;GET SYSTEM BUFFER ;LIKE GETBUF BUT NOT OWNED BY ANY TASK ; BP-2 FLAGS GETSBF: FRAME 1 MOV WORD PTR [BP-2],1 ;SYSTEM REQUEST JMP GETB00 ;ENTER COMMON CODE ;FREE BUFFER ;CALLED WITH ADDRESS OF BUFFER IN SI FREBUF: OR SI,SI ;ANYTHING JNZ FREB00 ;YES CLC RET ;IGNORE NULL REQUEST FREB00: PUSH SI SUB SI,QEDTA ;POINT TO HEADER CMP WORD PTR [SI+QETSK],BX ;OWNED BY THIS TASK? JZ FREB10 ;YES CMP WORD PTR [SI+QETSK],-1 ;OWNED BY SYSTEM? JZ FREB10 ;OK FOR NOW ERR 202H ;LOG ERROR POP SI STC ;SHOW ERROR RET FREB10: CMP WORD PTR [SI+QELEN],0 ;ZERO LENGTH? JNZ FREB15 ;NO PROBLEM ERR 203H ;LOG ERROR POP SI STC RET FREB15: MOV WORD PTR [SI+QETSK],0 ;SHOW AREA FREE PUSH DI PUSH DX MOV DI,OFFSET FAQEHD ;HEAD OF CHAIN CALL FINDQE ;FIND POSITION IN CHAIN MOV DX,WORD PTR [DI+QENXT] ;NEXT FAQE POINTER MOV WORD PTR [SI+QENXT],DX ;CHAIN FROM NEW FAQE MOV WORD PTR [DI+QENXT],SI ;INSERT IN CHAIN ;TRY TO COMBINE FREE AREAS CMP DI,OFFSET FAQEHD ;FIRST FAQE? JZ FREB20 ;YES MOV DX,DI ;PREVIOUS FAQE ADD DX,WORD PTR [DI+QELEN] ;END OF PREVIOUS FAQE CMP SI,DX ;ARE WE NEXT? JNZ FREB20 ;NO ;COMBINE THIS FAQE WITH PREVIOUS ONE MOV DX,WORD PTR [SI+QELEN] ;THIS AREA LENGTH ADD DX,WORD PTR [DI+QELEN] ;PREVIOUS LENGTH MOV WORD PTR [DI+QELEN],DX ;COMBINED LENGTH MOV DX,WORD PTR [SI+QENXT] ;THIS NEXT FAQE POINTER MOV WORD PTR [DI+QENXT],DX ;PREVIOUS FAQE POINTER MOV SI,DI ;POINT TO COMBINED AREA ;CHECK FOLLOWING AREA FREB20: MOV DI,SI ADD DI,WORD PTR [SI+QELEN] ;POINT PAST THIS AREA CMP DI,WORD PTR [SI+QENXT] ;SAME AS NEXT AREA? JNZ FREBUX ;NO ;COMBINE THIS FAQE WITH FOLLOWING ONE MOV DX,WORD PTR [SI+QELEN] ;THIS LENGTH ADD DX,WORD PTR [DI+QELEN] ;NEXT LENGTH MOV WORD PTR [SI+QELEN],DX ;NEW LENGTH MOV DX,WORD PTR [DI+QENXT] ;NEXT FAQE POINTER MOV WORD PTR [SI+QENXT],DX ;SHOW AS NEXT FREBUX: POP DX POP DI POP SI CLC RET ;FIND BUFFER POSITION IN CHAIN FINDQE: CMP SI,WORD PTR [DI+QENXT] ;INSERT HERE? JB FINDQ1 ;YES - DONE MOV DI,WORD PTR [DI+QENXT] ;NEXT ELEMENT JMP FINDQE ;CHECK AGAIN FINDQ1: RET BUFRPOOL ENDP CSEG ENDS END