PR#3
PREFIX /A2OSX.SRC
NEW
INC 1
AUTO 6
				.LIST OFF
*--------------------------------------
* !!!!!! DO NOT USE ZPQuickPTRs !!!!!
*--------------------------------------
ZPMemMgrSPtr 	.EQ ZPMEMMGR			Pointer To Slot selected
ZPMemMgrTmp1	.EQ ZPMEMMGR+2
ZPMemMgrSrcPtr	.EQ ZPMEMMGR+4
ZPMemMgrDstPtr	.EQ ZPMEMMGR+6
*--------------------------------------
MemMgr.ReqSize 	.EQ ZPMEMMGR+8			store requested Size
MemMgr.ReqFlags	.EQ ZPMEMMGR+10			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
*--------------------------------------
* K.GetMem
*  In: 
*	PULLB = FLAGS 
*   PULLW = Size Requested
*  Out:
*   YA = PTR to Mem
*	X = S.MEM.ID
*   CS on err
*--------------------------------------
K.GetMem		>PULLB MemMgr.ReqFlags	store requested flags
				and #S.MEM.F.AUX
				beq .11

				sta SETREADAUX			Aux Mem requested,switch to AUX
				sta SETWRITEAUX				
				
.11				>PULLAX					get requested size
				bit #$0F				16 bytes aligned ?
				beq .10					yes, request it	
				
				and #$F0				align on 16 bytes
				clc
				adc #$10
				bcc .10
				inx
				
.10				>STAX  MemMgr.ReqSize

				>LDYAI MemMgr.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 MemMgr.NextSlot
				lda (ZPMemMgrSPtr)		Get Flags
				bmi .4					in use ?
				
.2				lda MemMgr.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 MemMgr.ReqSize		compare with requested size
				bne .4
				
				iny
				lda (ZPMemMgrSPtr),y
				cmp MemMgr.ReqSize+1
				beq .7					requested size matches slot size !!!
				
.4				cpx MemMgr.LastSlot		any other slot to check?
				bne .1					last one, create a new slot
				
*-------------- Create a New SLOT
				lda MemMgr.ReqFlags
				and #S.MEM.F.ALIGN		is request needs a page align ?
				beq .6
				
				lda MemMgr.Free			target PTR will be page aligned ?
				sec
				sbc MemMgr.ReqSize
				beq .6					yes, allocate
				
				tay						no, reserve a free slot to fill gap
				lda #0
				jsr MemMgr.AddSlot		X = new slot
				bcs .9
				
.6				>LDYA MemMgr.ReqSize
				jsr MemMgr.AddSlot		X = new slot
				bcs .9
				
*-------------- Reuse this SLOT
.7				lda MemMgr.ReqFlags		get requested flags
				ora #S.MEM.F.INUSE		mark as in use
				sta (ZPMemMgrSPtr)
				
				and #S.MEM.F.INIT0
				beq .8
				phx						save hMem
				jsr MemMgr.Init0
				plx						restore hMem
				
.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.ID
				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				bit MemMgr.ReqFlags		
				bpl .99
				
				sta CLRREADAUX
				sta CLRWRITEAUX
				
.99				rts						
*--------------------------------------
* MemMgr.AddSlot
*  In:
*   Y,A = Requested size
*  Out: 
*--------------------------------------
MemMgr.AddSlot  >STYA ZPMemMgrTmp1		save req size
				ldx MemMgr.LastSlot		
				inx
				beq .99					> 255 ERR:OUT OF SLOT
				
				lda MemMgr.Free			Compute base PTR=FREE-REQ size
				sec
				sbc ZPMemMgrTmp1
				tay						save new MemMgr.Free LO
				lda MemMgr.Free+1
				sbc ZPMemMgrTmp1+1
				pha						save new MemMgr.Free HI				

				cpy MemMgr.LoMem
				sbc MemMgr.LoMem+1
				bcc .98					ERR out of mem

				jsr MemMgr.NextSlot		X,Y unmodified
				
				tya						get back MemMgr.Free LO
				
				ldy #S.MEM.PTR
				sta MemMgr.Free			set as system MemMgr.Free value
				sta (ZPMemMgrSPtr),y	store is as base address of new slot
				iny
				pla						get back MemMgr.Free HI
				sta MemMgr.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 MemMgr.LastSlot		mark this slot allocated
				clc
				rts
				
