strslice.asm 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. ; String slicing library
  2. ; HL = Str pointer
  3. ; DE = String start
  4. ; BC = String character end
  5. ; A register => 0 => the HL pointer wont' be freed from the HEAP
  6. ; e.g. a$(5 TO 10) => HL = a$; DE = 5; BC = 10
  7. ; This implements a$(X to Y) being X and Y first and
  8. ; last characters respectively. If X > Y, NULL is returned
  9. ; Otherwise returns a pointer to a$ FROM X to Y (starting from 0)
  10. ; if Y > len(a$), then a$ will be padded with spaces (reallocating
  11. ; it in dynamic memory if needed). Returns pointer (HL) to resulting
  12. ; string. NULL (0) if no memory for padding.
  13. ;
  14. #include once <strlen.asm>
  15. #include once <alloc.asm>
  16. #include once <free.asm>
  17. __STRSLICE: ; Callee entry
  18. pla ;- pop hl ; Return ADDRESS
  19. sta z80_h
  20. pla
  21. sta z80_l
  22. pla ;- pop bc ; Last char pos
  23. sta z80_b
  24. pla
  25. sta z80_c
  26. pla ;- pop de ; 1st char pos
  27. sta z80_d
  28. pla
  29. sta z80_e
  30. tsx ;- ex (sp), hl ; CALLEE. -> String start
  31. lda $0103,x
  32. ldy z80_h
  33. sta z80_h
  34. tya
  35. sta $0103,x
  36. lda $0104,x
  37. ldy z80_l
  38. sta z80_l
  39. tya
  40. sta $104,x
  41. __STRSLICE_FAST: ; __FASTCALL__ Entry
  42. ;- PROC
  43. ;- LOCAL __CONT
  44. ;- LOCAL __EMPTY
  45. ;- LOCAL __FREE_ON_EXIT
  46. lda z80_l ;- push hl ; Stores original HL pointer to be recovered on exit
  47. pha
  48. lda z80_h
  49. pha
  50. ldx z80_ap ;- ex af,af' ; Saves A register for later
  51. sta z80_ap
  52. txa
  53. lda z80_l ;- push hl
  54. pha
  55. lda z80_h
  56. pha
  57. jsr __STRLEN ;- call __STRLEN
  58. inc z80_c ;- inc bc ; Last character position + 1 (string starts from 0)
  59. bne *+4
  60. inc z80_b
  61. ora z80_a ;- or a
  62. ;- sbc hl, bc ; Compares length with last char position
  63. jcs __CONT ;- jr nc, __CONT ; If Carry => We must copy to end of string
  64. lda z80_l ;- add hl,bc ; Restore back original LEN(a$) in HL
  65. clc
  66. adc z80_c
  67. sta z80_l
  68. lda z80_h
  69. adc z80_b
  70. sta z80_h
  71. lda z80_h ;- ld b,h
  72. sta z80_b
  73. lda z80_l ;- ld c,l ; Copy to the end of str
  74. sta z80_c
  75. ;- ccf ; Clears Carry flag for next subtraction
  76. __CONT:
  77. lda z80_b ;- ld h,b
  78. sta z80_h
  79. lda z80_c ;- ld l,c ; HL = Last char position to copy (1 for char 0, 2 for char 1, etc)
  80. sta z80_l
  81. ;- sbc hl, de ; HL = LEN(a$) - DE => Number of chars to copy
  82. jeq __EMPTY ;- jr z, __EMPTY ; 0 Chars to copy => Return HL = 0 (NULL STR)
  83. jcc __EMPTY ;- jr c, __EMPTY ; If Carry => Nothing to return (NULL STR)
  84. lda z80_h ;- ld b,h
  85. sta z80_b
  86. lda z80_l ;- ld c,l ; BC = Number of chars to copy
  87. sta z80_c
  88. inc z80_c ;- inc bc
  89. bne *+4
  90. inc z80_b
  91. inc z80_c ;- inc bc ; +2 bytes for string length number
  92. bne *+4
  93. inc z80_b
  94. lda z80_c ;- push bc
  95. pha
  96. lda z80_b
  97. pha
  98. lda z80_e ;- push de
  99. pha
  100. lda z80_d
  101. pha
  102. jsr __MEM_ALLOC ;- call __MEM_ALLOC
  103. pla ;- pop de
  104. sta z80_d
  105. pla
  106. sta z80_e
  107. pla ;- pop bc
  108. sta z80_b
  109. pla
  110. sta z80_c
  111. lda z80_h ;- ld a,h
  112. sta z80_a
  113. ora z80_l ;- or l
  114. jeq __EMPTY ;- jr z, __EMPTY ; Return if NULL (no memory)
  115. ;- dec bc
  116. ;- dec bc ; Number of chars to copy (Len of slice)
  117. lda z80_c ;- ld (hl),c
  118. ldy #$00
  119. sta (z80_hl),y
  120. inc z80_l ;- inc hl
  121. bne *+4
  122. inc z80_h
  123. lda z80_b ;- ld (hl),b
  124. ldy #$00
  125. sta (z80_hl),y
  126. inc z80_l ;- inc hl ; Stores new string length
  127. bne *+4
  128. inc z80_h
  129. tsx ;- ex (sp), hl ; Pointer to A$ now in HL; Pointer to new string chars in Stack
  130. lda $0103,x
  131. ldy z80_h
  132. sta z80_h
  133. tya
  134. sta $0103,x
  135. lda $0104,x
  136. ldy z80_l
  137. sta z80_l
  138. tya
  139. sta $104,x
  140. inc z80_l ;- inc hl
  141. bne *+4
  142. inc z80_h
  143. inc z80_l ;- inc hl ; Skip string length
  144. bne *+4
  145. inc z80_h
  146. clc ;- add hl,de ; Were to start from A$
  147. lda z80_l
  148. adc z80_e
  149. sta z80_l
  150. lda z80_h
  151. adc z80_d
  152. sta z80_h
  153. pla ;- pop de ; Start of new string chars
  154. sta z80_d
  155. pla
  156. sta z80_e
  157. lda z80_e ;- push de ; Stores it again
  158. pha
  159. lda z80_d
  160. pha
  161. ;- ldir ; Copies BC chars
  162. pla ;- pop de
  163. sta z80_d
  164. pla
  165. sta z80_e
  166. ;- dec de
  167. ;- dec de ; Points to String LEN start
  168. lda z80_e ;- ex de,hl ; Returns it in HL
  169. ldx z80_l
  170. stx z80_e
  171. sta z80_l
  172. lda z80_d
  173. ldx z80_h
  174. stx z80_d
  175. sta z80_h
  176. jmp __FREE_ON_EXIT ;- jr __FREE_ON_EXIT
  177. __EMPTY:
  178. ; Return NULL (empty) string
  179. pla ;- pop hl
  180. sta z80_h
  181. pla
  182. sta z80_l
  183. lda #<0 ;- ld hl, 0 ; Return NULL
  184. sta z80_l
  185. lda #>0
  186. sta z80_h
  187. __FREE_ON_EXIT:
  188. ldx z80_ap ;- ex af,af' ; Recover original A register
  189. sta z80_ap
  190. txa
  191. tsx ;- ex (sp),hl ; Original HL pointer
  192. lda $0103,x
  193. ldy z80_h
  194. sta z80_h
  195. tya
  196. sta $0103,x
  197. lda $0104,x
  198. ldy z80_l
  199. sta z80_l
  200. tya
  201. sta $104,x
  202. ora z80_a ;- or a
  203. beq *+5 ;- call nz, __MEM_FREE
  204. jsr __MEM_FREE
  205. pla ;- pop hl ; Recover result
  206. sta z80_h
  207. pla
  208. sta z80_l
  209. rts ;- ret
  210. ;- ENDP