Mercurial > hg > index.cgi
annotate 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 |
rev | line source |
---|---|
135
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
1 *pragmapush list |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
2 *pragma list |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
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 |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
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 |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
6 ; the end of a memory block into said memory block. |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
7 ; |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
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 |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
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, |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
10 ; a byte by byte insertion process is run. |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
11 ; |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
12 ; Without the first phase, U-X bytes must by copied D times making the process O((U-X)*D). However, the first phase |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
13 ; will run FLOOR((U-X)/D) times, each time swapping exactly D bytes, but at basically twice the cost per byte and then |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
14 ; only the remainder needs to be copied on the byte by byte sequence meaning each byte sequence will have to shift |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
15 ; (U-X)%D bytes. This will show the biggest gain for larger insertion sizes inserted a fairly large number of bytes |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
16 ; before the end of the memory block. |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
17 ; |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
18 ; Entry: |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
19 ; X Insertion point |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
20 ; U Source data |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
21 ; D Length of source data (must not be zero) |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
22 ; |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
23 ; Exit: |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
24 ; |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
25 ; DO NOT ENTER WITH D SET TO 0 |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
26 mem_insert pshs d,u ; save the length and insertion point |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
27 mem_insert0 leay d,x ; point to the end of this copy iteration |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
28 cmpy 2,s ; is there room for a full iteration? |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
29 bhi mem_insert2 ; brif not |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
30 tfr d,y ; get copy length somewhere usfule |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
31 mem_insert1 ldb ,x ; swap a byte |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
32 lda ,u |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
33 sta ,x+ |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
34 stb ,u+ |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
35 leay -1,y ; done this iteration? |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
36 bne mem_insert1 ; brif not |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
37 ldd ,s ; get back length |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
38 ldu 2,s ; get back source pointer |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
39 cmpx 2,s ; did we actually finish? |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
40 bne mem_insert0 ; brif not |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
41 puls d,x,pc ; we're done - clean up stack and return |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
42 mem_insert2 ldy ,s ; get number bytes to insert one by one |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
43 mem_insert3 pshs x,u ; save the pointers |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
44 lda ,u ; get byte at top of move range |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
45 mem_insert4 ldb ,-u |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
46 stb 1,u |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
47 cmpu ,s |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
48 bne mem_insert4 |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
49 puls x,u ; get back original pointers |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
50 sta ,x+ ; save new byte in insert location |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
51 leau 1,u ; move to next source byte |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
52 leay -1,y ; done all source bytes? |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
53 bne mem_insert3 ; brif not |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
54 puls d,x,pc ; clean up stack and return |
3a4cb89a419c
Add a memory insertion routine to swap the end block into middle of a block
William Astle <lost@l-w.ca>
parents:
diff
changeset
|
55 *pragmapop list |