NEW AUTO 3,1 *-------------------------------------- ZPMemMgrSPtr .EQ ZPMEMMGR Pointer To Slot selected ZPMemMgrTmp1 .EQ ZPMEMMGR+2 ZPMemMgrSize .EQ ZPMEMMGR+4 MEM.ReqFlags .EQ ZPMEMMGR+6 store requested Flags MEM.BestSlot .EQ ZPMEMMGR+7 MEM.BestScore .EQ ZPMemMgrTmp1 */-------------------------------------- * # Realloc * ## C * `void *realloc(short int hMem, int size);` * ## ASM * `>PUSHB hMem` * `>PUSHW size` * `>SYSCALL realloc` * ## RETURN VALUE * YA = ptr * X = hMem *\-------------------------------------- K.Realloc >PULLA sta .1+1 New Size LO >PULLA sta .2+1 New Size HI >PULLA Src hMem tax jsr MEM.GetMemByID ldy #S.MEM.LEN lda (ZPMemMgrSPtr),y pha iny lda (ZPMemMgrSPtr),y ply jsr MEM.MoveToAux x = Src hMem, YA = Old size bcs .99 stx .7+1 Aux hMem .1 ldy #$FF SELF MODIFIED .2 lda #$FF SELF MODIFIED >STYA A2L size for MoveSetupA1A2 jsr K.getmem bcs .99 stx .8+1 new main hMem to return >STYA A4L Save MAIN Ptr lda .7+1 sta IO.SETREADAUX jsr MEM.SetA1A2 Setup AUX base & End Ptrs sta IO.CLRREADAUX clc Aux To Main jsr XMov .7 lda #$ff SELF MODIFIED >SYSCALL2 FreeStkObj .8 lda #$ff SELF MODIFIED tax X = new hMem jmp k.GetMemPtr YA = new ptr .99 rts */-------------------------------------- * # GetMem * Y,A = Size Requested * ## RETURN VALUE * CC : success * YA = PTR to Mem (Uninitialised) * X = hMem * CS : * A = EC *\-------------------------------------- K.GetMem0 ldx #S.MEM.F.INIT0 .HS 2C BIT ABS K.GetMem ldx #0 MEM.GetMem.YAX stx MEM.ReqFlags sta ZPMemMgrSize+1 tya bit #K.MEM.ALIGN-1 aligned ? beq .10 yes, request it and #K.MEM.nALIGNm1 align on boundary clc adc #K.MEM.ALIGN bcc .10 inc ZPMemMgrSize+1 .10 sta ZPMemMgrSize >LDYAI Mem.Table >STYA ZPMemMgrSPtr stz MEM.BestSlot ldx #$ff stx MEM.BestScore stx MEM.BestScore+1 ldx #0 Current slot=0 bra .4 skip slot 0, Check if some free slot to reuse first .1 inx move to next slot jsr Mem.NextSlot lda (ZPMemMgrSPtr) Get Flags bmi .4 in use ? .2 lda MEM.ReqFlags Found an empty slot bit #S.MEM.F.NOCROSS beq .21 ldy ZPMemMgrSize+1 > 255, not applicable bne .22 Align to page if $100 ldy #S.MEM.PTR lda (ZPMemMgrSPtr),y get LO of PTR clc adc ZPMemMgrSize bcs .4 cross page boundary.... lda MEM.ReqFlags get back flags to test if match .21 bit #S.MEM.F.ALIGN is request needs a page align ? beq .3 .22 ldy #S.MEM.PTR lda (ZPMemMgrSPtr),y get LO of PTR bne .4 not page-aligned .3 ldy #S.MEM.LEN sec lda (ZPMemMgrSPtr),y get LEN of this block sbc ZPMemMgrSize compare with requested size pha iny lda (ZPMemMgrSPtr),y sbc ZPMemMgrSize+1 ply Y,A = SlotLen - ReqSize bcc .4 req size > slot size cpy MEM.BestScore pha sbc MEM.BestScore+1 pla bcs .4 Delta is >= BestScore bne .4 Delta is > 255... sty MEM.BestScore sta MEM.BestScore+1 stx MEM.BestSlot .4 cpx Mem.LastSlot any other slot to check? bne .1 last one, create a new slot lda MEM.BestSlot beq .5 tax jsr MEM.GetMemByID bra .7 *-------------- Create a New SLOT .5 lda MEM.ReqFlags bit #S.MEM.F.NOCROSS beq .51 lda ZPMemMgrSize+1 > 255, not applicable bne .52 Align to page if $100 lda Mem.Free target PTR will be in same page ? beq .6 Memfree is xx00, will be in same page cmp ZPMemMgrSize bcs .6 yes, allocate tay no, reserve a free slot to fill gap lda #0 jsr Mem.AddSlot X = new slot bcs .9 lda #S.MEM.F.NOCROSS Make sure marked FREE sta (ZPMemMgrSPtr) bra .6 .51 bit #S.MEM.F.ALIGN is request needs a page align ? beq .6 .52 lda Mem.Free target PTR will be page aligned ? sec sbc ZPMemMgrSize beq .6 yes, allocate tay no, reserve a free slot to fill gap lda #0 jsr Mem.AddSlot X = new slot bcs .9 lda #S.MEM.F.ALIGN Make sure marked FREE sta (ZPMemMgrSPtr) .6 >LDYA ZPMemMgrSize jsr Mem.AddSlot X = new slot bcs .9 *-------------- Reuse this SLOT .7 lda MEM.ReqFlags get requested flags ora #S.MEM.F.INUSE mark as in use sta (ZPMemMgrSPtr) and #S.MEM.F.INIT0 beq .8 jsr MEM.Init0 .8 lda #0 ldy #S.MEM.BIN sta (ZPMemMgrSPtr),y inc Mark this slot used by one process ldy #S.MEM.REFCNT sta (ZPMemMgrSPtr),y lda IO.RDREADAUX pha sta IO.CLRREADAUX ldy #S.PS.PID lda (pPS),y ldy #S.MEM.OWNERPID sta (ZPMemMgrSPtr),y pla bpl .80 sta IO.SETREADAUX .80 clc jmp MEM.GetMEMPTR * A = HI PTR,Y = LO PTR,X = Current hMem .9 rts *-------------------------------------- * Mem.AddSlot * In: * Y,A = Requested size * Out: *-------------------------------------- Mem.AddSlot >STYA ZPMemMgrTmp1 save req size ldx Mem.LastSlot inx beq .99 > 255 ERR:OUT OF SLOT lda Mem.Free Compute base PTR=FREE-REQ size sec sbc ZPMemMgrTmp1 tay save new Mem.Free LO lda Mem.Free+1 sbc ZPMemMgrTmp1+1 pha save new Mem.Free HI cpy Mem.LoMem sbc Mem.LoMem+1 bcc .98 ERR out of mem jsr Mem.NextSlot X,Y unmodified tya get back Mem.Free LO ldy #S.MEM.PTR sta Mem.Free set as system Mem.Free value sta (ZPMemMgrSPtr),y store it as base address of new slot iny pla get back Mem.Free HI sta Mem.Free+1 sta (ZPMemMgrSPtr),y iny lda ZPMemMgrTmp1 get requested size sta (ZPMemMgrSPtr),y setup slot LEN iny lda ZPMemMgrTmp1+1 sta (ZPMemMgrSPtr),y stx Mem.LastSlot mark this slot allocated clc rts .98 pla discard new Mem.Free HI .99 lda #E.OOM sec rts *-------------------------------------- MEM.NextSlot lda ZPMemMgrSPtr clc adc #S.MEM sta ZPMemMgrSPtr bcc .8 inc ZPMemMgrSPtr+1 .8 rts *-------------------------------------- MEM.Init0 phx ldy #S.MEM.PTR lda (ZPMemMgrSPtr),y ZPMemMgrSPtr already set sta .12+1 iny lda (ZPMemMgrSPtr),y sta .12+2 lda ZPMemMgrSize eor #$ff tay y=not lo count lda ZPMemMgrSize+1 eor #$ff a=not hi count ldx #0 .11 iny bne .12 inc beq .13 .12 stz $ffff,x inx bne .11 inc .12+2 bra .11 .13 plx rts *-------------------------------------- DEV.FreeFD.8 clc rts DEV.FreeFD ldx IO.hFD lda FDs.pHI-1,x cmp #$C0 bcs DEV.FreeFD.8 stz FDs.pHI-1,x ldy FDs.pLO-1,x */-------------------------------------- * # Free * Y,A = Ptr To Free * ## RETURN VALUE * none. * (X unmodified) *\-------------------------------------- K.Free >STYA ZPMemMgrTmp1 ldx Mem.LastSlot .1 txa jsr MEM.GetMemByID ldy #S.MEM.PTR lda (ZPMemMgrSPtr),y cmp ZPMemMgrTmp1 bne .2 iny lda (ZPMemMgrSPtr),y cmp ZPMemMgrTmp1+1 beq MEM.FreeMem .2 dex bne .1 sec rts */-------------------------------------- * # FreeMem * A = hMem To Free * ## RETURN VALUE * none. * (X unmodified) *\-------------------------------------- K.FreeMem.ERR >PUSHWI .1 tya hMem n Y >PUSHA ldy #S.PS.PID lda (pPS),y >PUSHA >PUSHBI 2 >SYSCALL2 PrintF * >DEBUG lda #E.INVH sec rts .1 .CZ "Free(%h),PID=%d\r\n" *-------------------------------------- K.FreeMem tay beq K.FreeMem.ERR Slot=0, reserved by Kernel cmp Mem.LastSlot bcc .1 bne K.FreeMem.ERR .1 jsr MEM.GetMemByID X,Y unmodified *-------------------------------------- MEM.FreeMem lda (ZPMemMgrSPtr) In use ? bpl K.FreeMem.ERR ldy #S.MEM.REFCNT lda (ZPMemMgrSPtr),y dec only one left ? sta (ZPMemMgrSPtr),y bne .8 no, must be a code segment loaded several times lda (ZPMemMgrSPtr) and #$7f keep flags for memdump sta (ZPMemMgrSPtr) Mark as FREE and #S.MEM.F.CODE CS: Any BINPATH to discard ? beq .1 ldy #S.MEM.BIN lda (ZPMemMgrSPtr),y jsr MEM.GetMemByID X unmodified * lda (ZPMemMgrSPtr) * bpl * ***MUST BE ALLOCATED*** lda #0 mark BINPATH slot as free sta (ZPMemMgrSPtr) .1 lda Mem.LastSlot beq .8 jsr MEM.GetMemByID X unmodified lda (ZPMemMgrSPtr) bmi .8 used, exit .2 dec Mem.LastSlot free! get previous.... beq .80 empty list: go set Mem.Free=Mem.HiMem lda Mem.LastSlot jsr MEM.GetMemByID X unmodified lda (ZPMemMgrSPtr) bpl .2 free again! loop ldy #S.MEM.PTR lda (ZPMemMgrSPtr),y set Mem.Free... sta Mem.Free iny lda (ZPMemMgrSPtr),y sta Mem.Free+1 .8 clc rts .80 >LDYA Mem.HiMem >STYA Mem.Free clc rts */-------------------------------------- * # GetMemPtr * A = hMem * ## RETURN VALUE * Y,A = PTR to MemBlock * (X unmodified) *\-------------------------------------- * Optimized for : * Mem.Table is page aligned at $800 * S.MEM is 8 bytes *-------------------------------------- .DO Mem.Table=$800 .ELSE !!!!!WARNING!!!!! .FIN .DO S.MEM=8 .ELSE !!!!!WARNING!!!!! .FIN *-------------------------------------- K.GetMemPtr jsr MEM.GetMemByID MEM.GetMEMPTR ldy #S.MEM.PTR lda (ZPMemMgrSPtr),y pha iny lda (ZPMemMgrSPtr),y ply rts *-------------------------------------- MEM.GetMemByID sta ZPMemMgrSPtr lda /Mem.Table/8 asl ZPMemMgrSPtr rol asl ZPMemMgrSPtr rol asl ZPMemMgrSPtr rol sta ZPMemMgrSPtr+1 rts *-------------------------------------- Mem.SetOwner lda CORE.LastPSID .HS 2C BIT ABS Mem.SetOwnerPS0 lda #0 ldy #S.MEM.OWNERPID sta (ZPMemMgrSPtr),y rts *-------------------------------------- Mem.IncRefCnt ldy #S.MEM.REFCNT lda (ZPMemMgrSPtr),y inc sta (ZPMemMgrSPtr),y rts */-------------------------------------- * # NewStkObj * Y,A = Size Requested * ## RETURN VALUE * CC : success * YA = PTR to Mem (Uninitialised) * X = hMem * CS : * A = EC *\-------------------------------------- */-------------------------------------- * # GetStkObjPtr * ## ASM * `lda hStkObj` * `>SYSCALL GetStkObjPtr` * ## RETURN VALUE *\-------------------------------------- */-------------------------------------- * # FreeStkObj * A = hMem To Free (AUX Memory) * ## RETURN VALUE * none. * (X,Y unmodified) *\-------------------------------------- *-------------------------------------- MEM.DupX sta IO.SETREADAUX sta IO.SETWRITEAUX jsr MEM.Dup sta IO.CLRREADAUX sta IO.CLRWRITEAUX rts *-------------------------------------- MEM.Dup jsr K.GetMemPtr >STYA A1L ldy #S.MEM.LEN lda (ZPMemMgrSPtr),y pha eor #$ff sta A4L iny lda (ZPMemMgrSPtr),y eor #$ff sta A4L+1 eor #$ff ply MEM.DupA1LnA4L jsr K.GetMem bcs MEM.Dup.RTS >STYA A2L ldy #0 .1 inc A4L bne .2 inc A4L+1 beq .8 .2 lda (A1L),y sta (A2L),y iny bne .1 inc A1L+1 inc A2L+1 bra .1 .8 txa * clc MEM.Dup.RTS rts *-------------------------------------- MEM.CopyToMain clc .HS B0 BCS MEM.MoveToMain sec ror .1+1 stx .2+1 Save AUX hMem >STYA A2L Save LEN to copy/move sta IO.CLRREADAUX Make sure MAIN !!!! sta IO.CLRWRITEAUX jsr K.GetMem bcs MEM.Dup.RTS stx .8+1 Save MAIN hMem >STYA A4L Save MAIN Ptr lda .2+1 Get AUX mem Ptr sta IO.SETREADAUX jsr MEM.SetA1A2 Setup AUX base & End Ptrs sta IO.CLRREADAUX clc Aux To Main jsr XMov .1 lda #$ff SELF MODIFIED bpl .8 Copy : dont discard AUX mem .2 lda #$ff SELF MODIFIED >SYSCALL2 FreeStkObj release AUX mem .8 ldx #$ff Returns MAIN hMem txa jmp K.GetMemPtr Y,A = Ptr *-------------------------------------- MEM.MoveToAux stx .1+1 Save MAIN hMem >STYA A2L Save LEN to move >SYSCALL2 NewStkObj bcs .9 stx .8+1 Save AUX hMem >STYA A4L Save AUX Ptr lda .1+1 jsr MEM.SetA1A2 Setup MAIN base & End Ptrs sec Main To Aux jsr XMov .1 lda #$ff SELF MODIFIED jsr K.FreeMem release MAIN memory .8 ldx #$ff Returns AUX hMem * clc .9 rts *-------------------------------------- MEM.SetA1A2 jsr K.GetMemPtr >STYA A1L Start Address pha tya clc adc A2L tay pla adc A2L+1 sta A2L+1 tya bne .1 dec A2L+1 .1 dey sty A2L rts *-------------------------------------- MEM.GetKBuf pha tya clc adc DevMgr.Free tax pla adc DevMgr.Free+1 bcs .99 we crossed $FFFF, out of mem cpx #DevMgr.HiMem pha sbc /DevMgr.HiMem pla bcs .99 No More Room... ldy DevMgr.Free stx DevMgr.Free ldx DevMgr.Free+1 sta DevMgr.Free+1 txa * clc rts .99 lda #E.OOM * sec rts *-------------------------------------- MAN SAVE usr/src/sys/kernel.s.mem LOAD usr/src/sys/kernel.s ASM