comparison src/memory.s @ 135:3a4cb89a419c

Add a memory insertion routine to swap the end block into middle of a block
author William Astle <lost@l-w.ca>
date Tue, 09 Jul 2024 22:18:30 -0600
parents
children e49bd0493baf
comparison
equal deleted inserted replaced
134:3ab4b62665c3 135:3a4cb89a419c
1 *pragmapush list
2 *pragma list
3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4 ; Insert the sequence of bytes at U, of length D, at X. The memory from X to (U+D-1) is assumed to be a continguous
5 ; block and that D bytes of free memory are not available at U+D. That is, this is an in-place insertion of D bytes at
6 ; the end of a memory block into said memory block.
7 ;
8 ; This works in two stages. As long as there are more than D bytes between X and U, a full copy that swaps the data
9 ; at U with the data at X is done and then X is advanced by D bytes. Once there are less than D bytes between X and U,
10 ; a byte by byte insertion process is run.
11 ;
12 ; Without the first phase, U-X bytes must by copied D times making the process O((U-X)*D). However, the first phase
13 ; will run FLOOR((U-X)/D) times, each time swapping exactly D bytes, but at basically twice the cost per byte and then
14 ; only the remainder needs to be copied on the byte by byte sequence meaning each byte sequence will have to shift
15 ; (U-X)%D bytes. This will show the biggest gain for larger insertion sizes inserted a fairly large number of bytes
16 ; before the end of the memory block.
17 ;
18 ; Entry:
19 ; X Insertion point
20 ; U Source data
21 ; D Length of source data (must not be zero)
22 ;
23 ; Exit:
24 ;
25 ; DO NOT ENTER WITH D SET TO 0
26 mem_insert pshs d,u ; save the length and insertion point
27 mem_insert0 leay d,x ; point to the end of this copy iteration
28 cmpy 2,s ; is there room for a full iteration?
29 bhi mem_insert2 ; brif not
30 tfr d,y ; get copy length somewhere usfule
31 mem_insert1 ldb ,x ; swap a byte
32 lda ,u
33 sta ,x+
34 stb ,u+
35 leay -1,y ; done this iteration?
36 bne mem_insert1 ; brif not
37 ldd ,s ; get back length
38 ldu 2,s ; get back source pointer
39 cmpx 2,s ; did we actually finish?
40 bne mem_insert0 ; brif not
41 puls d,x,pc ; we're done - clean up stack and return
42 mem_insert2 ldy ,s ; get number bytes to insert one by one
43 mem_insert3 pshs x,u ; save the pointers
44 lda ,u ; get byte at top of move range
45 mem_insert4 ldb ,-u
46 stb 1,u
47 cmpu ,s
48 bne mem_insert4
49 puls x,u ; get back original pointers
50 sta ,x+ ; save new byte in insert location
51 leau 1,u ; move to next source byte
52 leay -1,y ; done all source bytes?
53 bne mem_insert3 ; brif not
54 puls d,x,pc ; clean up stack and return
55 *pragmapop list