Mirror of CollapseOS
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

263 Zeilen
4.5KB

  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. ; A is preserved through some register hocus pocus: having cpHLDE destroying
  78. ; A bit me too many times.
  79. cpHLDE:
  80. push bc
  81. ld b, a ; preserve A
  82. ld a, h
  83. cp d
  84. jr nz, .end ; if not equal, flags are correct
  85. ld a, l
  86. cp e
  87. ; flags are correct
  88. .end:
  89. ; restore A but don't touch flags
  90. ld a, b
  91. pop bc
  92. ret
  93. ; Write the contents of HL in (DE)
  94. writeHLinDE:
  95. push af
  96. ld a, l
  97. ld (de), a
  98. inc de
  99. ld a, h
  100. ld (de), a
  101. dec de
  102. pop af
  103. ret
  104. ; Call the method (IX) is a pointer to. In other words, call intoIX before
  105. ; callIX
  106. callIXI:
  107. push ix
  108. call intoIX
  109. call callIX
  110. pop ix
  111. ret
  112. ; jump to the location pointed to by IX. This allows us to call IX instead of
  113. ; just jumping it. We use IX because we seldom use this for arguments.
  114. callIX:
  115. jp (ix)
  116. callIY:
  117. jp (iy)
  118. ; Ensures that Z is unset (more complicated than it sounds...)
  119. unsetZ:
  120. push bc
  121. ld b, a
  122. inc b
  123. cp b
  124. pop bc
  125. ret
  126. ; *** STRINGS ***
  127. ; Fill B bytes at (HL) with A
  128. fill:
  129. push bc
  130. push hl
  131. .loop:
  132. ld (hl), a
  133. inc hl
  134. djnz .loop
  135. pop hl
  136. pop bc
  137. ret
  138. ; Increase HL until the memory address it points to is equal to A for a maximum
  139. ; of 0xff bytes. Returns the new HL value as well as the number of bytes
  140. ; iterated in A.
  141. ; If a null char is encountered before we find A, processing is stopped in the
  142. ; same way as if we found our char (so, we look for A *or* 0)
  143. ; Set Z if the character is found. Unsets it if not
  144. findchar:
  145. push bc
  146. ld c, a ; let's use C as our cp target
  147. ld a, 0xff
  148. ld b, a
  149. .loop: ld a, (hl)
  150. cp c
  151. jr z, .match
  152. or a ; cp 0
  153. jr z, .nomatch
  154. inc hl
  155. djnz .loop
  156. .nomatch:
  157. call unsetZ
  158. jr .end
  159. .match:
  160. ; We ran 0xff-B loops. That's the result that goes in A.
  161. ld a, 0xff
  162. sub b
  163. cp a ; ensure Z
  164. .end:
  165. pop bc
  166. ret
  167. ; Format the lower nibble of A into a hex char and stores the result in A.
  168. fmtHex:
  169. and 0xf
  170. cp 10
  171. jr nc, .alpha ; if >= 10, we have alpha
  172. add a, '0'
  173. ret
  174. .alpha:
  175. add a, 'A'-10
  176. ret
  177. ; Formats value in A into a string hex pair. Stores it in the memory location
  178. ; that HL points to. Does *not* add a null char at the end.
  179. fmtHexPair:
  180. push af
  181. ; let's start with the rightmost char
  182. inc hl
  183. call fmtHex
  184. ld (hl), a
  185. ; and now with the leftmost
  186. dec hl
  187. pop af
  188. push af
  189. and 0xf0
  190. rra \ rra \ rra \ rra
  191. call fmtHex
  192. ld (hl), a
  193. pop af
  194. ret
  195. ; Compares strings pointed to by HL and DE up to A count of characters. If
  196. ; equal, Z is set. If not equal, Z is reset.
  197. strncmp:
  198. push bc
  199. push hl
  200. push de
  201. ld b, a
  202. .loop:
  203. ld a, (de)
  204. cp (hl)
  205. jr nz, .end ; not equal? break early. NZ is carried out
  206. ; to the called
  207. cp 0 ; If our chars are null, stop the cmp
  208. jr z, .end ; The positive result will be carried to the
  209. ; caller
  210. inc hl
  211. inc de
  212. djnz .loop
  213. ; We went through all chars with success, but our current Z flag is
  214. ; unset because of the cp 0. Let's do a dummy CP to set the Z flag.
  215. cp a
  216. .end:
  217. pop de
  218. pop hl
  219. pop bc
  220. ; Because we don't call anything else than CP that modify the Z flag,
  221. ; our Z value will be that of the last cp (reset if we broke the loop
  222. ; early, set otherwise)
  223. ret
  224. ; Transforms the character in A, if it's in the a-z range, into its upcase
  225. ; version.
  226. upcase:
  227. cp 'a'
  228. ret c ; A < 'a'. nothing to do
  229. cp 'z'+1
  230. ret nc ; A >= 'z'+1. nothing to do
  231. ; 'a' - 'A' == 0x20
  232. sub 0x20
  233. ret