string.asm 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. ; String library
  2. ;
  3. #include once <free.asm>
  4. ;
  5. __STR_ISNULL: ; Returns A = FF if HL is 0, 0 otherwise
  6. lda z80_h ;- ld a,h
  7. sta z80_a
  8. ;- or l
  9. ;- sub 1 ; Only CARRY if HL is NULL
  10. ;- sbc a, a ; Only FF if HL is NULL (0 otherwise)
  11. rts ;- ret
  12. __STRCMP: ; Compares strings at HL, DE: Returns 0 if EQual, -1 if HL < DE, +1 if HL > DE
  13. ; A register is preserved and returned in A'
  14. ;- PROC ; __FASTCALL__
  15. ;- LOCAL __STRCMPZERO
  16. ;- LOCAL __STRCMPEXIT
  17. ;- LOCAL __STRCMPLOOP
  18. ;- LOCAL __NOPRESERVEBC
  19. ;- LOCAL __EQULEN
  20. ;- LOCAL __EQULEN1
  21. ;- LOCAL __HLZERO
  22. ;- ex af, af' ; Saves current A register in A' (it's used by STRXX comparison functions)
  23. lda z80_h ;- ld a,h
  24. sta z80_a
  25. ;- or l
  26. ;- jr z, __HLZERO
  27. lda z80_d ;- ld a,d
  28. sta z80_a
  29. ;- or e
  30. ;- ld a, 1
  31. ;- ret z ; Returns +1 if HL is not NULL and DE is NULL
  32. ;- ld c, (hl)
  33. ;- inc hl
  34. ;- ld b, (hl)
  35. ;- inc hl ; BC = LEN(a$)
  36. ;- push hl ; HL = &a$, saves it
  37. ;- ex de, hl
  38. ;- ld e, (hl)
  39. ;- inc hl
  40. ;- ld d, (hl)
  41. ;- inc hl
  42. ;- ex de, hl ; HL = LEN(b$), de = &b$
  43. ; At this point Carry is cleared, and A reg. = 1
  44. ;- sbc hl, bc ; Carry if len(b$) > len(a$)
  45. ;- jr z, __EQULEN ; Jump if they have the same length so A reg. = 0
  46. ;- jr c, __EQULEN1 ; Jump if len(b$) > len(a$) so A reg. = 1
  47. __NOPRESERVEBC:
  48. ;- add hl, bc ; Restore HL (original length)
  49. ;- ld b, h ; len(b$) <= len(a$)
  50. ;- ld c, l ; so BC = hl
  51. ;- dec a ; At this point A register = 0, it must be -1 since len(a$) > len(b$)
  52. __EQULEN:
  53. ;- dec a ; A = 0 if len(a$) = len(b$), -1 otherwise
  54. __EQULEN1:
  55. ;- pop hl ; Recovers A$ pointer
  56. ;- push af ; Saves A for later (Value to return if strings reach the end)
  57. ;- ld a, b
  58. ;- or c
  59. ;- jr z, __STRCMPZERO ; empty string being compared
  60. ; At this point: BC = lesser length, DE and HL points to b$ and a$ chars respectively
  61. __STRCMPLOOP:
  62. ;- ld a, (de)
  63. ;- cpi
  64. ;- jr nz, __STRCMPEXIT ; (HL) != (DE). Examine carry
  65. ;- jp po, __STRCMPZERO ; END of string (both are equal)
  66. ;- inc de
  67. ;- jp __STRCMPLOOP
  68. __STRCMPZERO:
  69. ;- pop af ; This is -1 if len(a$) < len(b$), +1 if len(b$) > len(a$), 0 otherwise
  70. rts ;- ret
  71. __STRCMPEXIT: ; Sets A with the following value
  72. ;- dec hl ; Get back to the last char
  73. ;- cp (hl)
  74. ;- sbc a, a ; A = -1 if carry => (DE) < (HL); 0 otherwise (DE) > (HL)
  75. ;- cpl ; A = -1 if (HL) < (DE), 0 otherwise
  76. ;- add a, a ; A = A * 2 (thus -2 or 0)
  77. ;- inc a ; A = A + 1 (thus -1 or 1)
  78. pla ;- pop bc ; Discard top of the stack
  79. sta z80_b
  80. pla
  81. sta z80_c
  82. rts ;- ret
  83. __HLZERO:
  84. ora z80_d ;- or d
  85. ora z80_e ;- or e
  86. ;- ret z ; Returns 0 (EQ) if HL == DE == NULL
  87. ;- ld a, -1
  88. rts ;- ret ; Returns -1 if HL is NULL and DE is not NULL
  89. ;- ENDP
  90. ; The following routines perform string comparison operations (<, >, ==, etc...)
  91. ; On return, A will contain 0 for False, other value for True
  92. ; Register A' will determine whether the incoming strings (HL, DE) will be freed
  93. ; from dynamic memory on exit:
  94. ; Bit 0 => 1 means HL will be freed.
  95. ; Bit 1 => 1 means DE will be freed.
  96. __STREQ: ; Compares a$ == b$ (HL = ptr a$, DE = ptr b$). Returns FF (True) or 0 (False)
  97. lda z80_l ;- push hl
  98. pha
  99. lda z80_h
  100. pha
  101. lda z80_e ;- push de
  102. pha
  103. lda z80_d
  104. pha
  105. jsr __STRCMP ;- call __STRCMP
  106. pla ;- pop de
  107. sta z80_d
  108. pla
  109. sta z80_e
  110. pla ;- pop hl
  111. sta z80_h
  112. pla
  113. sta z80_l
  114. ;inc a ; If A == -1, return 0
  115. ;jp z, __FREE_STR
  116. ;dec a ;
  117. ;dec a ; Return -1 if a = 0 (True), returns 0 if A == 1 (False)
  118. ;- sub 1
  119. ;- sbc a, a
  120. jmp __FREE_STR ;- jp __FREE_STR
  121. __STRNE: ; Compares a$ != b$ (HL = ptr a$, DE = ptr b$). Returns FF (True) or 0 (False)
  122. lda z80_l ;- push hl
  123. pha
  124. lda z80_h
  125. pha
  126. lda z80_e ;- push de
  127. pha
  128. lda z80_d
  129. pha
  130. jsr __STRCMP ;- call __STRCMP
  131. pla ;- pop de
  132. sta z80_d
  133. pla
  134. sta z80_e
  135. pla ;- pop hl
  136. sta z80_h
  137. pla
  138. sta z80_l
  139. ;jp z, __FREE_STR
  140. ;ld a, 0FFh ; Returns 0xFFh (True)
  141. jmp __FREE_STR ;- jp __FREE_STR
  142. __STRLT: ; Compares a$ < b$ (HL = ptr a$, DE = ptr b$). Returns FF (True) or 0 (False)
  143. lda z80_l ;- push hl
  144. pha
  145. lda z80_h
  146. pha
  147. lda z80_e ;- push de
  148. pha
  149. lda z80_d
  150. pha
  151. jsr __STRCMP ;- call __STRCMP
  152. pla ;- pop de
  153. sta z80_d
  154. pla
  155. sta z80_e
  156. pla ;- pop hl
  157. sta z80_h
  158. pla
  159. sta z80_l
  160. jeq __FREE_STR ;- jp z, __FREE_STR ; Returns 0 if A == B
  161. ;- dec a ; Returns 0 if A == 1 => a$ > b$
  162. ;jp z, __FREE_STR
  163. ;inc a ; A = FE now (-2). Set it to FF and return
  164. jmp __FREE_STR ;- jp __FREE_STR
  165. __STRLE: ; Compares a$ <= b$ (HL = ptr a$, DE = ptr b$). Returns FF (True) or 0 (False)
  166. lda z80_l ;- push hl
  167. pha
  168. lda z80_h
  169. pha
  170. lda z80_e ;- push de
  171. pha
  172. lda z80_d
  173. pha
  174. jsr __STRCMP ;- call __STRCMP
  175. pla ;- pop de
  176. sta z80_d
  177. pla
  178. sta z80_e
  179. pla ;- pop hl
  180. sta z80_h
  181. pla
  182. sta z80_l
  183. ;- dec a ; Returns 0 if A == 1 => a$ < b$
  184. ;jp z, __FREE_STR
  185. ;ld a, 0FFh ; A = FE now (-2). Set it to FF and return
  186. jmp __FREE_STR ;- jp __FREE_STR
  187. __STRGT: ; Compares a$ > b$ (HL = ptr a$, DE = ptr b$). Returns FF (True) or 0 (False)
  188. lda z80_l ;- push hl
  189. pha
  190. lda z80_h
  191. pha
  192. lda z80_e ;- push de
  193. pha
  194. lda z80_d
  195. pha
  196. jsr __STRCMP ;- call __STRCMP
  197. pla ;- pop de
  198. sta z80_d
  199. pla
  200. sta z80_e
  201. ;- pop hl
  202. jeq __FREE_STR ;- jp z, __FREE_STR ; Returns 0 if A == B
  203. ;- inc a ; Returns 0 if A == -1 => a$ < b$
  204. ;jp z, __FREE_STR ; Returns 0 if A == B
  205. ;ld a, 0FFh ; A = FE now (-2). Set it to FF and return
  206. jmp __FREE_STR ;- jp __FREE_STR
  207. __STRGE: ; Compares a$ >= b$ (HL = ptr a$, DE = ptr b$). Returns FF (True) or 0 (False)
  208. lda z80_l ;- push hl
  209. pha
  210. lda z80_h
  211. pha
  212. lda z80_e ;- push de
  213. pha
  214. lda z80_d
  215. pha
  216. jsr __STRCMP ;- call __STRCMP
  217. pla ;- pop de
  218. sta z80_d
  219. pla
  220. sta z80_e
  221. pla ;- pop hl
  222. sta z80_h
  223. pla
  224. sta z80_l
  225. clc ;- inc a ; Returns 0 if A == -1 => a$ < b$
  226. adc #$01
  227. ;jr z, __FREE_STR
  228. ;ld a, 0FFh ; A = FE now (-2). Set it to FF and return
  229. __FREE_STR: ; This exit point will test A' for bits 0 and 1
  230. ; If bit 0 is 1 => Free memory from HL pointer
  231. ; If bit 1 is 1 => Free memory from DE pointer
  232. ; Finally recovers A, to return the result
  233. ;- PROC
  234. ;- LOCAL __FREE_STR2
  235. ;- LOCAL __FREE_END
  236. ldx z80_ap ;- ex af,af'
  237. sta z80_ap
  238. txa
  239. lda z80_a ;- bit 0,a
  240. bit 0
  241. jeq __FREE_STR2 ;- jr z, __FREE_STR2
  242. pha ;- push af
  243. php
  244. lda z80_e ;- push de
  245. pha
  246. lda z80_d
  247. pha
  248. jsr __MEM_FREE ;- call __MEM_FREE
  249. pla ;- pop de
  250. sta z80_d
  251. pla
  252. sta z80_e
  253. plp ;- pop af
  254. pha
  255. __FREE_STR2:
  256. lda z80_a ;- bit 1,a
  257. bit 1
  258. jeq __FREE_END ;- jr z, __FREE_END
  259. lda z80_e ;- ex de,hl
  260. ldx z80_l
  261. stx z80_e
  262. sta z80_l
  263. lda z80_d
  264. ldx z80_h
  265. stx z80_d
  266. sta z80_h
  267. jsr __MEM_FREE ;- call __MEM_FREE
  268. __FREE_END:
  269. ldx z80_ap ;- ex af,af'
  270. sta z80_ap
  271. txa
  272. rts ;- ret
  273. ;- ENDP