A2osX/SYS/KERNEL.S.MEM.txt
2019-05-12 22:45:11 +02:00

784 lines
16 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

NEW
PREFIX
AUTO 4,1
*--------------------------------------
ZPMemMgrSPtr .EQ ZPMEMMGR Pointer To Slot selected
ZPMemMgrTmp1 .EQ ZPMEMMGR+2
ZPMemMgrSize .EQ ZPMEMMGR+4
*/--------------------------------------
* # GetMem0
* Y,A = Size Requested
* ## RETURN VALUE
* CC : success
* YA = PTR to Mem (ZERO Initialised)
* X = hMem
* CS :
* A = EC
*\--------------------------------------
MEM.ReqFlags .BS 1 store requested Flags
MEM.BestSlot .BS 1
*MEM.BestScore .BS 2
MEM.BestScore .EQ ZPMemMgrTmp1
*--------------------------------------
K.GetMem0 ldx #S.MEM.F.INIT0
.HS 2C bit abs
*/--------------------------------------
* # GetMem
* Y,A = Size Requested
* ## RETURN VALUE
* CC : success
* YA = PTR to Mem (Uninitialised)
* X = hMem
* CS :
* A = EC
*\--------------------------------------
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
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
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
and #S.MEM.F.ALIGN is request needs a page align ?
beq .6
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
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
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
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
*/--------------------------------------
* # FreeMem
* A = hMem To Free
* ## RETURN VALUE
* none.
* (X unmodified)
*\--------------------------------------
K.FreeMem.MSG .AZ "FreeMem:hMem=$%h,PID=%d\r\n"
*--------------------------------------
K.FreeMem.ERR phx
phy hMem n Y
ldy #S.PS.PID
lda (pPS),y
>PUSHA
pla
>PUSHA
>PUSHBI 2
>LDYAI K.FreeMem.MSG
.1 ldx #SYS.printf
jsr K.SYSCALL2.BANK
plx
sec
rts
*--------------------------------------
K.FreeMem tay
beq K.FreeMem.ERR Slot=0, reserved by Kernel
cmp Mem.LastSlot
bcc .10
bne K.FreeMem.ERR
.10 jsr MEM.GetMemByID X,Y unmodified
lda (ZPMemMgrSPtr) In use ?
bpl K.FreeMem.ERR
ldy #S.MEM.REFCNT
lda (ZPMemMgrSPtr),y
dec
sta (ZPMemMgrSPtr),y only one left ?
bne .8 no, must be a code segment loaded several times
lda (ZPMemMgrSPtr)
and #S.MEM.F.CODE CS: Any BINPATH to discard ?
sta (ZPMemMgrSPtr) Mark as FREE
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
*--------------------------------------
ZPSListKeyID .EQ ZPMEMMGR+6
ZPSListDataPtr .EQ ZPMEMMGR+8
ZPSListDataLen .EQ ZPMEMMGR+10
ZPSListIBlkPtr .EQ ZPMEMMGR+12
ZPSListDBlkPtr .EQ ZPMEMMGR+14
*/--------------------------------------
* # SListGetData
* ## ASM
* `PUSHW DataOfs`
* `PUSHW DataLen`
* `PUSHW DataPtr`
* `PUSHW KeyID`
* `lda hSList`
* `>SYSCALL SListGetData`
* ## RETURN VALUE
* Y,A = Byte Count
* X = hMem (if DataPtr = 0)
*\--------------------------------------
K.SListGetData pha
>PULLW ZPSListKeyID
>PULLW ZPSListDataPtr
>PULLW ZPSListDataLen
>PULLW ZPMemMgrSize
pla
bra K.SListFree
pla
*/--------------------------------------
* # SListAddData
* ## ASM
* `PUSHW DataLen`
* `PUSHW DataPtr`
* `PUSHW KeyID`
* `lda hSList`
* `>SYSCALL SListAddData`
* ## RETURN VALUE
*\--------------------------------------
K.SListAddData
*/--------------------------------------
* # SListSetData
* ## ASM
* `PUSHW DataLen`
* `PUSHW DataPtr`
* `PUSHW KeyID`
* `lda hSList`
* `>SYSCALL SListSetData`
* ## RETURN VALUE
*\--------------------------------------
K.SListSetData pha
>PULLW ZPSListKeyID
>PULLW ZPSListDataPtr
>PULLW ZPSListDataLen
pla
bra K.SListFree
*/--------------------------------------
* # SListGetByID
* ## ASM
* `PUSHW KeyPtr`
* `PUSHW KeyID`
* `lda hSList`
* `>SYSCALL SListGetByID`
* ## RETURN VALUE
* Y,A = Next KeyID
*\--------------------------------------
K.SListGetByID pha
>PULLW ZPSListKeyID
>PULLW ZPSListDataPtr
pla
bra K.SListFree
*/--------------------------------------
* # SListNewKey
* ## ASM
* `PUSHW KeyPtr`
* `lda hSList`
* `>SYSCALL SListNewKey`
* ## RETURN VALUE
* Y,A = KeyID
* X = KeyLen
*\--------------------------------------
K.SListNewKey
*/--------------------------------------
* # SListLookup
* ## ASM
* `PUSHW KeyPtr`
* `lda hSList`
* `>SYSCALL SListLookup`
* ## RETURN VALUE
* Y,A = KeyID
* X = Key Length
*\--------------------------------------
K.SListLookup pha
>PULLW ZPSListDataPtr
pla
*/--------------------------------------
* # SListNew
* ## ASM
* `>SYSCALL SListNew`
* ## RETURN VALUE
* A=hSList
*\--------------------------------------
K.SListNew
*/--------------------------------------
* # SListFree
* ## ASM
* `lda hSList`
* `>SYSCALL SListFree`
* ## RETURN VALUE
*\--------------------------------------
K.SListFree sta SETREADAUX
sta SETWRITEAUX
jsr X.SLIST
sta CLRREADAUX
sta CLRWRITEAUX
rts
*/--------------------------------------
* # NewStkObj
* Y,A = Size Requested
* ## RETURN VALUE
* CC : success
* YA = PTR to Mem (Uninitialised)
* X = hMem
* CS :
* A = EC
*\--------------------------------------
K.NewStkObj ldx #SYS.GetMem
.HS 2C BIT ABS
*/--------------------------------------
* # FreeStkObj
* A = hMem To Free (AUX Memory)
* ## RETURN VALUE
* none.
* (X,Y unmodified)
*\--------------------------------------
K.FreeStkObj ldx #SYS.FreeMem
sta SETREADAUX
sta SETWRITEAUX
jsr K.SYSCALL.JMP
sta CLRREADAUX
sta CLRWRITEAUX
rts
*/--------------------------------------
* # LoadStkObj
* Load a file in AUX memory (Stock Objects)
* PUSHW = AUXTYPE (Handled by....
* PUSHB = TYPE ...
* PUSHB = MODE ...
* LDYA = PATH ...FOpen)
* ## RETURN VALUE
* Y,A = File Length
* X = hMem of Loaded Object in AUX mem
*\--------------------------------------
K.LoadStkObj ldx #SYS.LoadTxtFile To get ending \0
jsr K.SYSCALL2.BANK
bcs .99
sty .81+1
sta .82+1
stx .8+1 Save MAIN hMem
iny
bne .1
inc +1 for ending 0
.1 >STYA A2L Save LEN temporarly
jsr K.NewStkObj
bcs .9
stx .80+1
>STYA A4L Save Destination Address in AUX
lda .8+1
jsr K.GetMemPtr
>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 release MAIN memory
.80 ldx #$ff Returns AUX hMem
.81 ldy #$ff and file len in Y,A
.82 lda #$ff
* clc
rts
.9 pha
jsr .8
pla
sec
.99 rts
*/--------------------------------------
* # GetStkObjData
* ## ASM
* `PUSHW DataLen`
* `PUSHW DataPtr`
* `lda hStkObj`
* `>SYSCALL GetStkObjData`
* ## RETURN VALUE
*\--------------------------------------
K.GetStkObjData sta SETREADAUX
jsr K.GetMemPtr
>STYA ZPMemMgrTmp1
>PULLW ZPSListDataLen
>PULLW ZPSListDataPtr
lda (ZPMemMgrTmp1),y
pha
iny
lda (ZPMemMgrTmp1),y
ply
sta CLRREADAUX
rts
*--------------------------------------
* in Y,A = buf size
*--------------------------------------
MEM.GetMainBuf sta CLRREADAUX
sta CLRWRITEAUX
jsr K.GetMem
sta SETREADAUX
sta SETWRITEAUX
rts
*--------------------------------------
MEM.GetKrnlBuf 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
bcs .98 No More Room...
ldy DevMgr.Free
stx DevMgr.Free
ldx DevMgr.Free+1
pla
sta DevMgr.Free+1
txa
* clc
rts
.98 pla
.99 lda #E.OOM
* sec
rts
*--------------------------------------
MEM.GetKeyCharY sta CLRREADAUX
lda (ZPSListDataPtr),y
sta SETREADAUX
beq MEM.IsDigit.9
MEM.IsIDValid cmp #'.'
beq MEM.IsDigit.8
cmp #'_'
beq MEM.IsDigit.8
MEM.IsDigitOrL cmp #'z'+1
bcs MEM.IsDigit.RTS
cmp #'a'
bcs MEM.IsDigit.8
MEM.IsDigitOrUC cmp #'Z'+1
bcs MEM.IsDigit.RTS
cmp #'A'
bcs MEM.IsDigit.8
MEM.IsDigit cmp #'9'+1
bcs MEM.IsDigit.RTS
cmp #'0'
bcs MEM.IsDigit.8
MEM.IsDigit.9 sec
MEM.IsDigit.RTS rts
MEM.IsDigit.8 clc
rts
*--------------------------------------
MEM.IsHexDigit jsr MEM.IsDigit
bcc .8
cmp #'A'
bcc MEM.IsDigit.9
cmp #'F'+1
bcc .1
cmp #'a'
bcc MEM.IsDigit.9
cmp #'f'+1
bcs MEM.IsDigit.RTS
eor #$20
.1
* clc
sbc #'A'-11 cc so A->10 (11-CC)
clc
.8 and #$0F
rts
*--------------------------------------
MEM.SetKeyCharY sta CLRWRITEAUX
sta (ZPSListDataPtr),y
sta SETWRITEAUX
rts
*--------------------------------------
MEM.GetDataByte sta CLRREADAUX
lda (ZPSListDataPtr)
sta SETREADAUX
bra MEM.SetDataByte.1
*--------------------------------------
MEM.SetDataByte sta CLRWRITEAUX
sta (ZPSListDataPtr)
sta SETWRITEAUX
MEM.SetDataByte.1
inc ZPSListDataPtr
bne .8
inc ZPSListDataPtr+1
.8 rts
*--------------------------------------
MEM.TXTPTR.GetY sta CLRREADAUX
lda (TXTPTR),y
sta SETREADAUX
rts
*--------------------------------------
MEM.TXTPTR.GetNext
sta CLRREADAUX
lda (TXTPTR)
sta SETREADAUX
beq .9
inc TXTPTR
bne .9
inc TXTPTR+1
.9 rts
*--------------------------------------
MEM.SPtr1PPtr2 >STYA ZPPtr1
>PULLW ZPPtr2
rts
*--------------------------------------
MEM.SPtr2PPtr1 >STYA ZPPtr2
>PULLW ZPPtr1
rts
*--------------------------------------
MEM.GetCharPtr1 lda (ZPPtr1)
beq MEM.GetCharPtr1.8
MEM.NextCharPtr1
inc ZPPtr1
bne MEM.GetCharPtr1.8
inc ZPPtr1+1 never Z
MEM.GetCharPtr1.8
rts
*--------------------------------------
MEM.AddYp1ToPtr1
sec
.HS 90 BCC
MEM.AddYToPtr1 clc
tya
adc ZPPtr1
sta ZPPtr1
bcc .8
inc ZPPtr1+1
.8 rts
*--------------------------------------
MEM.PutCharPtr2 sta (ZPPtr2)
MEM.NextCharPtr2
inc ZPPtr2
bne .8
inc ZPPtr2+1
.8 rts
*--------------------------------------
DevMgr.Stat .DA DevMgr.FreeMem
DevMgr.Free .DA DevMgr.FreeMem
.DA DevMgr.HiMem
DevMgr.DevIdx .DA #1
*--------------------------------------
MAN
SAVE USR/SRC/SYS/KERNEL.S.MEM
LOAD USR/SRC/SYS/KERNEL.S
ASM