.98				pla						discard new MemMgr.Free HI
				lda #MemMgr.ERROOM
				sec
				rts
				
.99				lda #MemMgr.ERROOH
				sec
				rts	
*--------------------------------------
MemMgr.NextSlot	lda ZPMemMgrSPtr
				clc
				adc #S.MEM
				sta ZPMemMgrSPtr
				bcc .8
				inc ZPMemMgrSPtr+1
.8				rts								
*--------------------------------------
MemMgr.Init0	ldy #S.MEM.PTR
				lda (ZPMemMgrSPtr),y	ZPMemMgrSPtr already set
				sta .2+1
				iny
				lda (ZPMemMgrSPtr),y
				sta .2+2
				
				ldy #S.MEM.LEN			
				lda (ZPMemMgrSPtr),y
				eor #$ff
				pha
				
				iny
				lda (ZPMemMgrSPtr),y
				eor #$ff				a=not hi count			

				ply						y=not lo count
				ldx #0
				
.1				iny
				bne .2
				inc
				beq .8
				
.2				stz $ffff,x
				inx
				bne .1
				inc .2+2
				bne .1
				
.8				rts
*--------------------------------------
* K.FreeMemA
* In:
*  A = hMem To Free
* Out:
*  X,Y unmodified
*--------------------------------------
K.FreeMemA	    phy
				tay
				
				beq *					Slot=0, reserved by Kernel
				
				jsr K.GetMemByIDA		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
				
				ldy #S.MEM.BIN
				lda (ZPMemMgrSPtr),y	Any BINPATH to discard ?		
				beq .1
				
				pha						save hMem
				>PUSHW ZPMemMgrSPtr
				pla
				jsr K.GetMemByIDA		X unmodified
				lda (ZPMemMgrSPtr)
				bpl *					***MUST BE ALLOCATED***
				
				lda #0					mark BINPATH slot as free
				sta (ZPMemMgrSPtr)
				>PULLW ZPMemMgrSPtr
				
.1				lda #0					mark this slot as free
				sta (ZPMemMgrSPtr)

.2				lda MemMgr.LastSlot
				beq .8
				
				jsr K.GetMemByIDA		X unmodified
				lda (ZPMemMgrSPtr)
				bmi .8
				
				ldy #S.MEM.LEN
				lda (ZPMemMgrSPtr),y	give back LEN bytes
				clc
				adc MemMgr.Free			to MemMgr.Free
				sta MemMgr.Free
				iny
				lda (ZPMemMgrSPtr),y
				adc MemMgr.Free+1
				sta MemMgr.Free+1
				
				dec	MemMgr.LastSlot		discard last slot	
				bne .2					no slot left, exit

.8				ply
				clc
				rts
*--------------------------------------				
.9				ply						discard	saved Y

				lda $D000
				sta .91+1
				bit RRAMWRAMBNK2
				bit RRAMWRAMBNK2		
				
				jsr DevMgr.SYS.Select
				jsr PS.Select0
				
				pla						Get PC and sub 2 for calling address
				sec
				sbc #2
				tay
				pla
				sbc #0

				>PUSHYA
				
				>LDYAI K.FreeMemA.ERR
				jsr K.PrintFYA
				
.91				ldx #$ff				
				bit $C000,x
				bit $C000,x
				bra *
*--------------------------------------
K.FreeMemA.ERR	>CSTRING "***MemMgr:Attempt to Free an already freed hMem at $%H"
*--------------------------------------
* K.GetMemPtrA
* In:
*   A = hMem
* Out:
*	Y,A = PTR to MemBlock
*   X unmodified
*--------------------------------------
K.GetMemPtrA	jsr K.GetMemByIDA
				ldy #S.MEM.PTR
				lda (ZPMemMgrSPtr),y
				pha
				iny
				lda (ZPMemMgrSPtr),y
				ply
				rts
