chiark / gitweb /
Initial revision
[ssr] / StraySrc / Libraries / BAS / src / s / bas
1 ;
2 ; bas.s
3 ;
4 ; Base code for BAS
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.aofGen
37                 GET     sh.basicEnv
38                 GET     sh.basTalk
39                 GET     sh.fastMove
40                 GET     sh.flex
41                 GET     sh.get
42                 GET     sh.insert
43                 GET     sh.lit
44                 GET     sh.messages
45                 GET     sh.string
46                 GET     sh.vars
47                 GET     sh.workspace
48
49 ;----- Branch table header --------------------------------------------------
50
51                 AREA    |!BAS$$Header|,CODE,READONLY
52
53                 B       bas__workSize           ;Find workspace requirements
54                 B       bas__init               ;Initialise workspace
55                 B       aof_init                ;Initialise AOF generation
56                 B       aof_pass                ;Signal start of new pass
57                 B       aof_iImport             ;Import a symbol
58                 B       aof_export              ;Export a symbol
59                 B       get                     ;Read in a header file
60                 B       aof_area                ;Define start of new area
61                 B       aof_reloc               ;Mark start of reloc area
62                 B       aof_noReloc             ;Mark start of non-reloc area
63                 B       aof_entry               ;Define entry point of image
64                 B       aof_save                ;Save AOF file
65                 B       insert_align            ;Align and add zeroes
66                 B       insert_reserve          ;Reserve lots of zeroes
67                 B       lit_add                 ;Add data to literal pool
68                 B       lit_ltorg               ;Insert a literal pool
69                 B       bas__saveOpt            ;Read the current OPT value
70                 B       bas__restoreOpt         ;Restore the OPT value
71
72 ;----- Main code ------------------------------------------------------------
73
74                 AREA    |BAS$$Code|,CODE,READONLY
75
76 ; --- bas__workSize ---
77 ;
78 ; On entry:     --
79 ;
80 ; On exit:      R0 == size of workspace required (picked up by USR())
81 ;
82 ; Use:          Allows the BASIC component to allocate a workspace block of
83 ;               the right size.  This will then be passed to us in R7 when
84 ;               we get called later.
85
86 bas__workSize   ROUT
87
88                 LDR     R0,=bas_wSize           ;Get the workspace size
89                 MOVS    PC,R14                  ;And return to caller
90
91                 LTORG
92
93 ; --- bas__init ---
94 ;
95 ; On entry:     R7 == address of workspace
96 ;               R8-R14 from BASIC's CALL
97 ;
98 ; On exit:      --
99 ;
100 ; Use:          Initialises the code component of BAS.
101
102 bas__init       ROUT
103
104                 STMFD   R13!,{R12,R14}          ;Save some registers
105                 STR     R12,[R7,#:INDEX:be__line] ;Store line value
106                 MOV     R12,R7                  ;Point to my workspace
107
108                 ; --- Fill in the BASIC environment things ---
109
110                 STR     R8,be__argp             ;Save BASIC's workspace addr
111                 STR     R14,be__interface       ;And save the interface ptr
112
113                 ; --- Set up some special bits ---
114
115                 MOV     R14,#0                  ;Set up string's buffer
116                 STR     R14,str__buffNum        ;Tell it to use the first one
117                 STR     R14,aof__objHead        ;We're not generating AOF
118
119                 ; --- Work out address of A% ---
120
121                 ADR     R0,bas__aPercent        ;Find the variable name
122                 BL      bTalk_lvblnk            ;Find the address of it
123                 STR     R0,be__percents         ;Save this address
124
125                 ; --- Start up our memory manager ---
126
127                 BL      flex_init               ;Initialise flex
128                 BL      vars_set                ;Set up register names etc.
129
130                 LDMFD   R13!,{R12,PC}^          ;And return to caller
131
132 bas__aPercent   DCB     "A%",0
133
134                 LTORG
135
136 ; --- bas__saveOpt ---
137 ;
138 ; On entry:     R8 == BASIC's ARGP pointer
139 ;
140 ; On exit:      R0 == current value of OPT
141 ;
142 ; Use:          Returns the current value of BASIC's assembler options.  This
143 ;               is handy, because BASIC doesn't seem terribly good at
144 ;               handling this by itself.  The value -38 used here is stolen
145 ;               from BAX.
146
147 bas__saveOpt    ROUT
148
149                 LDRB    R0,[R8,#-38]            ;Load the OPT value
150                 MOVS    PC,R14                  ;And return to caller
151
152                 LTORG
153
154 ; --- bas__restoreOpt ---
155 ;
156 ; On entry:     R0 == OPT value to restore
157 ;               R8 == BASIC's ARGP pointer
158 ;
159 ; On exit:      --
160 ;
161 ; Use:          Sets the value of BASIC's assembler options to the given
162 ;               value.  This is necessary because BASIC isn't terribly good
163 ;               at nesting the option values.
164
165 bas__restoreOpt ROUT
166
167                 STRB    R0,[R8,#-38]            ;Store the OPT value
168                 MOVS    PC,R14                  ;And return to caller
169
170                 LTORG
171
172 ; --- bas_argString ---
173 ;
174 ; On entry:     R1 == address of destination buffer
175 ;               R9 == pointer to argument entry
176 ;               R10 == number of arguments left
177 ;
178 ; On exit:      R9 increased by 8
179 ;               R10 decreased by 1
180 ;
181 ; Use:          Reads a string argument into a buffer and null terminates
182 ;               it sensibly so we can use it.
183
184                 EXPORT  bas_argString
185 bas_argString   ROUT
186
187                 STMFD   R13!,{R0-R3,R14}        ;Save some registers
188                 SUBS    R10,R10,#1              ;Decrement R10 as promised
189                 BCC     bas_badCall             ;If there wasn't one, die
190                 LDR     R14,[R9,#4]             ;Load the argument type
191                 CMP     R14,#&81                ;Is this a $(addr) string?
192                 BEQ     %50bas_argString        ;Yes -- handle that then
193                 CMP     R14,#&80                ;Is it a normal string?
194                 BNE     bas_badCall             ;No -- the make an error
195
196                 ; --- Handle a normal string variable ---
197
198                 MOV     R0,R1                   ;Point to caller's buffer
199                 LDR     R3,[R9],#8              ;Load the string pointer
200                 ANDS    R14,R3,#3               ;Get non-word-alignedness
201                 BIC     R1,R3,#3                ;Word align anyway
202                 LDMIA   R1,{R1,R2}              ;Load the possible bytes
203                 MOV     R14,R14,LSL #3          ;Convert bytes to bits
204                 MOVNE   R1,R1,LSR R14           ;Shove the bytes down
205                 RSB     R14,R14,#32             ;Get the other shift size
206                 ORRNE   R1,R1,R2,LSL R14        ;And work that out
207                 LDRB    R2,[R3,#4]              ;Load the string length
208                 BL      fastMove                ;(This is overkill)
209                 MOV     R14,#0                  ;Terminate the string
210                 STRB    R14,[R0,R2]             ;Do this nicely
211                 B       %90bas_argString        ;And return to caller
212
213                 ; --- Handle a $(addr) type string ---
214
215 50bas_argString MOV     R2,R1                   ;Keep the buffer pointer
216                 MOV     R0,R1                   ;And point to it for str_cpy
217                 LDR     R1,[R9],#8              ;Point to caller's string
218                 BL      str_cpy                 ;Copy it over (and null term)
219
220 90bas_argString LDMFD   R13!,{R0-R3,PC}^        ;Return to caller
221
222                 LTORG
223
224 ; --- bas_badCall ---
225 ;
226 ; On entry:     --
227 ;
228 ; On exit:      Generates an error
229 ;
230 ; Use:          Generates an error about bad arguments.  It saves space to
231 ;               just have this here.
232
233                 EXPORT  bas_badCall
234 bas_badCall     ROUT
235
236                 ADRL    R0,msg_errBadArg
237                 SWI     OS_GenerateError
238
239                 LTORG
240
241 ; --- bas_noMem ---
242 ;
243 ; On entry:     --
244 ;
245 ; On exit:      Generates an error
246 ;
247 ; Use:          Generates an error about not having any memory left.
248
249
250                 EXPORT  bas_noMem
251 bas_noMem       ROUT
252
253                 ADRL    R0,msg_errNoMoreMem
254                 SWI     OS_GenerateError
255
256                 LTORG
257
258 ;----- That's all, folks ----------------------------------------------------
259
260                 END