PR#3 PREFIX /A2OSX.BUILD LOMEM $A00 INC 1 AUTO 6 *-------------------------------------- * !!!!!! DO NOT USE ZPPtrs !!!!! *-------------------------------------- ZPMemMgrSPtr .EQ ZPMEMMGR Pointer To Slot selected ZPMemMgrTmp1 .EQ ZPMEMMGR+2 Mem.ReqSize .EQ ZPMEMMGR+4 store requested Size Mem.ReqFlags .EQ ZPMEMMGR+6 store requested Flags *-------------------------------------- * TODO : * - Create a 256 bytes table * mapping hMem's to real memory blocks to help * Garbage collector move blocks * - mem.ID=0 always used! useful to test if hMem=0 *-------------------------------------- * PUBLIC */-------------------------------------- * # GetMem * ## In: * PUSHW = Size Requested * PUSHB = Options * S.MEM.F.INIT0 : init memory with 00 * S.MEM.F.ALIGN : page aligned * ## Out: * CC : success * YA = PTR to Mem * X = hMem * CS : * A = EC *\-------------------------------------- K.GetMem >PULLB Mem.ReqFlags store requested flags >PULLA get requested size LO tay >PULLA get requested size HI sta Mem.ReqSize+1 bit Mem.ReqFlags S.MEM.F.AUX ? bpl K.GetMem.I sta SETREADAUX Aux Mem requested,switch to AUX sta SETWRITEAUX jsr K.GetMem.I sta CLRREADAUX sta CLRWRITEAUX rts */-------------------------------------- * # GetMem0.YA * ## In: * Y,A = Size Requested * ## Out: * CC : success * YA = PTR to Mem (ZERO Initialised) * X = hMem * CS : * A = EC *\-------------------------------------- K.GetMem0.YA ldx #S.MEM.F.INIT0 stx Mem.ReqFlags .HS 2C bit abs */-------------------------------------- * # GetMem.YA * ## In: * Y,A = Size Requested * ## Out: * CC : success * YA = PTR to Mem (Uninitialised) * X = hMem * CS : * A = EC *\-------------------------------------- K.GetMem.YA stz Mem.ReqFlags sta Mem.ReqSize+1 K.GetMem.I tya bit #$0F 16 bytes aligned ? beq .10 yes, request it and #$F0 align on 16 bytes clc adc #$10 bcc .10 inc Mem.ReqSize+1 .10 sta Mem.ReqSize >LDYAI Mem.Table >STYA ZPMemMgrSPtr 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 and #S.MEM.F.ALIGN is request needs a page align ? beq .3 ldy #S.MEM.PTR lda (ZPMemMgrSPtr),y get LO of PTR bne .4 not page-aligned .3 ldy #S.MEM.LEN lda (ZPMemMgrSPtr),y get LEN of this block cmp Mem.ReqSize compare with requested size bne .4 iny lda (ZPMemMgrSPtr),y cmp Mem.ReqSize+1 beq .7 requested size matches slot size !!! .4 cpx Mem.LastSlot any other slot to check? bne .1 last one, create a new slot *-------------- Create a New SLOT lda Mem.ReqFlags and #S.MEM.F.ALIGN is request needs a page align ? beq .6 lda Mem.Free target PTR will be page aligned ? sec sbc Mem.ReqSize beq .6 yes, allocate tay no, reserve a free slot to fill gap lda #0 jsr Mem.AddSlot X = new slot bcs .9 .6 >LDYA Mem.ReqSize 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 ldy #S.MEM.PTR lda (ZPMemMgrSPtr),y ZPMemMgrSPtr already set sta .12+1 iny lda (ZPMemMgrSPtr),y sta .12+2 lda Mem.ReqSize eor #$ff tay y=not lo count lda Mem.ReqSize+1 eor #$ff a=not hi count phx ldx #0 .11 iny bne .12 inc beq .13 .12 stz $ffff,x inx bne .11 inc .12+2 bra .11 .13 plx .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 ldy #S.PS.PID lda (pPs),y ldy #S.MEM.OWNERPID sta (ZPMemMgrSPtr),y ldy #S.MEM.PTR lda (ZPMemMgrSPtr),y pha iny lda (ZPMemMgrSPtr),y A = HI PTR ply Y = LO PTR clc 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 is 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 #K.E.OOM sec rts *-------------------------------------- Mem.NextSlot lda ZPMemMgrSPtr clc adc #S.MEM sta ZPMemMgrSPtr bcc .8 inc ZPMemMgrSPtr+1 .8 rts */-------------------------------------- * # FreeMem.A * ## In: * A = hMem To Free * ## Out: * none. * (X,Y unmodified) *\-------------------------------------- K.FreeMem.A phy tay beq * Slot=0, reserved by Kernel jsr K.GetMemByID.A X unmodified lda (ZPMemMgrSPtr) bpl .9 In use ? ldy #S.MEM.REFCNT lda (ZPMemMgrSPtr),y Get count of those referencing this hMem dec only one left ? sta (ZPMemMgrSPtr),y bne .8 no, must be a code segment loaded several times lda #0 mark this slot as free sta (ZPMemMgrSPtr) ldy #S.MEM.BIN lda (ZPMemMgrSPtr),y Any BINPATH to discard ? beq .1 jsr K.GetMemByID.A X unmodified lda (ZPMemMgrSPtr) bpl * ***MUST BE ALLOCATED*** lda #0 mark BINPATH slot as free sta (ZPMemMgrSPtr) .1 lda Mem.LastSlot beq .8 jsr K.GetMemByID.A X unmodified lda (ZPMemMgrSPtr) bmi .8 used, exit .2 dec Mem.LastSlot free! get previous.... beq .3 empty list: go set Mem.Free=Mem.HiMem lda Mem.LastSlot jsr K.GetMemByID.A 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 ply clc rts .3 >LDYA Mem.HiMem >STYA Mem.Free bra .8 *-------------------------------------- .9 ply discard saved Y lda $D000 sta .91+1 bit RRAMWRAMBNK2 bit RRAMWRAMBNK2 jsr CORE.PSSelect0 Select PS0 for proper I/O devices jsr DevMgr.SYS.Control pla Get PC and sub 2 for calling address sec sbc #2 tay pla sbc #0 >PUSHYA >LDYAI K.FreeMem.A.ERR >SYSCALL PrintF.YA .91 ldx #$ff bit $C000,x bit $C000,x bra * *-------------------------------------- K.FreeMem.A.ERR >CSTR "***MemMgr:Attempt to Free an already freed hMem at $%H" */-------------------------------------- * # GetMemPtr.A * ## In: * A = hMem * ## Out: * Y,A = PTR to MemBlock * (X unmodified) *\-------------------------------------- K.GetMemPtr.A jsr K.GetMemByID.A ldy #S.MEM.PTR lda (ZPMemMgrSPtr),y pha iny lda (ZPMemMgrSPtr),y ply rts */-------------------------------------- * # GetMemByID.A * ## In: * A = hMem * ## Out: * Y,A = ZPMemMgrSPtr = PTR to S.MEM * X unmodified *\-------------------------------------- * Optimized for : * Mem.Table is page aligned at $1800 * S.MEM is 8 bytes *-------------------------------------- .DO Mem.Table=$1800 .ELSE !!!!!WARNING!!!!! .FIN .DO S.MEM=8 .ELSE !!!!!WARNING!!!!! .FIN *-------------------------------------- K.GetMemByID.A sta ZPMemMgrSPtr lda /Mem.Table/8 asl ZPMemMgrSPtr rol asl ZPMemMgrSPtr rol asl ZPMemMgrSPtr rol sta ZPMemMgrSPtr+1 ldy ZPMemMgrSPtr rts *-------------------------------------- * OLD CODE *-------------------------------------- * stz ZPMemMgrSPtr+1 * asl * rol ZPMemMgrSPtr+1 * asl * rol ZPMemMgrSPtr+1 * asl * rol ZPMemMgrSPtr+1 ** clc IMPLICIT * adc #Mem.Table * tay * lda ZPMemMgrSPtr+1 * adc /Mem.Table * sty ZPMemMgrSPtr * sta ZPMemMgrSPtr+1 * rts */-------------------------------------- * # NewStr.YA * Create a new copy of this C-String * ## In: * Y,A = Ptr to source C-String * ## Out: * CC : success * Y,A = PTR to String * X = hMem (PSTR) * CS : error * A = SYS error code *\-------------------------------------- K.NewStr.YA >STYA .1+1 >STYA .4+1 stz Mem.ReqFlags stz Mem.ReqSize+1 ldy #0 .1 lda $ffff,y beq .2 iny bne .1 inc Mem.ReqSize+1 inc .1+2 bne .1 .2 iny Add one for ending 0 bne .3 inc Mem.ReqSize+1 .3 jsr K.GetMem.I bcs .9 >STYA .5+1 phy pha ldy #0 .4 lda $ffff,y .5 sta $ffff,y beq .8 iny bne .4 inc .4+2 inc .5+2 bne .4 .8 pla ply clc .9 rts *-------------------------------------- * SList : * Block : * 0 hMem of next Block (0=End) * 1....255 data records * Record : * 0 Flags * 1 KeyLen+Key * n DataLen+Data */-------------------------------------- * # SListNew * ## In: * ## Out: * A=hMem *\-------------------------------------- K.SListNew */-------------------------------------- * # SListAdd * ## In: * ## Out: * A=hMem *\-------------------------------------- K.SListAdd */-------------------------------------- * # SListGet * ## In: * ## Out: * A=hMem *\-------------------------------------- K.SListGet */-------------------------------------- * # SListPut * ## In: * ## Out: * A=hMem *\-------------------------------------- K.SListPut */-------------------------------------- * # SListFree * ## In: * ## Out: * A=hMem *\-------------------------------------- K.SListFree *-------------------------------------- MEM.SList.Next */-------------------------------------- * # LoadStkObj.YA * ## In: * ## Out: * A=hMem *\-------------------------------------- K.LoadStkObj.YA */-------------------------------------- * # GetStkObj.A * ## In: * ## Out: * A=hMem *\-------------------------------------- K.GetStkObj.A */-------------------------------------- * # FreeStkObj.A * ## In: * ## Out: * A=hMem *\-------------------------------------- K.FreeStkObj.A */-------------------------------------- * # GetMemStat.YA * ## In: * Y,A = Ptr to 24 bytes buffer * ## Out: * Buffer filled with memory stats *\-------------------------------------- K.GetMemStat.YA >STYA ZPMemMgrTmp1 ldy #6 .1 lda Mem.Table,y sta (ZPMemMgrTmp1),y dey bpl .1 ldx #6 ldy #14 sta SETREADAUX .2 lda Mem.Table,x sta (ZPMemMgrTmp1),y dey dex bpl .2 sta CLRREADAUX ldx #6 ldy #22 .3 lda DevMgr.Stat,x sta (ZPMemMgrTmp1),y dey dex bpl .3 rts *-------------------------------------- MAN SAVE /A2OSX.SRC/SYS/KERNEL.S.MEM LOAD /A2OSX.SRC/SYS/KERNEL.S ASM