heapinit.asm 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. ; vim: ts=4:et:sw=4:
  2. ; Copyleft (K) by Jose M. Rodriguez de la Rosa
  3. ; (a.k.a. Boriel)
  4. ; http://www.boriel.com
  5. ;
  6. ; This ASM library is licensed under the BSD license
  7. ; you can use it for any purpose (even for commercial
  8. ; closed source programs).
  9. ;
  10. ; Please read the BSD license on the internet
  11. ; ----- IMPLEMENTATION NOTES ------
  12. ; The heap is implemented as a linked list of free blocks.
  13. ; Each free block contains this info:
  14. ;
  15. ; +----------------+ <-- HEAP START
  16. ; | Size (2 bytes) |
  17. ; | 0 | <-- Size = 0 => DUMMY HEADER BLOCK
  18. ; +----------------+
  19. ; | Next (2 bytes) |---+
  20. ; +----------------+ <-+
  21. ; | Size (2 bytes) |
  22. ; +----------------+
  23. ; | Next (2 bytes) |---+
  24. ; +----------------+ |
  25. ; | <free bytes...>| | <-- If Size > 4, then this contains (size - 4) bytes
  26. ; | (0 if Size = 4)| |
  27. ; +----------------+ <-+
  28. ; | Size (2 bytes) |
  29. ; +----------------+
  30. ; | Next (2 bytes) |---+
  31. ; +----------------+ |
  32. ; | <free bytes...>| |
  33. ; | (0 if Size = 4)| |
  34. ; +----------------+ |
  35. ; <Allocated> | <-- This zone is in use (Already allocated)
  36. ; +----------------+ <-+
  37. ; | Size (2 bytes) |
  38. ; +----------------+
  39. ; | Next (2 bytes) |---+
  40. ; +----------------+ |
  41. ; | <free bytes...>| |
  42. ; | (0 if Size = 4)| |
  43. ; +----------------+ <-+
  44. ; | Next (2 bytes) |--> NULL => END OF LIST
  45. ; | 0 = NULL |
  46. ; +----------------+
  47. ; | <free bytes...>|
  48. ; | (0 if Size = 4)|
  49. ; +----------------+
  50. ; When a block is FREED, the previous and next pointers are examined to see
  51. ; if we can defragment the heap. If the block to be breed is just next to the
  52. ; previous, or to the next (or both) they will be converted into a single
  53. ; block (so defragmented).
  54. ; MEMORY MANAGER
  55. ;
  56. ; This library must be initialized calling __MEM_INIT with
  57. ; HL = BLOCK Start & DE = Length.
  58. ; An init directive is useful for initialization routines.
  59. ; They will be added automatically if needed.
  60. #init "__MEM_INIT"
  61. ; ---------------------------------------------------------------------
  62. ; __MEM_INIT must be called to initalize this library with the
  63. ; standard parameters
  64. ; ---------------------------------------------------------------------
  65. __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and
  66. ;- ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start
  67. ;- ld de, ZXBASIC_HEAP_SIZE ; Change this with your size
  68. ; ---------------------------------------------------------------------
  69. ; __MEM_INIT2 initalizes this library
  70. ; Parameters:
  71. ; HL : Memory address of 1st byte of the memory heap
  72. ; DE : Length in bytes of the Memory Heap
  73. ; ---------------------------------------------------------------------
  74. __MEM_INIT2:
  75. ; HL as TOP
  76. ;- PROC
  77. ;- dec de
  78. ;- dec de
  79. ;- dec de
  80. ;- dec de ; DE = length - 4; HL = start
  81. ; This is done, because we require 4 bytes for the empty dummy-header block
  82. eor z80_a ;- xor a
  83. lda z80_a ;- ld (hl),a
  84. ldy #$00
  85. sta (z80_hl),y
  86. inc z80_l ;- inc hl
  87. bne *+4
  88. inc z80_h
  89. lda z80_a ;- ld (hl),a ; First "free" block is a header: size=0, Pointer=&(Block) + 4
  90. ldy #$00
  91. sta (z80_hl),y
  92. inc z80_l ;- inc hl
  93. bne *+4
  94. inc z80_h
  95. lda z80_h ;- ld b,h
  96. sta z80_b
  97. lda z80_l ;- ld c,l
  98. sta z80_c
  99. inc z80_c ;- inc bc
  100. bne *+4
  101. inc z80_b
  102. inc z80_c ;- inc bc ; BC = starts of next block
  103. bne *+4
  104. inc z80_b
  105. lda z80_c ;- ld (hl),c
  106. ldy #$00
  107. sta (z80_hl),y
  108. inc z80_l ;- inc hl
  109. bne *+4
  110. inc z80_h
  111. lda z80_b ;- ld (hl),b
  112. ldy #$00
  113. sta (z80_hl),y
  114. inc z80_l ;- inc hl ; Pointer to next block
  115. bne *+4
  116. inc z80_h
  117. lda z80_e ;- ld (hl),e
  118. ldy #$00
  119. sta (z80_hl),y
  120. inc z80_l ;- inc hl
  121. bne *+4
  122. inc z80_h
  123. lda z80_d ;- ld (hl),d
  124. ldy #$00
  125. sta (z80_hl),y
  126. inc z80_l ;- inc hl ; Block size (should be length - 4 at start); This block contains all the available memory
  127. bne *+4
  128. inc z80_h
  129. lda z80_a ;- ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block)
  130. ldy #$00
  131. sta (z80_hl),y
  132. inc z80_l ;- inc hl
  133. bne *+4
  134. inc z80_h
  135. lda z80_a ;- ld (hl),a
  136. ldy #$00
  137. sta (z80_hl),y
  138. ;- ld a,201
  139. ;- ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again
  140. rts ;- ret
  141. ;- ENDP