home *** CD-ROM | disk | FTP | other *** search
- ; ***** DON'T KNOW WHETHER THIS WORKS. WAS NEVER USED!! *****
- ; ----------------------------------------------------------------------
- ; Copyright (C) 1991 by Natürlich!
- ; This file is copyrighted!
- ; Refer to the documentation for details.
- ; ----------------------------------------------------------------------
- ; Nothing beats a selfwritten malloc....
- ; HEAD -> [used.w][size.w][next.l] -> ....
- ; This mallocer doesn't really free anything back to the OS. Why should
- ; we ? For all programs that are expected to run in a matter of seconds
- ; not hours, the overhead isn't justified.
- ; Leaves in the worst case MANY bytes of fragmented OS space unused
- ; This is only a crutch for GEMDOSes fucked up memory manager
- ; ----------------------------------------------------------------------
- .export malloc
- .export free
-
- BLOCKSIZE equ $6008 ;; must be within 15 bits
- GBLOCK equ $03
-
-
- .code
- failed:
- sub.l a0,a0
- bra done
-
- malloc:
- move.w d0,1
- move.l a3,-(a7) ;; save two regs
- move.l d3,-(a7)
-
- move.l d0,d3 ;; try to alloc 0 ??
- beq.b failed ;; that's stupid
- bmi.b failed ;; negative is wrong also
-
- cmpi.l #BLOCKSIZE-$100,d0 ;; more than we can handle
- ble.b goodenough ;; then give it to GEMDOS
-
- addq.l #8,d0 ;; so this is too big for us
- move.l d0,-(a7) ;; use MALLOC from GEMDOS
- move.w #$48,-(a7)
- trap #1
- addq.l #6,a7
- tst.l d0 ;; Enough memory ??
- beq.b failed ;; njet ->
- move.l d0,a0 ;; else mark it as
- move.w #GBLOCK,(a0) ;; being a GEMDOS block
- addq.l #8,a0 ;; skip header
- bra.b done ;; and return
-
- goodenough:
- lea head,a1 ;; get head pointer
- bra.b next
-
- loop:
- tst.w (a1) ;; block in USE ?
- bne.b next ;; yes ->next
- cmp.l (a1),d0 ;; size OK ? (First fit)
- ble.b ok
- next:
- lea 4(a1),a3 ;; save address of NEXT pointer
- move.l (a3),a1 ;; get NEXT pointer
- move.l a1,d1 ;; end of list
- bne.b loop ;; da nada ---^
-
- alloc:
- pea BLOCKSIZE
- move.w #$48,-(a7)
- trap #1
- addq.l #6,a7
- tst.l d0
- beq.b failed ;; not enough room ---V
-
- move.l d0,(a3) ;; initialize header
- move.l d0,a1 ;; of memory block
- move.l #BLOCKSIZE-8,(a1) ;; actual block - header
- clr.l 4(a1) ;; clear next pointer
-
- ok:
- lea 8(a1),a0 ;; get memory area anyway
- move.l (a1),d1 ;; get block size
- sub.l d3,d1 ;; subtract #bytes
- subq.l #8,d1 ;; less the header
- cmpi.w #4,d1 ;; no split for less than 4
- blt.b success ;; then we are thru!!
-
- move.l d3,(a1)+ ;; mosey on up to NEXT field
- lea 4(d3,a1),a3 ;; DO THE SPLIT
- move.l (a1),4(a3) ;; save old NEXT in new
- move.l a3,(a1) ;; save new as NEXT in old
- move.l d1,(a3) ;; save SIZE and clear USED
-
- success:
- st -8(a0) ;; mark as used
- done:
- move.l (a7)+,d3
- fdone:
- move.l (a7)+,a3
- rts
-
-
- free:
- move.l a3,-(a7) ;; save a reg
-
- move.l a0,d0 ;; 0 pointer (MAYBE WE SHOULD CRASH)
- beq.b fdone ;; but we don't
-
- lea -8(a0),a3 ;; get header
- move.w (a3),d0
- beq.b fdone ;; LUSER tried to free twice
- subq.w #GBLOCK,d0 ;; Was it a bona fide GEMDOS block ?
- beq.b yup ;; then we DO free ---V
-
- clr.w (a3) ;; mark as unused
- move.l (a3),d1 ;; get size in D1
- add.l a3,d1 ;; add with current pointer
- addq.l #8,d1 ;; add header len
- move.l 4(a3),a1 ;; get NEXT pointer
- cmpa.l d1,a1 ;; curr + #header + size == NEXT ??
- bne.b nojoin ;; NO join impossible
- tst.w (a1) ;; next block free ?
- bne.b nojoin ;; no --V
- bsr.b join_adjacent
-
- nojoin:
- lea head,a1 ;; get head (CHK LFT NEIGHBOR)
-
- loop2a:
- move.l 4(a1),a1 ;; get next pointer address
- move.l a1,d1 ;; end of list
- beq.b fdone
-
- move.l (a1),d1 ;; get size in A2
- add.l a1,d1 ;; add with current pointer
- addq.l #8,d1 ;; add header len
- cmpa.l d1,a3 ;; points to us ??
- bne.b loop2a ;; yes -> done
-
- bsr.b join_adjacent ;; USED must have been CLEAR
- bra.b fdone ;; for this to work
-
- yup:
- move.l a0,-(a7) ;; free that sucker
- move.w #$49,-(a7)
- trap #1
- addq.l #6,a7
- bra.b fdone
-
-
-
- join_adjacent:
- move.l (a3),d0 ;; get SIZE of LEFT guy
- add.l (a1),d0 ;; add sizes of RITE to it
- addq.l #8,d0 ;; don't forget the header
- move.l d0,(a3) ;; write in LEFT
- move.l 4(a1),4(a3) ;; copy RITE NEXT pointer to LEFT
- rts
-
-
- .data
- head:
- .dc.w $FFFF ;; used internally flag
- .dc.w $0000 ;; no size
- headnext:
- .dc.l 0 ;; points nowhere
-
-