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.

235 lines
4.0KB

  1. ; core
  2. ;
  3. ; Routines used by pretty much all parts. You will want to include it first
  4. ; in your glue file.
  5. ; *** CONSTS ***
  6. .equ ASCII_CR 0x0d
  7. .equ ASCII_LF 0x0a
  8. ; *** DATA ***
  9. ; Useful data to point to, when a pointer is needed.
  10. P_NULL: .db 0
  11. ; *** REGISTER FIDDLING ***
  12. ; add the value of A into DE
  13. addDE:
  14. push af
  15. add a, e
  16. jr nc, .end ; no carry? skip inc
  17. inc d
  18. .end:
  19. ld e, a
  20. pop af
  21. noop: ; piggy backing on the first "ret" we have
  22. ret
  23. ; copy (DE) into DE, little endian style (addresses in z80 are always have
  24. ; their LSB before their MSB)
  25. intoDE:
  26. push af
  27. ld a, (de)
  28. inc de
  29. ex af, af'
  30. ld a, (de)
  31. ld d, a
  32. ex af, af'
  33. ld e, a
  34. pop af
  35. ret
  36. intoHL:
  37. push de
  38. ex de, hl
  39. call intoDE
  40. ex de, hl
  41. pop de
  42. ret
  43. ; add the value of A into HL
  44. addHL:
  45. push af
  46. add a, l
  47. jr nc, .end ; no carry? skip inc
  48. inc h
  49. .end:
  50. ld l, a
  51. pop af
  52. ret
  53. ; subtract the value of A from HL
  54. subHL:
  55. push af
  56. ; To avoid having to swap L and A, we sub "backwards", that is, we add
  57. ; a NEGated value. This means that the carry flag is inverted
  58. neg
  59. add a, l
  60. jr c, .end ; if carry, no carry. :)
  61. dec h
  62. .end:
  63. ld l, a
  64. pop af
  65. ret
  66. ; Compare HL with DE and sets Z and C in the same way as a regular cp X where
  67. ; HL is A and DE is X.
  68. cpHLDE:
  69. ld a, h
  70. cp d
  71. ret nz ; if not equal, flags are correct
  72. ld a, l
  73. cp e
  74. ret ; flags are correct
  75. ; Write the contents of HL in (DE)
  76. writeHLinDE:
  77. push af
  78. ld a, l
  79. ld (de), a
  80. inc de
  81. ld a, h
  82. ld (de), a
  83. dec de
  84. pop af
  85. ret
  86. ; jump to the location pointed to by IX. This allows us to call IX instead of
  87. ; just jumping it. We use IX because we seldom use this for arguments.
  88. callIX:
  89. jp (ix)
  90. callIY:
  91. jp (iy)
  92. ; Ensures that Z is unset (more complicated than it sounds...)
  93. unsetZ:
  94. push bc
  95. ld b, a
  96. inc b
  97. cp b
  98. pop bc
  99. ret
  100. ; *** STRINGS ***
  101. ; Fill B bytes at (HL) with A
  102. fill:
  103. push bc
  104. push hl
  105. .loop:
  106. ld (hl), a
  107. inc hl
  108. djnz .loop
  109. pop hl
  110. pop bc
  111. ret
  112. ; Increase HL until the memory address it points to is equal to A for a maximum
  113. ; of 0xff bytes. Returns the new HL value as well as the number of bytes
  114. ; iterated in A.
  115. ; If a null char is encountered before we find A, processing is stopped in the
  116. ; same way as if we found our char (so, we look for A *or* 0)
  117. ; Set Z if the character is found. Unsets it if not
  118. findchar:
  119. push bc
  120. ld c, a ; let's use C as our cp target
  121. ld a, 0xff
  122. ld b, a
  123. .loop: ld a, (hl)
  124. cp c
  125. jr z, .match
  126. or a ; cp 0
  127. jr z, .nomatch
  128. inc hl
  129. djnz .loop
  130. .nomatch:
  131. call unsetZ
  132. jr .end
  133. .match:
  134. ; We ran 0xff-B loops. That's the result that goes in A.
  135. ld a, 0xff
  136. sub b
  137. cp a ; ensure Z
  138. .end:
  139. pop bc
  140. ret
  141. ; Format the lower nibble of A into a hex char and stores the result in A.
  142. fmtHex:
  143. and 0xf
  144. cp 10
  145. jr nc, .alpha ; if >= 10, we have alpha
  146. add a, '0'
  147. ret
  148. .alpha:
  149. add a, 'A'-10
  150. ret
  151. ; Formats value in A into a string hex pair. Stores it in the memory location
  152. ; that HL points to. Does *not* add a null char at the end.
  153. fmtHexPair:
  154. push af
  155. ; let's start with the rightmost char
  156. inc hl
  157. call fmtHex
  158. ld (hl), a
  159. ; and now with the leftmost
  160. dec hl
  161. pop af
  162. push af
  163. and 0xf0
  164. rra \ rra \ rra \ rra
  165. call fmtHex
  166. ld (hl), a
  167. pop af
  168. ret
  169. ; Compares strings pointed to by HL and DE up to A count of characters. If
  170. ; equal, Z is set. If not equal, Z is reset.
  171. strncmp:
  172. push bc
  173. push hl
  174. push de
  175. ld b, a
  176. .loop:
  177. ld a, (de)
  178. cp (hl)
  179. jr nz, .end ; not equal? break early. NZ is carried out
  180. ; to the called
  181. cp 0 ; If our chars are null, stop the cmp
  182. jr z, .end ; The positive result will be carried to the
  183. ; caller
  184. inc hl
  185. inc de
  186. djnz .loop
  187. ; We went through all chars with success, but our current Z flag is
  188. ; unset because of the cp 0. Let's do a dummy CP to set the Z flag.
  189. cp a
  190. .end:
  191. pop de
  192. pop hl
  193. pop bc
  194. ; Because we don't call anything else than CP that modify the Z flag,
  195. ; our Z value will be that of the last cp (reset if we broke the loop
  196. ; early, set otherwise)
  197. ret
  198. ; Transforms the character in A, if it's in the a-z range, into its upcase
  199. ; version.
  200. upcase:
  201. cp 'a'
  202. ret c ; A < 'a'. nothing to do
  203. cp 'z'+1
  204. ret nc ; A >= 'z'+1. nothing to do
  205. ; 'a' - 'A' == 0x20
  206. sub 0x20
  207. ret