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.

238 lines
4.4KB

  1. ; run RLA the number of times specified in B
  2. rlaX:
  3. ; first, see if B == 0 to see if we need to bail out
  4. inc b
  5. dec b
  6. ret z ; Z flag means we had B = 0
  7. .loop: rla
  8. djnz .loop
  9. ret
  10. callHL:
  11. jp (hl)
  12. ret
  13. ; HL - DE -> HL
  14. subDEFromHL:
  15. push af
  16. ld a, l
  17. sub e
  18. ld l, a
  19. ld a, h
  20. sbc a, d
  21. ld h, a
  22. pop af
  23. ret
  24. ; make Z the opposite of what it is now
  25. toggleZ:
  26. jp z, unsetZ
  27. cp a
  28. ret
  29. ; Returns length of string at (HL) in A.
  30. ; Doesn't include null termination.
  31. strlen:
  32. push bc
  33. push hl
  34. ld bc, 0
  35. ld a, 0 ; look for null char
  36. .loop:
  37. cpi
  38. jp z, .found
  39. jr .loop
  40. .found:
  41. ; How many char do we have? the (NEG BC)-1, which started at 0 and
  42. ; decreased at each CPI call. In this routine, we stay in the 8-bit
  43. ; realm, so C only.
  44. ld a, c
  45. neg
  46. dec a
  47. pop hl
  48. pop bc
  49. ret
  50. ; Sets Z if string at (HL) is one character long
  51. strIs1L:
  52. xor a
  53. cp (hl)
  54. jp z, unsetZ ; empty string
  55. inc hl
  56. cp (hl) ; Z has proper value
  57. dec hl ; doesn't touch Z
  58. ret
  59. ; Compares strings pointed to by HL and DE up to A count of characters in a
  60. ; case-insensitive manner.
  61. ; If equal, Z is set. If not equal, Z is reset.
  62. strncmpI:
  63. push bc
  64. push hl
  65. push de
  66. ld b, a
  67. .loop:
  68. ld a, (de)
  69. call upcase
  70. ld c, a
  71. ld a, (hl)
  72. call upcase
  73. cp c
  74. jr nz, .end ; not equal? break early. NZ is carried out
  75. ; to the called
  76. or a ; cp 0. If our chars are null, stop the cmp
  77. jr z, .end ; The positive result will be carried to the
  78. ; caller
  79. inc hl
  80. inc de
  81. djnz .loop
  82. ; Success
  83. ; We went through all chars with success. Ensure Z
  84. cp a
  85. .end:
  86. pop de
  87. pop hl
  88. pop bc
  89. ; Because we don't call anything else than CP that modify the Z flag,
  90. ; our Z value will be that of the last cp (reset if we broke the loop
  91. ; early, set otherwise)
  92. ret
  93. ; Compares strings pointed to by HL and DE until one of them hits its null char.
  94. ; If equal, Z is set. If not equal, Z is reset.
  95. strcmp:
  96. push hl
  97. push de
  98. .loop:
  99. ld a, (de)
  100. cp (hl)
  101. jr nz, .end ; not equal? break early. NZ is carried out
  102. ; to the called
  103. cp 0 ; If our chars are null, stop the cmp
  104. jr z, .end ; The positive result will be carried to the
  105. ; caller
  106. inc hl
  107. inc de
  108. jr .loop
  109. .end:
  110. pop de
  111. pop hl
  112. ; Because we don't call anything else than CP that modify the Z flag,
  113. ; our Z value will be that of the last cp (reset if we broke the loop
  114. ; early, set otherwise)
  115. ret
  116. ; If string at (HL) starts with ( and ends with ), "enter" into the parens
  117. ; (advance HL and put a null char at the end of the string) and set Z.
  118. ; Otherwise, do nothing and reset Z.
  119. enterParens:
  120. ld a, (hl)
  121. cp '('
  122. ret nz ; nothing to do
  123. push hl
  124. ld a, 0 ; look for null char
  125. ; advance until we get null
  126. .loop:
  127. cpi
  128. jp z, .found
  129. jr .loop
  130. .found:
  131. dec hl ; cpi over-advances. go back to null-char
  132. dec hl ; looking at the last char before null
  133. ld a, (hl)
  134. cp ')'
  135. jr nz, .doNotEnter
  136. ; We have parens. While we're here, let's put a null
  137. xor a
  138. ld (hl), a
  139. pop hl ; back at the beginning. Let's advance.
  140. inc hl
  141. cp a ; ensure Z
  142. ret ; we're good!
  143. .doNotEnter:
  144. pop hl
  145. call unsetZ
  146. ret
  147. ; Scans (HL) and sets Z according to whether the string is double quoted, that
  148. ; is, starts with a " and ends with a ". If it is double quoted, "enter" them,
  149. ; that is, advance HL by one and transform the ending quote into a null char.
  150. ; If the string isn't double-enquoted, HL isn't changed.
  151. enterDoubleQuotes:
  152. ld a, (hl)
  153. cp '"'
  154. ret nz
  155. push hl
  156. inc hl
  157. ld a, (hl)
  158. or a ; already end of string?
  159. jr z, .nomatch
  160. xor a
  161. call findchar ; go to end of string
  162. dec hl
  163. ld a, (hl)
  164. cp '"'
  165. jr nz, .nomatch
  166. ; We have a match, replace ending quote with null char
  167. xor a
  168. ld (hl), a
  169. ; Good, let's go back
  170. pop hl
  171. ; ... but one char further
  172. inc hl
  173. cp a ; ensure Z
  174. ret
  175. .nomatch:
  176. call unsetZ
  177. pop hl
  178. ret
  179. ; Find string (HL) in string list (DE) of size B, in a case-insensitive manner.
  180. ; Each string is C bytes wide.
  181. ; Returns the index of the found string. Sets Z if found, unsets Z if not found.
  182. findStringInList:
  183. push de
  184. push bc
  185. .loop:
  186. ld a, c
  187. call strncmpI
  188. ld a, c
  189. call addDE
  190. jr z, .match
  191. djnz .loop
  192. ; no match, Z is unset
  193. pop bc
  194. pop de
  195. ret
  196. .match:
  197. ; Now, we want the index of our string, which is equal to our initial B
  198. ; minus our current B. To get this, we have to play with our registers
  199. ; and stack a bit.
  200. ld d, b
  201. pop bc
  202. ld a, b
  203. sub d
  204. pop de
  205. cp a ; ensure Z
  206. ret
  207. ; DE * BC -> DE (high) and HL (low)
  208. multDEBC:
  209. ld hl, 0
  210. ld a, 0x10
  211. .loop:
  212. add hl, hl
  213. rl e
  214. rl d
  215. jr nc, .noinc
  216. add hl, bc
  217. jr nc, .noinc
  218. inc de
  219. .noinc:
  220. dec a
  221. jr nz, .loop
  222. ret