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.

206 lines
3.9KB

  1. ; Parse string at (HL) as a hexadecimal value and return value in IX under the
  2. ; same conditions as parseLiteral.
  3. parseHexadecimal:
  4. call hasHexPrefix
  5. ret nz
  6. push hl
  7. push de
  8. ld d, 0
  9. inc hl ; get rid of "0x"
  10. inc hl
  11. call strlen
  12. cp 3
  13. jr c, .single
  14. cp 4
  15. jr c, .doubleShort ; 0x123
  16. cp 5
  17. jr c, .double ; 0x1234
  18. ; too long, error
  19. jr .error
  20. .double:
  21. call parseHexPair
  22. jr c, .error
  23. inc hl ; now HL is on first char of next pair
  24. ld d, a
  25. jr .single
  26. .doubleShort:
  27. ld a, (hl)
  28. call parseHex
  29. jr c, .error
  30. inc hl ; now HL is on first char of next pair
  31. ld d, a
  32. .single:
  33. call parseHexPair
  34. jr c, .error
  35. ld e, a
  36. cp a ; ensure Z
  37. jr .end
  38. .error:
  39. call unsetZ
  40. .end:
  41. push de \ pop ix
  42. pop de
  43. pop hl
  44. ret
  45. ; Sets Z if (HL) has a '0x' prefix.
  46. hasHexPrefix:
  47. ld a, (hl)
  48. cp '0'
  49. ret nz
  50. push hl
  51. inc hl
  52. ld a, (hl)
  53. cp 'x'
  54. pop hl
  55. ret
  56. ; Parse string at (HL) as a binary value (0b010101) and return value in IX.
  57. ; High IX byte is always clear.
  58. ; Sets Z on success.
  59. parseBinaryLiteral:
  60. call hasBinPrefix
  61. ret nz
  62. push bc
  63. push hl
  64. push de
  65. ld d, 0
  66. inc hl ; get rid of "0b"
  67. inc hl
  68. call strlen
  69. or a
  70. jr z, .error ; empty, error
  71. cp 9
  72. jr nc, .error ; >= 9, too long
  73. ; We have a string of 8 or less chars. What we'll do is that for each
  74. ; char, we rotate left and set the LSB according to whether we have '0'
  75. ; or '1'. Error out on anything else. C is our stored result.
  76. ld b, a ; we loop for "strlen" times
  77. ld c, 0 ; our stored result
  78. .loop:
  79. rlc c
  80. ld a, (hl)
  81. inc hl
  82. cp '0'
  83. jr z, .nobit ; no bit to set
  84. cp '1'
  85. jr nz, .error ; not 0 or 1
  86. ; We have a bit to set
  87. inc c
  88. .nobit:
  89. djnz .loop
  90. ld e, c
  91. cp a ; ensure Z
  92. jr .end
  93. .error:
  94. call unsetZ
  95. .end:
  96. push de \ pop ix
  97. pop de
  98. pop hl
  99. pop bc
  100. ret
  101. ; Sets Z if (HL) has a '0b' prefix.
  102. hasBinPrefix:
  103. ld a, (hl)
  104. cp '0'
  105. ret nz
  106. push hl
  107. inc hl
  108. ld a, (hl)
  109. cp 'b'
  110. pop hl
  111. ret
  112. ; Parse string at (HL) and, if it is a char literal, sets Z and return
  113. ; corresponding value in IX. High IX byte is always clear.
  114. ;
  115. ; A valid char literal starts with ', ends with ' and has one character in the
  116. ; middle. No escape sequence are accepted, but ''' will return the apostrophe
  117. ; character.
  118. parseCharLiteral:
  119. ld a, 0x27 ; apostrophe (') char
  120. cp (hl)
  121. ret nz
  122. push hl
  123. push de
  124. inc hl
  125. inc hl
  126. cp (hl)
  127. jr nz, .end ; not ending with an apostrophe
  128. inc hl
  129. ld a, (hl)
  130. or a ; cp 0
  131. jr nz, .end ; string has to end there
  132. ; Valid char, good
  133. ld d, a ; A is zero, take advantage of that
  134. dec hl
  135. dec hl
  136. ld a, (hl)
  137. ld e, a
  138. cp a ; ensure Z
  139. .end:
  140. push de \ pop ix
  141. pop de
  142. pop hl
  143. ret
  144. ; Parses the string at (HL) and returns the 16-bit value in IX. The string
  145. ; can be a decimal literal (1234), a hexadecimal literal (0x1234) or a char
  146. ; literal ('X').
  147. ;
  148. ; As soon as the number doesn't fit 16-bit any more, parsing stops and the
  149. ; number is invalid. If the number is valid, Z is set, otherwise, unset.
  150. parseLiteral:
  151. call parseCharLiteral
  152. ret z
  153. call parseHexadecimal
  154. ret z
  155. call parseBinaryLiteral
  156. ret z
  157. jp parseDecimal
  158. ; Parse string in (HL) and return its numerical value whether its a number
  159. ; literal or a symbol. Returns value in IX.
  160. ; Sets Z if number or symbol is valid, unset otherwise.
  161. parseNumberOrSymbol:
  162. call parseLiteral
  163. ret z
  164. ; Not a number.
  165. ; Is str a single char? If yes, maybe it's a special symbol.
  166. call strIs1L
  167. jr nz, .symbol ; nope
  168. ld a, (hl)
  169. cp '$'
  170. jr z, .returnPC
  171. cp '@'
  172. jr nz, .symbol
  173. ; last val
  174. ld ix, (DIREC_LASTVAL)
  175. ret
  176. .symbol:
  177. push de ; --> lvl 1
  178. call symFindVal ; --> DE
  179. jr nz, .notfound
  180. ; value in DE. We need it in IX
  181. push de \ pop ix
  182. pop de ; <-- lvl 1
  183. cp a ; ensure Z
  184. ret
  185. .notfound:
  186. pop de ; <-- lvl 1
  187. ; If not found, check if we're in first pass. If we are, it doesn't
  188. ; matter that we didn't find our symbol. Return success anyhow.
  189. ; Otherwise return error. Z is already unset, so in fact, this is the
  190. ; same as jumping to zasmIsFirstPass
  191. jp zasmIsFirstPass
  192. .returnPC:
  193. push hl
  194. call zasmGetPC
  195. push hl \ pop ix
  196. pop hl
  197. ret