*--------------------------------------
* K.GetMemByIDA
* In:
*   A = hMem
* Out:
*	Y,A = ZPMemMgrSPtr = PTR to S.MEM
*   X unmodified
* *** Optimized for :
*  MemMgr.Table is page aligned at $1800
*  S.MEM is 8 bytes
*--------------------------------------
				.DO MemMgr.Table=$1800
				.ELSE
				!!!!!WARNING!!!!!
				.FIN
				.DO S.MEM=8
				.ELSE
				!!!!!WARNING!!!!!
				.FIN
*--------------------------------------
K.GetMemByIDA	sta ZPMemMgrSPtr
				lda /MemMgr.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 #MemMgr.Table
*				tay
*				lda ZPMemMgrSPtr+1
*				adc /MemMgr.Table				
*				sty ZPMemMgrSPtr
*				sta ZPMemMgrSPtr+1
*				rts
*--------------------------------------
* In:
*	Y,A = BINPATH (PSTR)
* Out:
*	Y,A = ZPMemMgrSPtr = PTR to S.MEM
*   X = hMem
*--------------------------------------
K.GetMemByNameYA
				ldx MemMgr.LastSlot
				beq .9

				>STYA ZPMemMgrSrcPtr		save BINPATH
				>LDYAI MemMgr.Table
				>STYA ZPMemMgrTmp1		

				ldx #0
				
.1				lda (ZPMemMgrTmp1)
				bpl .6					In Use?
				
				ldy #S.MEM.BIN			any BIN PATH in this slot?	
				lda (ZPMemMgrTmp1),y
				beq .6
				
				jsr K.GetMemPtrA		get pathname
				>STYA ZPMemMgrDstPtr
				
				lda (ZPMemMgrSrcPtr)
				cmp (ZPMemMgrDstPtr)
				bne .6

				tay
				
.2				lda (ZPMemMgrSrcPtr),y
				cmp (ZPMemMgrDstPtr),y
				bne .6
				dey
				bne .2
				
				>LDYA ZPMemMgrTmp1
				
				clc
				rts
				
.6				lda ZPMemMgrTmp1
				clc
				adc #S.MEM
				sta ZPMemMgrTmp1
				bcc .7
				inc ZPMemMgrTmp1+1
				
.7				inx
				cpx MemMgr.LastSlot
				bne .1
				
.9				sec
				rts
*--------------------------------------
K.LoadStockObjectYA
*--------------------------------------
K.GetStockObjectA
*--------------------------------------
K.FreeStockObject
*--------------------------------------
K.SetLoMem
				clc
				rts
*--------------------------------------
K.GetMemStatYA	>STYA ZPMemMgrDstPtr
				
				ldy #7
				
.1				lda MemMgr.Table,y
				sta (ZPMemMgrDstPtr),y
				dey
				bpl .1
				
				
				ldx #7
				ldy #15
				
				sta SETREADAUX
				
.2				lda MemMgr.Table,x
				sta (ZPMemMgrDstPtr),y
				dey
				dex
				bpl .2
				
				sta CLRREADAUX
				
				ldy #16
				lda #DevMgr.LoMem
				sta (ZPMemMgrDstPtr),y
				
				iny
				lda /DevMgr.LoMem
				sta (ZPMemMgrDstPtr),y
				
				iny
				lda DevMgr.Free
				sta (ZPMemMgrDstPtr),y
				
				iny
				lda DevMgr.Free+1
				sta (ZPMemMgrDstPtr),y
				
				iny
				lda #DevMgr.HiMem
				sta (ZPMemMgrDstPtr),y
				
				iny
				lda /DevMgr.HiMem
				sta (ZPMemMgrDstPtr),y
				
				iny
				lda DevMgr.LastDevID
				sta (ZPMemMgrDstPtr),y
				
				rts
*--------------------------------------
MEM.GarbageCollector
				clc
				rts
*--------------------------------------
MAN
SAVE SYS/KERNEL.S.MEM
LOAD SYS/KERNEL.S
ASM
