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.

254 lines
4.3KB

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