strcat.asm 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. #include once <alloc.asm>
  2. #include once <strlen.asm>
  3. ;
  4. __ADDSTR: ; Implements c$ = a$ + b$
  5. ; hl = &a$, de = &b$ (pointers)
  6. ;
  7. __STRCAT2: ; This routine creates a new string in dynamic space
  8. ; making room for it. Then copies a$ + b$ into it.
  9. ; HL = a$, DE = b$
  10. ;- PROC
  11. ;- LOCAL __STR_CONT
  12. ;- LOCAL __STRCATEND
  13. lda z80_l ;- push hl
  14. pha
  15. lda z80_h
  16. pha
  17. jsr __STRLEN ;- call __STRLEN
  18. lda z80_l ;- ld c,l
  19. sta z80_c
  20. ;- ld b, h ; BC = LEN(a$)
  21. ;- ex (sp), hl ; (SP) = LEN (a$), HL = a$
  22. ;- push hl ; Saves pointer to a$
  23. ;- inc bc
  24. ;- inc bc ; +2 bytes to store length
  25. ;- ex de, hl
  26. lda z80_l ;- push hl
  27. pha
  28. lda z80_h
  29. pha
  30. jsr __STRLEN ;- call __STRLEN
  31. ; HL = len(b$)
  32. ;- add hl, bc ; Total str length => 2 + len(a$) + len(b$)
  33. lda z80_l ;- ld c,l
  34. sta z80_c
  35. ;- ld b, h ; BC = Total str length + 2
  36. jsr __MEM_ALLOC ;- call __MEM_ALLOC
  37. ;- pop de ; HL = c$, DE = b$
  38. lda z80_e ;- ex de,hl ; HL = b$, DE = c$
  39. ldx z80_l
  40. stx z80_e
  41. sta z80_l
  42. lda z80_d
  43. ldx z80_h
  44. stx z80_d
  45. sta z80_h
  46. ;- ex (sp), hl ; HL = a$, (SP) = b$
  47. lda z80_c ;- exx
  48. ldx z80_cp
  49. stx z80_c
  50. sta z80_cp
  51. lda z80_b
  52. ldx z80_bp
  53. stx z80_b
  54. sta z80_bp
  55. lda z80_e
  56. ldx z80_ep
  57. stx z80_e
  58. sta z80_ep
  59. lda z80_d
  60. ldx z80_dp
  61. stx z80_d
  62. sta z80_dp
  63. lda z80_l
  64. ldx z80_lp
  65. stx z80_l
  66. sta z80_lp
  67. lda z80_h
  68. ldx z80_hp
  69. stx z80_h
  70. sta z80_hp
  71. pla ;- pop de ; D'E' = b$
  72. sta z80_d
  73. pla
  74. sta z80_e
  75. lda z80_c ;- exx
  76. ldx z80_cp
  77. stx z80_c
  78. sta z80_cp
  79. lda z80_b
  80. ldx z80_bp
  81. stx z80_b
  82. sta z80_bp
  83. lda z80_e
  84. ldx z80_ep
  85. stx z80_e
  86. sta z80_ep
  87. lda z80_d
  88. ldx z80_dp
  89. stx z80_d
  90. sta z80_dp
  91. lda z80_l
  92. ldx z80_lp
  93. stx z80_l
  94. sta z80_lp
  95. lda z80_h
  96. ldx z80_hp
  97. stx z80_h
  98. sta z80_hp
  99. pla ;- pop bc ; LEN(a$)
  100. sta z80_b
  101. pla
  102. sta z80_c
  103. lda z80_d ;- ld a,d
  104. sta z80_a
  105. ora z80_e ;- or e
  106. ;- ret z ; If no memory: RETURN
  107. __STR_CONT:
  108. lda z80_e ;- push de ; Address of c$
  109. pha
  110. lda z80_d
  111. pha
  112. lda z80_h ;- ld a,h
  113. sta z80_a
  114. ora z80_l ;- or l
  115. jne __STR_CONT1 ;- jr nz, __STR_CONT1 ; If len(a$) != 0 do copy
  116. ; a$ is NULL => uses HL = DE for transfer
  117. lda z80_d ;- ld h,d
  118. sta z80_h
  119. lda z80_e ;- ld l,e
  120. sta z80_l
  121. ;- ld (hl),a ; This will copy 00 00 at (DE) location
  122. inc z80_e ;- inc de
  123. bne *+4
  124. inc z80_d
  125. ;- dec bc ; Ensure BC will be set to 1 in the next step
  126. __STR_CONT1: ; Copies a$ (HL) into c$ (DE)
  127. inc z80_c ;- inc bc
  128. bne *+4
  129. inc z80_b
  130. inc z80_c ;- inc bc ; BC = BC + 2
  131. bne *+4
  132. inc z80_b
  133. ;- ldir ; MEMCOPY: c$ = a$
  134. pla ;- pop hl ; HL = c$
  135. sta z80_h
  136. pla
  137. sta z80_l
  138. lda z80_c ;- exx
  139. ldx z80_cp
  140. stx z80_c
  141. sta z80_cp
  142. lda z80_b
  143. ldx z80_bp
  144. stx z80_b
  145. sta z80_bp
  146. lda z80_e
  147. ldx z80_ep
  148. stx z80_e
  149. sta z80_ep
  150. lda z80_d
  151. ldx z80_dp
  152. stx z80_d
  153. sta z80_dp
  154. lda z80_l
  155. ldx z80_lp
  156. stx z80_l
  157. sta z80_lp
  158. lda z80_h
  159. ldx z80_hp
  160. stx z80_h
  161. sta z80_hp
  162. lda z80_e ;- push de ; Recovers b$; A ex hl,hl' would be very handy
  163. pha
  164. lda z80_d
  165. pha
  166. lda z80_c ;- exx
  167. ldx z80_cp
  168. stx z80_c
  169. sta z80_cp
  170. lda z80_b
  171. ldx z80_bp
  172. stx z80_b
  173. sta z80_bp
  174. lda z80_e
  175. ldx z80_ep
  176. stx z80_e
  177. sta z80_ep
  178. lda z80_d
  179. ldx z80_dp
  180. stx z80_d
  181. sta z80_dp
  182. lda z80_l
  183. ldx z80_lp
  184. stx z80_l
  185. sta z80_lp
  186. lda z80_h
  187. ldx z80_hp
  188. stx z80_h
  189. sta z80_hp
  190. pla ;- pop de ; DE = b$
  191. sta z80_d
  192. pla
  193. sta z80_e
  194. __STRCAT: ; ConCATenate two strings a$ = a$ + b$. HL = ptr to a$, DE = ptr to b$
  195. ; NOTE: Both DE, BC and AF are modified and lost
  196. ; Returns HL (pointer to a$)
  197. ; a$ Must be NOT NULL
  198. lda z80_d ;- ld a,d
  199. sta z80_a
  200. ora z80_e ;- or e
  201. bne *+3 ;- ret z ; Returns if de is NULL (nothing to copy)
  202. rts
  203. lda z80_l ;- push hl ; Saves HL to return it later
  204. pha
  205. lda z80_h
  206. pha
  207. ldy #$00 ;- ld c,(hl)
  208. lda (z80_hl),y
  209. sta z80_c
  210. inc z80_l ;- inc hl
  211. bne *+4
  212. inc z80_h
  213. ldy #$00 ;- ld b,(hl)
  214. lda (z80_hl),y
  215. sta z80_b
  216. inc z80_l ;- inc hl
  217. bne *+4
  218. inc z80_h
  219. lda z80_l ;- add hl,bc ; HL = end of (a$) string ; bc = len(a$)
  220. clc
  221. adc z80_c
  222. sta z80_l
  223. lda z80_h
  224. adc z80_b
  225. sta z80_h
  226. lda z80_c ;- push bc ; Saves LEN(a$) for later
  227. pha
  228. lda z80_b
  229. pha
  230. lda z80_e ;- ex de,hl ; DE = end of string (Begin of copy addr)
  231. ldx z80_l
  232. stx z80_e
  233. sta z80_l
  234. lda z80_d
  235. ldx z80_h
  236. stx z80_d
  237. sta z80_h
  238. ldy #$00 ;- ld c,(hl)
  239. lda (z80_hl),y
  240. sta z80_c
  241. inc z80_l ;- inc hl
  242. bne *+4
  243. inc z80_h
  244. ldy #$00 ;- ld b,(hl) ; BC = len(b$)
  245. lda (z80_hl),y
  246. sta z80_b
  247. lda z80_b ;- ld a,b
  248. sta z80_a
  249. ora z80_c ;- or c
  250. ;- jr z, __STRCATEND; Return if len(b$) == 0
  251. lda z80_c ;- push bc ; Save LEN(b$)
  252. pha
  253. lda z80_b
  254. pha
  255. inc z80_l ;- inc hl ; Skip 2nd byte of len(b$)
  256. bne *+4
  257. inc z80_h
  258. ;- ldir ; Concatenate b$
  259. pla ;- pop bc ; Recovers length (b$)
  260. sta z80_b
  261. pla
  262. sta z80_c
  263. pla ;- pop hl ; Recovers length (a$)
  264. sta z80_h
  265. pla
  266. sta z80_l
  267. lda z80_l ;- add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$)
  268. clc
  269. adc z80_c
  270. sta z80_l
  271. lda z80_h
  272. adc z80_b
  273. sta z80_h
  274. lda z80_e ;- ex de,hl ; DE = LEN(a$+b$)
  275. ldx z80_l
  276. stx z80_e
  277. sta z80_l
  278. lda z80_d
  279. ldx z80_h
  280. stx z80_d
  281. sta z80_h
  282. pla ;- pop hl
  283. sta z80_h
  284. pla
  285. sta z80_l
  286. lda z80_e ;- ld (hl),e ; Updates new LEN and return
  287. ldy #$00
  288. sta (z80_hl),y
  289. inc z80_l ;- inc hl
  290. bne *+4
  291. inc z80_h
  292. lda z80_d ;- ld (hl),d
  293. ldy #$00
  294. sta (z80_hl),y
  295. ;- dec hl
  296. rts ;- ret
  297. __STRCATEND:
  298. pla ;- pop hl ; Removes Len(a$)
  299. sta z80_h
  300. pla
  301. sta z80_l
  302. pla ;- pop hl ; Restores original HL, so HL = a$
  303. sta z80_h
  304. pla
  305. sta z80_l
  306. rts ;- ret
  307. ;- ENDP