letsubstr.asm 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. ; Substring assigment eg. LET a$(p0 TO p1) = "xxxx"
  2. ; HL = Start of string
  3. ; TOP of the stack -> p1 (16 bit, unsigned)
  4. ; TOP -1 of the stack -> p0 register
  5. ; TOP -2 Flag (popped out in A register)
  6. ; A Register => 0 if HL is not freed from memory
  7. ; => Not 0 if HL must be freed from memory on exit
  8. ; TOP -3 B$ address
  9. ;
  10. #include once <free.asm>
  11. ;
  12. __LETSUBSTR:
  13. ;- PROC
  14. ;- LOCAL __CONT0
  15. ;- LOCAL __CONT1
  16. ;- LOCAL __CONT2
  17. ;- LOCAL __FREE_STR
  18. ;- LOCAL __FREE_STR0
  19. lda z80_c ;- exx
  20. ldx z80_cp
  21. stx z80_c
  22. sta z80_cp
  23. lda z80_b
  24. ldx z80_bp
  25. stx z80_b
  26. sta z80_bp
  27. lda z80_e
  28. ldx z80_ep
  29. stx z80_e
  30. sta z80_ep
  31. lda z80_d
  32. ldx z80_dp
  33. stx z80_d
  34. sta z80_dp
  35. lda z80_l
  36. ldx z80_lp
  37. stx z80_l
  38. sta z80_lp
  39. lda z80_h
  40. ldx z80_hp
  41. stx z80_h
  42. sta z80_hp
  43. pla ;- pop hl ; Return address
  44. sta z80_h
  45. pla
  46. sta z80_l
  47. pla ;- pop de ; p1
  48. sta z80_d
  49. pla
  50. sta z80_e
  51. pla ;- pop bc ; p0
  52. sta z80_b
  53. pla
  54. sta z80_c
  55. lda z80_c ;- exx
  56. ldx z80_cp
  57. stx z80_c
  58. sta z80_cp
  59. lda z80_b
  60. ldx z80_bp
  61. stx z80_b
  62. sta z80_bp
  63. lda z80_e
  64. ldx z80_ep
  65. stx z80_e
  66. sta z80_ep
  67. lda z80_d
  68. ldx z80_dp
  69. stx z80_d
  70. sta z80_dp
  71. lda z80_l
  72. ldx z80_lp
  73. stx z80_l
  74. sta z80_lp
  75. lda z80_h
  76. ldx z80_hp
  77. stx z80_h
  78. sta z80_hp
  79. plp ;- pop af ; Flag
  80. pha
  81. ldx z80_ap ;- ex af, af' ; Save it for later
  82. sta z80_ap
  83. txa
  84. pla ;- pop de ; B$
  85. sta z80_d
  86. pla
  87. sta z80_e
  88. lda z80_c ;- exx
  89. ldx z80_cp
  90. stx z80_c
  91. sta z80_cp
  92. lda z80_b
  93. ldx z80_bp
  94. stx z80_b
  95. sta z80_bp
  96. lda z80_e
  97. ldx z80_ep
  98. stx z80_e
  99. sta z80_ep
  100. lda z80_d
  101. ldx z80_dp
  102. stx z80_d
  103. sta z80_dp
  104. lda z80_l
  105. ldx z80_lp
  106. stx z80_l
  107. sta z80_lp
  108. lda z80_h
  109. ldx z80_hp
  110. stx z80_h
  111. sta z80_hp
  112. lda z80_l ;- push hl ; push ret addr back
  113. pha
  114. lda z80_h
  115. pha
  116. lda z80_c ;- exx
  117. ldx z80_cp
  118. stx z80_c
  119. sta z80_cp
  120. lda z80_b
  121. ldx z80_bp
  122. stx z80_b
  123. sta z80_bp
  124. lda z80_e
  125. ldx z80_ep
  126. stx z80_e
  127. sta z80_ep
  128. lda z80_d
  129. ldx z80_dp
  130. stx z80_d
  131. sta z80_dp
  132. lda z80_l
  133. ldx z80_lp
  134. stx z80_l
  135. sta z80_lp
  136. lda z80_h
  137. ldx z80_hp
  138. stx z80_h
  139. sta z80_hp
  140. lda z80_h ;- ld a,h
  141. sta z80_a
  142. ora z80_l ;- or l
  143. jeq __FREE_STR0 ;- jp z, __FREE_STR0 ; Return if null
  144. ldy #$00 ;- ld c,(hl)
  145. lda (z80_hl),y
  146. sta z80_c
  147. inc z80_l ;- inc hl
  148. bne *+4
  149. inc z80_h
  150. ldy #$00 ;- ld b,(hl) ; BC = Str length
  151. lda (z80_hl),y
  152. sta z80_b
  153. inc z80_l ;- inc hl ; HL = String start
  154. bne *+4
  155. inc z80_h
  156. lda z80_c ;- push bc
  157. pha
  158. lda z80_b
  159. pha
  160. lda z80_c ;- exx
  161. ldx z80_cp
  162. stx z80_c
  163. sta z80_cp
  164. lda z80_b
  165. ldx z80_bp
  166. stx z80_b
  167. sta z80_bp
  168. lda z80_e
  169. ldx z80_ep
  170. stx z80_e
  171. sta z80_ep
  172. lda z80_d
  173. ldx z80_dp
  174. stx z80_d
  175. sta z80_dp
  176. lda z80_l
  177. ldx z80_lp
  178. stx z80_l
  179. sta z80_lp
  180. lda z80_h
  181. ldx z80_hp
  182. stx z80_h
  183. sta z80_hp
  184. lda z80_e ;- ex de,hl
  185. ldx z80_l
  186. stx z80_e
  187. sta z80_l
  188. lda z80_d
  189. ldx z80_h
  190. stx z80_d
  191. sta z80_h
  192. ora z80_a ;- or a
  193. ;- sbc hl, bc ; HL = Length of string requester by user
  194. inc z80_l ;- inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1
  195. bne *+4
  196. inc z80_h
  197. lda z80_e ;- ex de, hl ; Saves it in DE
  198. ldx z80_l
  199. stx z80_e
  200. sta z80_l
  201. lda z80_d
  202. ldx z80_h
  203. stx z80_d
  204. sta z80_h
  205. pla ;- pop hl ; HL = String length
  206. sta z80_h
  207. pla
  208. sta z80_l
  209. lda z80_c ;- exx
  210. ldx z80_cp
  211. stx z80_c
  212. sta z80_cp
  213. lda z80_b
  214. ldx z80_bp
  215. stx z80_b
  216. sta z80_bp
  217. lda z80_e
  218. ldx z80_ep
  219. stx z80_e
  220. sta z80_ep
  221. lda z80_d
  222. ldx z80_dp
  223. stx z80_d
  224. sta z80_dp
  225. lda z80_l
  226. ldx z80_lp
  227. stx z80_l
  228. sta z80_lp
  229. lda z80_h
  230. ldx z80_hp
  231. stx z80_h
  232. sta z80_hp
  233. jcc __FREE_STR0 ;- jp c, __FREE_STR0 ; Return if greather
  234. lda z80_c ;- exx ; Return if p0 > p1
  235. ldx z80_cp
  236. stx z80_c
  237. sta z80_cp
  238. lda z80_b
  239. ldx z80_bp
  240. stx z80_b
  241. sta z80_bp
  242. lda z80_e
  243. ldx z80_ep
  244. stx z80_e
  245. sta z80_ep
  246. lda z80_d
  247. ldx z80_dp
  248. stx z80_d
  249. sta z80_dp
  250. lda z80_l
  251. ldx z80_lp
  252. stx z80_l
  253. sta z80_lp
  254. lda z80_h
  255. ldx z80_hp
  256. stx z80_h
  257. sta z80_hp
  258. ora z80_a ;- or a
  259. ;- sbc hl, bc ; P0 >= String length?
  260. lda z80_c ;- exx
  261. ldx z80_cp
  262. stx z80_c
  263. sta z80_cp
  264. lda z80_b
  265. ldx z80_bp
  266. stx z80_b
  267. sta z80_bp
  268. lda z80_e
  269. ldx z80_ep
  270. stx z80_e
  271. sta z80_ep
  272. lda z80_d
  273. ldx z80_dp
  274. stx z80_d
  275. sta z80_dp
  276. lda z80_l
  277. ldx z80_lp
  278. stx z80_l
  279. sta z80_lp
  280. lda z80_h
  281. ldx z80_hp
  282. stx z80_h
  283. sta z80_hp
  284. jeq __FREE_STR0 ;- jp z, __FREE_STR0 ; Return if equal
  285. jcc __FREE_STR0 ;- jp c, __FREE_STR0 ; Return if greather
  286. lda z80_c ;- exx
  287. ldx z80_cp
  288. stx z80_c
  289. sta z80_cp
  290. lda z80_b
  291. ldx z80_bp
  292. stx z80_b
  293. sta z80_bp
  294. lda z80_e
  295. ldx z80_ep
  296. stx z80_e
  297. sta z80_ep
  298. lda z80_d
  299. ldx z80_dp
  300. stx z80_d
  301. sta z80_dp
  302. lda z80_l
  303. ldx z80_lp
  304. stx z80_l
  305. sta z80_lp
  306. lda z80_h
  307. ldx z80_hp
  308. stx z80_h
  309. sta z80_hp
  310. lda z80_l ;- add hl,bc ; Add it back
  311. clc
  312. adc z80_c
  313. sta z80_l
  314. lda z80_h
  315. adc z80_b
  316. sta z80_h
  317. lda z80_l ;- sbc hl,de ; Length of substring > string => Truncate it
  318. sbc z80_e
  319. sta z80_l
  320. lda z80_h
  321. sbc z80_d
  322. sta z80_h
  323. clc ;- add hl,de ; add it back
  324. lda z80_l
  325. adc z80_e
  326. sta z80_l
  327. lda z80_h
  328. adc z80_d
  329. sta z80_h
  330. jcs __CONT0 ;- jr nc, __CONT0 ; Length of substring within a$
  331. lda z80_h ;- ld d,h
  332. sta z80_d
  333. lda z80_l ;- ld e,l ; Truncate length of substring to fit within the strlen
  334. sta z80_e
  335. __CONT0: ; At this point DE = Length of subtring to copy
  336. ;- ; BC = start of char to copy
  337. lda z80_e ;- push de
  338. pha
  339. lda z80_d
  340. pha
  341. lda z80_c ;- push bc
  342. pha
  343. lda z80_b
  344. pha
  345. lda z80_c ;- exx
  346. ldx z80_cp
  347. stx z80_c
  348. sta z80_cp
  349. lda z80_b
  350. ldx z80_bp
  351. stx z80_b
  352. sta z80_bp
  353. lda z80_e
  354. ldx z80_ep
  355. stx z80_e
  356. sta z80_ep
  357. lda z80_d
  358. ldx z80_dp
  359. stx z80_d
  360. sta z80_dp
  361. lda z80_l
  362. ldx z80_lp
  363. stx z80_l
  364. sta z80_lp
  365. lda z80_h
  366. ldx z80_hp
  367. stx z80_h
  368. sta z80_hp
  369. pla ;- pop bc
  370. sta z80_b
  371. pla
  372. sta z80_c
  373. lda z80_l ;- add hl,bc ; Start address (within a$) so copy from b$ (in DE)
  374. clc
  375. adc z80_c
  376. sta z80_l
  377. lda z80_h
  378. adc z80_b
  379. sta z80_h
  380. lda z80_l ;- push hl
  381. pha
  382. lda z80_h
  383. pha
  384. lda z80_c ;- exx
  385. ldx z80_cp
  386. stx z80_c
  387. sta z80_cp
  388. lda z80_b
  389. ldx z80_bp
  390. stx z80_b
  391. sta z80_bp
  392. lda z80_e
  393. ldx z80_ep
  394. stx z80_e
  395. sta z80_ep
  396. lda z80_d
  397. ldx z80_dp
  398. stx z80_d
  399. sta z80_dp
  400. lda z80_l
  401. ldx z80_lp
  402. stx z80_l
  403. sta z80_lp
  404. lda z80_h
  405. ldx z80_hp
  406. stx z80_h
  407. sta z80_hp
  408. pla ;- pop hl ; Start address (within a$) so copy from b$ (in DE)
  409. sta z80_h
  410. pla
  411. sta z80_l
  412. lda z80_d ;- ld b,d ; Length of string
  413. sta z80_b
  414. lda z80_e ;- ld c,e
  415. sta z80_c
  416. lda #$20 ;- ld (hl), ' '
  417. ldy #$00
  418. sta (z80_hl),y
  419. lda z80_h ;- ld d,h
  420. sta z80_d
  421. lda z80_l ;- ld e,l
  422. sta z80_e
  423. inc z80_e ;- inc de
  424. bne *+4
  425. inc z80_d
  426. ;- dec bc
  427. lda z80_b ;- ld a,b
  428. sta z80_a
  429. ora z80_c ;- or c
  430. jeq __CONT2 ;- jr z, __CONT2
  431. ;- ; At this point HL = DE = Start of Write zone in a$
  432. ;- ; BC = Number of chars to write
  433. ;- ldir
  434. __CONT2:
  435. pla ;- pop bc ; Recovers Length of string to copy
  436. sta z80_b
  437. pla
  438. sta z80_c
  439. lda z80_c ;- exx
  440. ldx z80_cp
  441. stx z80_c
  442. sta z80_cp
  443. lda z80_b
  444. ldx z80_bp
  445. stx z80_b
  446. sta z80_bp
  447. lda z80_e
  448. ldx z80_ep
  449. stx z80_e
  450. sta z80_ep
  451. lda z80_d
  452. ldx z80_dp
  453. stx z80_d
  454. sta z80_dp
  455. lda z80_l
  456. ldx z80_lp
  457. stx z80_l
  458. sta z80_lp
  459. lda z80_h
  460. ldx z80_hp
  461. stx z80_h
  462. sta z80_hp
  463. lda z80_e ;- ex de, hl ; HL = Source, DE = Target
  464. ldx z80_l
  465. stx z80_e
  466. sta z80_l
  467. lda z80_d
  468. ldx z80_h
  469. stx z80_d
  470. sta z80_h
  471. lda z80_h ;- ld a,h
  472. sta z80_a
  473. ora z80_l ;- or l
  474. jeq __FREE_STR ;- jp z, __FREE_STR ; Return if B$ is NULL
  475. ldy #$00 ;- ld c,(hl)
  476. lda (z80_hl),y
  477. sta z80_c
  478. inc z80_l ;- inc hl
  479. bne *+4
  480. inc z80_h
  481. ldy #$00 ;- ld b,(hl)
  482. lda (z80_hl),y
  483. sta z80_b
  484. inc z80_l ;- inc hl
  485. bne *+4
  486. inc z80_h
  487. lda z80_b ;- ld a,b
  488. sta z80_a
  489. ora z80_c ;- or c
  490. jeq __FREE_STR ;- jp z, __FREE_STR ; Return if len(b$) = 0
  491. ;- ; Now if len(b$) < len(char to copy), copy only len(b$) chars
  492. lda z80_e ;- push de
  493. pha
  494. lda z80_d
  495. pha
  496. lda z80_l ;- push hl
  497. pha
  498. lda z80_h
  499. pha
  500. lda z80_c ;- push bc
  501. pha
  502. lda z80_b
  503. pha
  504. lda z80_c ;- exx
  505. ldx z80_cp
  506. stx z80_c
  507. sta z80_cp
  508. lda z80_b
  509. ldx z80_bp
  510. stx z80_b
  511. sta z80_bp
  512. lda z80_e
  513. ldx z80_ep
  514. stx z80_e
  515. sta z80_ep
  516. lda z80_d
  517. ldx z80_dp
  518. stx z80_d
  519. sta z80_dp
  520. lda z80_l
  521. ldx z80_lp
  522. stx z80_l
  523. sta z80_lp
  524. lda z80_h
  525. ldx z80_hp
  526. stx z80_h
  527. sta z80_hp
  528. pla ;- pop hl ; LEN (b$)
  529. sta z80_h
  530. pla
  531. sta z80_l
  532. ora z80_a ;- or a
  533. ;- sbc hl, bc
  534. ;- add hl, bc
  535. jcs __CONT1 ;- jr nc, __CONT1
  536. ;- ; If len(b$) < len(to copy)
  537. lda z80_h ;- ld b,h ; BC = len(to copy)
  538. sta z80_b
  539. lda z80_l ;- ld c,l
  540. sta z80_c
  541. __CONT1:
  542. pla ;- pop hl
  543. sta z80_h
  544. pla
  545. sta z80_l
  546. pla ;- pop de
  547. sta z80_d
  548. pla
  549. sta z80_e
  550. ;- ldir ; Copy b$ into a$(x to y)
  551. lda z80_c ;- exx
  552. ldx z80_cp
  553. stx z80_c
  554. sta z80_cp
  555. lda z80_b
  556. ldx z80_bp
  557. stx z80_b
  558. sta z80_bp
  559. lda z80_e
  560. ldx z80_ep
  561. stx z80_e
  562. sta z80_ep
  563. lda z80_d
  564. ldx z80_dp
  565. stx z80_d
  566. sta z80_dp
  567. lda z80_l
  568. ldx z80_lp
  569. stx z80_l
  570. sta z80_lp
  571. lda z80_h
  572. ldx z80_hp
  573. stx z80_h
  574. sta z80_hp
  575. lda z80_e ;- ex de,hl
  576. ldx z80_l
  577. stx z80_e
  578. sta z80_l
  579. lda z80_d
  580. ldx z80_h
  581. stx z80_d
  582. sta z80_h
  583. __FREE_STR0:
  584. lda z80_e ;- ex de,hl
  585. ldx z80_l
  586. stx z80_e
  587. sta z80_l
  588. lda z80_d
  589. ldx z80_h
  590. stx z80_d
  591. sta z80_h
  592. __FREE_STR:
  593. ldx z80_ap ;- ex af,af'
  594. sta z80_ap
  595. txa
  596. ora z80_a ;- or a ; If not 0, free
  597. jne __MEM_FREE ;- jp nz, __MEM_FREE
  598. rts ;- ret
  599. ;- ENDP