realloc.asm 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  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. #include once <error.asm>
  61. #include once <alloc.asm>
  62. #include once <free.asm>
  63. ; ---------------------------------------------------------------------
  64. ; MEM_REALLOC
  65. ; Reallocates a block of memory in the heap.
  66. ;
  67. ; Parameters
  68. ; HL = Pointer to the original block
  69. ; BC = New Length of requested memory block
  70. ;
  71. ; Returns:
  72. ; HL = Pointer to the allocated block in memory. Returns 0 (NULL)
  73. ; if the block could not be allocated (out of memory)
  74. ;
  75. ; Notes:
  76. ; If BC = 0, the block is freed, otherwise
  77. ; the content of the original block is copied to the new one, and
  78. ; the new size is adjusted. If BC < original length, the content
  79. ; will be truncated. Otherwise, extra block content might contain
  80. ; memory garbage.
  81. ;
  82. ; ---------------------------------------------------------------------
  83. __REALLOC:
  84. ; Reallocates block pointed by HL, with new length BC
  85. ;- PROC
  86. ;- LOCAL __REALLOC_END
  87. lda z80_h ;- ld a,h
  88. sta z80_a
  89. ora z80_l ;- or l
  90. jeq __MEM_ALLOC ;- jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc
  91. ldy #$00 ;- ld e,(hl)
  92. lda (z80_hl),y
  93. sta z80_e
  94. inc z80_l ;- inc hl
  95. bne *+4
  96. inc z80_h
  97. ldy #$00 ;- ld d, (hl) ; DE = First 2 bytes of HL block
  98. lda (z80_hl),y
  99. sta z80_d
  100. lda z80_l ;- push hl
  101. pha
  102. lda z80_h
  103. pha
  104. lda z80_c ;- exx
  105. ldx z80_cp
  106. stx z80_c
  107. sta z80_cp
  108. lda z80_b
  109. ldx z80_bp
  110. stx z80_b
  111. sta z80_bp
  112. lda z80_e
  113. ldx z80_ep
  114. stx z80_e
  115. sta z80_ep
  116. lda z80_d
  117. ldx z80_dp
  118. stx z80_d
  119. sta z80_dp
  120. lda z80_l
  121. ldx z80_lp
  122. stx z80_l
  123. sta z80_lp
  124. lda z80_h
  125. ldx z80_hp
  126. stx z80_h
  127. sta z80_hp
  128. pla ;- pop de
  129. sta z80_d
  130. pla
  131. sta z80_e
  132. inc z80_e ;- inc de ; DE' <- HL + 2
  133. bne *+4
  134. inc z80_d
  135. lda z80_c ;- exx ; DE' <- HL (Saves current pointer into DE')
  136. ldx z80_cp
  137. stx z80_c
  138. sta z80_cp
  139. lda z80_b
  140. ldx z80_bp
  141. stx z80_b
  142. sta z80_bp
  143. lda z80_e
  144. ldx z80_ep
  145. stx z80_e
  146. sta z80_ep
  147. lda z80_d
  148. ldx z80_dp
  149. stx z80_d
  150. sta z80_dp
  151. lda z80_l
  152. ldx z80_lp
  153. stx z80_l
  154. sta z80_lp
  155. lda z80_h
  156. ldx z80_hp
  157. stx z80_h
  158. sta z80_hp
  159. ;- dec hl ; HL = Block start
  160. lda z80_e ;- push de
  161. pha
  162. lda z80_d
  163. pha
  164. lda z80_c ;- push bc
  165. pha
  166. lda z80_b
  167. pha
  168. jsr __MEM_FREE ;- call __MEM_FREE ; Frees current block
  169. pla ;- pop bc
  170. sta z80_b
  171. pla
  172. sta z80_c
  173. lda z80_c ;- push bc
  174. pha
  175. lda z80_b
  176. pha
  177. jsr __MEM_ALLOC ;- call __MEM_ALLOC ; Gets a new block of length BC
  178. pla ;- pop bc
  179. sta z80_b
  180. pla
  181. sta z80_c
  182. pla ;- pop de
  183. sta z80_d
  184. pla
  185. sta z80_e
  186. lda z80_h ;- ld a,h
  187. sta z80_a
  188. ora z80_l ;- or l
  189. ;- ret z ; Return if HL == NULL (No memory)
  190. lda z80_e ;- ld (hl),e
  191. ldy #$00
  192. sta (z80_hl),y
  193. inc z80_l ;- inc hl
  194. bne *+4
  195. inc z80_h
  196. lda z80_d ;- ld (hl),d
  197. ldy #$00
  198. sta (z80_hl),y
  199. inc z80_l ;- inc hl ; Recovers first 2 bytes in HL
  200. bne *+4
  201. inc z80_h
  202. ;- dec bc
  203. ;- dec bc ; BC = BC - 2 (Two bytes copied)
  204. lda z80_b ;- ld a,b
  205. sta z80_a
  206. ora z80_c ;- or c
  207. ;- jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0)
  208. lda z80_c ;- exx
  209. ldx z80_cp
  210. stx z80_c
  211. sta z80_cp
  212. lda z80_b
  213. ldx z80_bp
  214. stx z80_b
  215. sta z80_bp
  216. lda z80_e
  217. ldx z80_ep
  218. stx z80_e
  219. sta z80_ep
  220. lda z80_d
  221. ldx z80_dp
  222. stx z80_d
  223. sta z80_dp
  224. lda z80_l
  225. ldx z80_lp
  226. stx z80_l
  227. sta z80_lp
  228. lda z80_h
  229. ldx z80_hp
  230. stx z80_h
  231. sta z80_hp
  232. lda z80_e ;- push de
  233. pha
  234. lda z80_d
  235. pha
  236. lda z80_c ;- exx
  237. ldx z80_cp
  238. stx z80_c
  239. sta z80_cp
  240. lda z80_b
  241. ldx z80_bp
  242. stx z80_b
  243. sta z80_bp
  244. lda z80_e
  245. ldx z80_ep
  246. stx z80_e
  247. sta z80_ep
  248. lda z80_d
  249. ldx z80_dp
  250. stx z80_d
  251. sta z80_dp
  252. lda z80_l
  253. ldx z80_lp
  254. stx z80_l
  255. sta z80_lp
  256. lda z80_h
  257. ldx z80_hp
  258. stx z80_h
  259. sta z80_hp
  260. pla ;- pop de ; DE <- DE' ; Start of remaining block
  261. sta z80_d
  262. pla
  263. sta z80_e
  264. lda z80_l ;- push hl ; Saves current Block + 2 start
  265. pha
  266. lda z80_h
  267. pha
  268. lda z80_e ;- ex de,hl ; Exchanges them: DE is destiny block
  269. ldx z80_l
  270. stx z80_e
  271. sta z80_l
  272. lda z80_d
  273. ldx z80_h
  274. stx z80_d
  275. sta z80_h
  276. ;- ldir ; Copies BC Bytes
  277. pla ;- pop hl ; Recovers Block + 2 start
  278. sta z80_h
  279. pla
  280. sta z80_l
  281. __REALLOC_END:
  282. ;- dec hl ; Set HL
  283. ;- dec hl ; To begin of block
  284. rts ;- ret
  285. ;- ENDP