Mirror of CollapseOS
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

183 lines
3.9KB

  1. ; *** Consts ***
  2. ; maximum number of lines (line number maximum, however, is always 0xffff)
  3. .equ BUF_MAXLINES 0x100
  4. ; Size of the string pool
  5. .equ BUF_POOLSIZE 0x1000
  6. ; *** Variables ***
  7. ; A pointer to the first free line
  8. .equ BUF_LFREE BUF_RAMSTART
  9. ; A pointer to the first free byte in the pool
  10. .equ BUF_PFREE @+2
  11. ; The line index. Each record consists of 4 bytes: 2 for line number,
  12. ; 2 for pointer to string in pool. Kept in order of line numbers.
  13. .equ BUF_LINES @+2
  14. ; The line pool. A list of null terminated strings. BUF_LINES records point
  15. ; to those strings.
  16. .equ BUF_POOL @+BUF_MAXLINES*4
  17. .equ BUF_RAMEND @+BUF_POOLSIZE
  18. bufInit:
  19. ld hl, BUF_LINES
  20. ld (BUF_LFREE), hl
  21. ld hl, BUF_POOL
  22. ld (BUF_PFREE), hl
  23. cp a ; ensure Z
  24. ret
  25. ; Add line at (HL) with line number DE to the buffer. The string at (HL) should
  26. ; not contain the line number prefix or the whitespace between the line number
  27. ; and the comment.
  28. ; Note that an empty string is *not* an error. It will be saved as a line.
  29. ; Z for success.
  30. ; Error conditions are:
  31. ; * not enough space in the pool
  32. ; * not enough space in the line index
  33. bufAdd:
  34. ; Check whether we have enough pool space. This is done in all cases.
  35. call strlen
  36. inc a ; strlen doesn't include line termination
  37. exx ; preserve HL and DE
  38. ld hl, (BUF_PFREE)
  39. call addHL
  40. ld de, BUF_RAMEND
  41. sbc hl, de
  42. exx ; restore
  43. ; no carry? HL >= BUF_RAMEND, error. Z already unset
  44. ret nc
  45. ; Check the kind of operation we make: add, insert or replace?
  46. call bufFind
  47. jr z, .replace ; exact match, replace
  48. call c, .insert ; near match, insert
  49. ; do we have enough index space?
  50. exx ; preserve HL and DE
  51. ld hl, (BUF_LFREE)
  52. ld de, BUF_POOL-4
  53. or a ; reset carry
  54. sbc hl, de
  55. exx ; restore
  56. ; no carry? HL >= BUF_POOL, error. Z already unset
  57. ret nc
  58. ; We have enough space.
  59. ; set line index data
  60. push de ; --> lvl 1
  61. ld (ix), e
  62. ld (ix+1), d
  63. ld de, (BUF_PFREE)
  64. ld (ix+2), e
  65. ld (ix+3), d
  66. ; Increase line index size
  67. ld de, (BUF_LFREE)
  68. inc de \ inc de \ inc de \ inc de
  69. ld (BUF_LFREE), de
  70. ; Fourth step: copy string to pool
  71. ld de, (BUF_PFREE)
  72. call strcpyM
  73. ld (BUF_PFREE), de
  74. pop de ; <-- lvl 1
  75. ret
  76. ; No need to add a new line, just replace the current one.
  77. .replace:
  78. ld (ix), e
  79. ld (ix+1), d
  80. push de
  81. ld de, (BUF_PFREE)
  82. ld (ix+2), e
  83. ld (ix+3), d
  84. call strcpyM
  85. ld (BUF_PFREE), de
  86. pop de
  87. ret
  88. ; An insert is exactly like an add, except that lines following insertion point
  89. ; first.
  90. .insert:
  91. push hl
  92. push de
  93. push bc
  94. ; We want a LDDR that moves from (BUF_LFREE)-1 to (BUF_LFREE)+3
  95. ; for a count of (BUF_LFREE)-BUF_LINES
  96. ld hl, (BUF_LFREE)
  97. ld de, BUF_LINES
  98. or a ; clear carry
  99. sbc hl, de
  100. ld b, h
  101. ld c, l
  102. ld hl, (BUF_LFREE)
  103. ld d, h
  104. ld e, l
  105. dec hl
  106. inc de \ inc de \ inc de
  107. lddr
  108. pop bc
  109. pop de
  110. pop hl
  111. ret
  112. ; Set IX to point to the beginning of the pool.
  113. ; Z set if (IX) is a valid line, unset if the pool is empty.
  114. bufFirst:
  115. ld ix, BUF_LINES
  116. jp bufEOF
  117. ; Given a valid line record in IX, move IX to the next line.
  118. ; This routine doesn't check that IX is valid. Ensure IX validity before
  119. ; calling.
  120. bufNext:
  121. inc ix \ inc ix \ inc ix \ inc ix
  122. jp bufEOF
  123. ; Returns whether line index at IX is past the end of file, that is,
  124. ; whether IX == (BUF_LFREE)
  125. ; Z is set when not EOF, unset when EOF.
  126. bufEOF:
  127. push hl
  128. push de
  129. push ix \ pop hl
  130. or a ; clear carry
  131. ld de, (BUF_LFREE)
  132. sbc hl, de
  133. jr z, .empty
  134. cp a ; ensure Z
  135. .end:
  136. pop de
  137. pop hl
  138. ret
  139. .empty:
  140. call unsetZ
  141. jr .end
  142. ; Given a line index in (IX), set HL to its associated string pointer.
  143. bufStr:
  144. ld l, (ix+2)
  145. ld h, (ix+3)
  146. ret
  147. ; Browse lines looking for number DE. Set IX to point to one of these :
  148. ; 1 - an exact match
  149. ; 2 - the first found line to have a higher line number
  150. ; 3 - EOF
  151. ; Set Z on an exact match, C on a near match, NZ and NC on EOF.
  152. bufFind:
  153. call bufFirst
  154. ret nz
  155. .loop:
  156. ld a, d
  157. cp (ix+1)
  158. ret c ; D < (IX+1), situation 2
  159. jr nz, .next
  160. ld a, e
  161. cp (ix)
  162. ret c ; E < (IX), situation 2
  163. ret z ; exact match!
  164. .next:
  165. call bufNext
  166. ret nz
  167. jr .loop