NEW PREFIX /A2OSX.BUILD AUTO 4,1 *-------------------------------------- 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 ZPSListBlock .EQ ZPMEMMGR+8 ZPSListIndex .EQ ZPMEMMGR+10 ZPSListKey .EQ ZPMEMMGR+12 ZPSListData .EQ ZPMEMMGR+14 *-------------------------------------- * 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 *-------------------------------------- */-------------------------------------- * # 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 */-------------------------------------- * # 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 .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 ldx #0 MEM.GetMem.YAX stx Mem.ReqFlags sta Mem.ReqSize+1 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 ldy #0 lda #0 .1 ldx $ffff,y beq .2 iny bne .1 inc inc .1+2 bne .1 .2 iny Add one for ending 0 bne .3 inc .3 jsr K.GetMem.YA 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 */-------------------------------------- * # SListNew * ## In: * ## Out: * A=hMem *\-------------------------------------- K.SListNew >LDYAI 160 40k Max before out of memory!!! jsr K.GetMem0.YA bcs .9 >STYA ZPSListIndex stx .8+1 >LDYAI 256 jsr K.GetMem0.YA bcs .9 txa sta (ZPSListIndex) .8 lda #$ff SELF MODIFIED .9 rts */-------------------------------------- * # SListGetByID * ## In: * PUSHB = hSList * PUSHW = Key Ptr * PUSHW = Data Ptr * PUSHW = KeyID * ## Out: *\-------------------------------------- K.SListGetByID >PULLW MEM.IndexOfs jsr MEM.GetSListParams ldy MEM.IndexOfs lda (ZPSListIndex),y beq .9 jsr K.GetMemPtr.A >STYA ZPSListBlock clc rts .9 sec rts */-------------------------------------- * # SListAdd * ## In: * PUSHB = hSList * PUSHW = Key * PUSHW = Data Ptr * ## Out: * A=hSList *\-------------------------------------- K.SListAdd jsr K.SListLookup.I bcc .9 Lookup succeeded...DUP sta SETWRITEAUX ldy #0 .1 jsr MEM.GetKeyCharY iny bcc .1 tya jsr MEM.AddBlockByte bcs .99 ldy #0 .2 jsr MEM.GetKeyCharY bcs .3 jsr MEM.AddBlockByte bcs .99 iny bra .2 .3 sta CLRREADAUX lda (ZPSListData) sta SETREADAUX tax jsr MEM.AddBlockByte bcs .99 ldy #1 .4 sta CLRREADAUX lda (ZPSListData),y sta SETREADAUX jsr MEM.AddBlockByte bcs .99 iny dex bne .4 clc .HS B0 BCS .9 sec .99 sta CLRWRITEAUX sta CLRREADAUX rts */-------------------------------------- * # SListLookup * ## In: * PUSHB = hSList * PUSHW = Key * PUSHW = Data Ptr * ## Out: * Data Ptr Updated *\-------------------------------------- K.SListLookup jsr K.SListLookup.I bcs .9 jsr MEM.GetBlockByte tax sta (ZPSListData) ldy #0 .1 jsr MEM.GetBlockByte iny sta (ZPSListData),y dex bne .1 sta CLRREADAUX clc .9 rts *-------------------------------------- K.SListLookup.I jsr MEM.GetSListParams lda (ZPSListIndex) beq .9 jsr K.GetMemPtr.A >STYA ZPSListBlock stz MEM.BlockOfs jsr MEM.GetBlockByte beq .9 tax .1 ldy #0 .2 jsr MEM.GetKeyCharY bcs .4 iny sta .3+1 jsr MEM.GetBlockByte .3 cmp #$ff SELF MODIFIED bne .4 dex bne .2 clc rts .4 jsr MEM.GetBlockByte skip remaining key chars dex bne .4 jsr MEM.GetBlockByte get Data Len tax .5 jsr MEM.GetBlockByte skip data bytes dex bne .5 tax bne .1 .9 sec rts */-------------------------------------- * # SListUpdate * ## In: * PUSHB = hSList * PUSHW = Key * PUSHW = Data Ptr * ## Out: *\-------------------------------------- K.SListUpdate jsr K.SListLookup.I bcs .9 ldy #0 sta CLRREADAUX lda (ZPSListData) sta SETREADAUX tax jsr MEM.SetBlockByte bcs .99 ldy #1 .4 sta CLRREADAUX lda (ZPSListData),y sta SETREADAUX jsr MEM.SetBlockByte bcs .99 iny dex bne .4 clc .HS B0 BCS .9 sec .99 sta CLRWRITEAUX sta CLRREADAUX rts */-------------------------------------- * # SListFree * ## In: * A=hSList * ## Out: *\-------------------------------------- K.SListFree.A sta .8 sta SETREADAUX sta SETWRITEAUX jsr K.GetMemPtr.A >STYA .1+1 ldx #0 .1 lda $ffff,x SELF MODIFIED beq .8 jsr K.FreeMem.A inx bra .1 .8 lda #$ff SELF MODIFIED jsr K.FreeMem.A sta CLRWRITEAUX sta CLRREADAUX rts *-------------------------------------- MEM.GetSListParams >PULLW ZPSListData >PULLW ZPSListKey >PULLA sta SETREADAUX jsr K.GetMemPtr.A >STYA ZPSListIndex rts *-------------------------------------- MEM.GetKeyCharY sta CLRREADAUX lda (ZPSListKey),y sta SETREADAUX beq .9 cmp #'0' bcc .9 cmp #'9'+1 bcc .8 cmp #'A' bcc .9 cmp #'Z'+1 bcc .8 cmp #'a' bcc .9 cmp #'z'+1 bcc .8 cmp #'.' bne .9 cmp #'_' bne .9 .8 clc rts .9 sec rts *-------------------------------------- MEM.GetBlockByte phy ldy MEM.BlockOfs lda (ZPSListBlock),y inc MEM.BlockOfs bne .8 pha ldy MEM.IndexOfs lda (ZPSListIndex),y beq .9 jsr K.GetMemPtr.A >STYA ZPSListBlock * stz MEM.BlockOfs pla .8 ply clc rts .9 pla ply sec rts *-------------------------------------- MEM.AddBlockByte phy ldy MEM.BlockOfs sta (ZPSListBlock),y inc MEM.BlockOfs bne .8 inc MEM.IndexOfs >LDYAI 256 jsr K.GetMem0.YA bcs .9 >STYA ZPSListBlock txa ldy MEM.IndexOfs sta (ZPSListIndex),y * stz MEM.BlockOfs .8 ply clc rts .9 ply sec rts *-------------------------------------- MEM.SetBlockByte phy ldy MEM.BlockOfs sta (ZPSListBlock),y inc MEM.BlockOfs bne .8 inc MEM.IndexOfs ldy MEM.IndexOfs lda (ZPSListIndex),y jsr K.GetMemPtr.A >STYA ZPSListBlock * stz MEM.BlockOfs .8 ply clc rts *-------------------------------------- MEM.IndexOfs .BS 1 MEM.BlockOfs .BS 1 */-------------------------------------- * # LoadStkObj * Load a file in AUX memory (Stock Objects) * ## In: * PUSHW = AUXTYPE (Handled by.... * PUSHB = TYPE ... * PUSHB = MODE ... * PUSHW = PATH ...FOpen) * ## Out: * Y,A = File Length * X = hMem of Loaded Object in AUX mem *\-------------------------------------- K.LoadStkObj >SYSCALL LoadFile bcs .99 stx .8+1 Save MAIN hMem >STYA A2L Save LEN temporarly jsr K.NewStkObj.YA bcs .9 stx .80+1 >STYA A4L Save Destination Address in AUX lda .8+1 jsr K.GetMemPtr.A >STYA A1L Save MAIN base Ptr pha Add Allocated LEN tya clc adc A2L sta A2L pla adc A2L+1 sta A2L+1 to get End address in A2L/H sec Main To Aux jsr AuxMove .8 lda #$ff SELF MODIFIED jsr K.FreeMem.A release MAIN memory .80 lda #$ff Returns AUX hMem rts .9 pha jsr .8 pla sec .99 rts */-------------------------------------- * # NewStkObj.YA * ## In: * Y,A = Size Requested * ## Out: * CC : success * YA = PTR to Mem (Uninitialised) * X = hMem * CS : * A = EC *\-------------------------------------- K.NewStkObj.YA sta SETREADAUX sta SETWRITEAUX jsr K.GetMem.YA sta CLRREADAUX sta CLRWRITEAUX rts */-------------------------------------- * # FreeStkObj.A * ## In: * A = hMem To Free (AUX Memory) * ## Out: * none. * (X,Y unmodified) *\-------------------------------------- K.FreeStkObj.A sta SETREADAUX sta SETWRITEAUX jsr K.FreeMem.A sta CLRREADAUX sta CLRWRITEAUX rts *-------------------------------------- MAN SAVE /A2OSX.SRC/SYS/KERNEL.S.MEM LOAD /A2OSX.SRC/SYS/KERNEL.S ASM