Initial revision
[ssr] / StraySrc / Libraries / BAS / src / s / insert
1 ;
2 ; insert.s
3 ;
4 ; Insert zero-filled chunks of data
5 ;
6 ; © 1994-1998 Straylight
7 ;
8
9 ;----- Licensing note -------------------------------------------------------
10 ;
11 ; This file is part of Straylight's BASIC Assembler Supplement.
12 ;
13 ; BAS is free software; you can redistribute it and/or modify
14 ; it under the terms of the GNU General Public License as published by
15 ; the Free Software Foundation; either version 2, or (at your option)
16 ; any later version.
17 ;
18 ; BAS is distributed in the hope that it will be useful,
19 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 ; GNU General Public License for more details.
22 ;
23 ; You should have received a copy of the GNU General Public License
24 ; along with BAS. If not, write to the Free Software Foundation,
25 ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26
27 ;----- Standard header ------------------------------------------------------
28
29 GET libs:header
30 GET libs:swis
31
32 GET libs:stream
33
34 ;----- External dependencies ------------------------------------------------
35
36 GET sh.bas
37 GET sh.workspace
38
39 ;----- Main code ------------------------------------------------------------
40
41 AREA |BAS$$Code|,CODE,READONLY
42
43 ; --- insert_align ---
44 ;
45 ; On entry: --
46 ;
47 ; On exit: --
48 ;
49 ; Use: Inserts `0' bytes to align O% and P% to the next word
50 ; boundary.
51
52 EXPORT insert_align
53 insert_align ROUT
54
55 STMFD R13!,{R0,R14} ;Save some registers
56 LDR R14,[R7,#:INDEX:be__percents]
57 LDR R0,[R14,#('P'-'A')*4] ;Load current loc counter
58 ANDS R0,R0,#3 ;Get non-word-alignedness
59 RSBNE R0,R0,#4 ;Work out bytes to insert
60 BLNE insert_reserve ;Reserve so many bytes
61 LDMFD R13!,{R0,PC}^ ;And return to caller
62
63 LTORG
64
65 ; --- insert_reserve ---
66 ;
67 ; On entry: R0 == amount of memory to reserve
68 ;
69 ; On exit: --
70 ;
71 ; Use: Reserves R0 bytes of memory at the current position. The
72 ; memory is filled with 0s.
73
74 EXPORT insert_reserve
75 insert_reserve ROUT
76
77 STMFD R13!,{R0-R9,R12,R14} ;Save some registers
78 MOV R12,R7 ;Get workspace in R12
79
80 LDR R14,be__percents ;Load the % variable address
81 ADD R14,R14,#('O'-'A')*4 ;Find O% and P%
82 LDMIA R14,{R1,R3} ;Load them out nicely
83 ADD R2,R1,R0 ;Bump along O%
84 ADD R3,R3,R0 ;And bump along P%
85 STMIA R14,{R2,R3} ;Save them back again
86
87 CMP R0,#0 ;Insert no bytes?
88 BEQ %90insert_reserve ;Yup -- do nothing then
89 MOV R2,#0 ;A zero word
90
91 TST R1,#3 ;Is destination word-aligned?
92 BEQ %10insert_reserve ;Yes -- skip onwards then
93 00 STRB R2,[R1],#1 ;Zero a single byte
94 SUBS R0,R0,#1 ;Decrement counter
95 BEQ %90insert_reserve ;Done it all -- return
96 TST R1,#3 ;Is destination word-aligned?
97 BNE %00insert_reserve ;No -- go round again
98
99 ; --- Now blast 0s out AQAP ---
100
101 10 MOV R3,#0
102 MOV R4,#0
103 MOV R5,#0
104 MOV R6,#0
105 MOV R7,#0
106 MOV R8,#0
107 MOV R9,#0
108
109 SUBS R0,R0,#16 ;4 or more words to do?
110 BLT %03insert_reserve
111 SUBS R0,R0,#16 ;8 or more words to do?
112 BLT %02insert_reserve
113
114 01 STMIA R1!,{R2-R9} ;Blank out 8 words
115 SUBS R0,R0,#32 ;Decrement counter
116 BGE %01insert_reserve ;And keep going round
117
118 CMP R0,#-32 ;Are we finished?
119 BEQ %90insert_reserve ;Yes -- return then
120
121 02 ADDS R0,R0,#16 ;4 whole words to do?
122 BLT %03insert_reserve
123 STMIA R1!,{R2-R5} ;Blank out 4 words
124 BEQ %90insert_reserve ;Done -- return then
125 SUB R0,R0,#16
126
127 03 ADDS R0,R0,#8 ;2 whole words to do?
128 BLT %04insert_reserve
129 STMIA R1!,{R2,R3} ;Blank out 2 words
130 BEQ %90insert_reserve ;Done -- return then
131 SUB R0,R0,#8
132
133 04 ADDS R0,R0,#4 ;1 word to do?
134 BLT %05insert_reserve
135 STR R2,[R1],#4 ;Blank out 1 word
136 BEQ %90insert_reserve ;Done -- return then
137 SUB R0,R0,#4
138
139 05 ADDS R0,R0,#4
140 BEQ %90insert_reserve ;Done -- return then
141
142 06 STRB R2,[R1],#1 ;Save 1 byte
143 SUBS R2,R2,#1
144 BGT %06insert_reserve
145
146 90 LDMFD R13!,{R0-R9,R12,PC}^ ;And return to caller
147
148 LTORG
149
150 ;----- That's all, folks ----------------------------------------------------
151
152 END