1 REM Basic Assembler Supplement 1.00 © 1996-1998 Straylight
4 REM ----- Licensing note ----------------------------------------------------
6 REM This file is part of Straylight's BASIC Assembler Supplement (BAS)
8 REM BAS is free software; you can redistribute it and/or modify
9 REM it under the terms of the GNU General Public License as published by
10 REM the Free Software Foundation; either version 2, or (at your option)
13 REM BAS is distributed in the hope that it will be useful,
14 REM but WITHOUT ANY WARRANTY; without even the implied warranty of
15 REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 REM GNU General Public License for more details.
18 REM You should have received a copy of the GNU General Public License
19 REM along with BAS. If not, write to the Free Software Foundation,
20 REM 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 REM --- Hacking warning ---
24 REM That gorp on the second line is a magic marker word inserted by hand
25 REM (the three letters `BAS' with their top bits set) and space for an offset
26 REM word which marks the offset of the code section from the beginning of
27 REM the LIBRARY link block. Don't play with them unless you (a) know what
28 REM you're doing (and it should be perfectly clear by now that I don't have
29 REM a clue), and (b) want to seriously upset the library search code below.
31 ERROR 0,"You can't run the Basic Assembler Supplement"
35 REM To make this program particularly easy to strip down and transmogrify,
36 REM it contains directives which are picked up by a sed script during
37 REM munging. The directives currently are `del ... edel' which deletes
38 REM all the enclosed lines, and `hex' which inserts the generated hex version
39 REM of the library search code. Directives are enclosed in square brackets.
40 REM It's usual to put them in REM statements.
42 REM ----- Initialisation ----------------------------------------------------
45 DEF FNbas_assign(RETURN d,v%):d=v%:=0
46 DEF PROCbas_const(var$,val%)
47 IF bas_cf% THEN BPUT #bas_cf%,"/\<"+var$+"\>/s//"+STR$(val%)+"/g"
48 IF EVAL("FNbas_assign("+var$+",val%)")
51 DEF FNnext:R%+=4:=R%-4
54 bas_cf%=OPENOUT("work.basconst")
59 PROCbas_const("bcode_wSize",FNnext)
60 PROCbas_const("bcode_init",FNnext)
61 PROCbas_const("bcode_aofInit",FNnext)
62 PROCbas_const("bcode_newPass",FNnext)
63 PROCbas_const("bcode_import",FNnext)
64 PROCbas_const("bcode_export",FNnext)
65 PROCbas_const("bcode_get",FNnext)
66 PROCbas_const("bcode_area",FNnext)
67 PROCbas_const("bcode_reloc",FNnext)
68 PROCbas_const("bcode_noReloc",FNnext)
69 PROCbas_const("bcode_entry",FNnext)
70 PROCbas_const("bcode_save",FNnext)
71 PROCbas_const("bcode_align",FNnext)
72 PROCbas_const("bcode_reserve",FNnext)
73 PROCbas_const("bcode_lit",FNnext)
74 PROCbas_const("bcode_ltorg",FNnext)
75 PROCbas_const("bcode_saveOpt",FNnext)
76 PROCbas_const("bcode_restoreOpt",FNnext)
77 IF bas_cf% THEN CLOSE #bas_cf%
81 REM --- Unexplainable horridness ---
83 REM Tim wants to be able to embed the code into this library file, so
84 REM that it doesn't have to be searched for. I'll therefore have to write
85 REM some code to scan the library list and locate this one, and find the
86 REM code tacked onto the end. Yuk.
89 LOCAL type%,size% :REM [dl]
90 LOCAL workSize%,H%,len%,f%
91 PROCbas_constants :REM [dl]
93 REM --- Old code to load the library from disk ---
98 SYS "OS_File",17,"libs:BAScode" TO type%,,,,size%
99 IF type%<>1 THEN ERROR 0,"BAS code not found"
101 SYS "OS_File",16,"libs:BAScode",bas_code%,0
106 REM --- New hacking to scan the library list ---
108 REM This must be done in assembler, of course ;-) Time to put on my pointy
109 REM Rincewind hat... I've tried to do this in one pass because I'm lazy --
110 REM I guess that's why it's unreadable.
116 ; exit with r0 == pointer to code, or 0 if not found (erk!)
118 ldr r2,[pc] ; load the magic marker word
119 mov pc,pc ; skip over the magic marker word
120 dcd &d3c1c2f4 ; this is `REMBAS', with the top bits set
122 ldr r0,[r14,#&24] ; find offset of TIMEOF
123 add r0,r8,r0 ; add on ARGP to find TIMEOF
124 ldr r0,[r0,#&c] ; load the library list base
127 cmp r0,#0 ; is that the end of it all?
128 moveqs pc,r14 ; yes -- oh, well -- it was a nice try
130 ldr r1,[r0,#&44] ; load mystic recognition word
131 cmp r1,r2 ; does it match?
132 ldrne r0,[r0] ; if not there, load the next link
133 subne pc,pc,#28 ; and jump back to `loop' (erk)
135 ldr r1,[r0,#&48] ; load the code offset
136 add r0,r1,r0 ; and add it to the base address
140 REM --- Now some code to dump that out as hex ---
142 bas_code%=USR bas_scratch%
143 IF bas_code%=0 THEN ERROR 0,"BAS code not found: is the library corrupt?"
149 REM --- Back to life as normal ---
151 workSize%=USR(bas_code%+bcode_wSize)
152 DIM bas_workspace% workSize%
154 CALL bas_code%+bcode_init
155 SYS "XOS_ReadVarVal","BAS$Output",bas_scratch%,256,3 TO ,,len%;f%
160 bas_fileName$=$bas_scratch%
164 DEF PROCbas_aofInit(size%)
166 IF size% THEN DIM bas_asmCode% size% ELSE bas_asmCode%=bas_asmCode%
167 IF bas_asmCode%=0 THEN ERROR 0,"No buffer allocated for assembler code"
169 CALL bas_code%+bcode_aofInit,bas_asmCode%
172 REM This function saves a few bytes and tidies up the code a bit.
174 DEF FNbas_call(offset%)
177 =USR(bas_code%+offset%)
179 REM ----- AOF code generation -----------------------------------------------
181 DEF PROCbas_aofSaveAs(name$)
184 CALL bas_code%+bcode_save,name$
188 IF bas_fileName$="" THEN ERROR 0,"No implicit filename"
189 PROCbas_aofSaveAs(bas_fileName$)
193 DEF FNpass=FNbas_call(bcode_newPass)
195 DEF FNbas_port(offset%,A%,s$,t$)
198 CALL bas_code%+offset%,s$,t$
201 DEF FNimport(var$)=FNbas_port(bcode_import,0,var$,var$)
202 DEF FNimportAs(sym$,var$)=FNbas_port(bcode_import,0,sym$,var$)
203 DEF FNimportWeak(var$)=FNbas_port(bcode_import,1,var$,var$)
204 DEF FNimportWeakAs(sym$,var$)=FNbas_port(bcode_import,1,sym$,var$)
205 DEF FNexport(var$)=FNbas_port(bcode_export,0,var$,var$)
206 DEF FNexportAs(var$,sym$)=FNbas_port(bcode_export,0,var$,sym$)
207 DEF FNexportStrong(var$)=FNbas_port(bcode_export,1,var$,var$)
208 DEF FNexportStrongAs(var$,sym$)=FNbas_port(bcode_export,1,var$,sym$)
213 CALL bas_code%+bcode_get,file$
217 LOCAL err%,leaf$,lower$,i%
219 FOR i%=1 TO LEN(lib$)
220 IF INSTR(":.",MID$(lib$,i%,1)) THEN leaf$=MID$(lib$,i%+1)
222 FOR i%=1 TO LEN(leaf$)
223 lower$+=CHR$(ASC(MID$(leaf$,i%,1)) OR &20)
226 ON ERROR LOCAL err%=TRUE
228 IF EVAL("FN"+lower$+"_test")
231 IF err%=TRUE THEN LIBRARY lib$
234 DEF FNarea(name$,attr$)
237 IF INSTR(attr$,"CODE") THEN A%+=&200
238 IF INSTR(attr$,"COMDEF") THEN A%+=&400
239 IF INSTR(attr$,"COMMON") THEN A%+=&800
240 IF INSTR(attr$,"NOINIT") THEN A%+=&1000
241 IF INSTR(attr$,"READONLY") THEN A%+=&2000
242 IF INSTR(attr$,"DEBUG") THEN A%+=&8000
243 IF A% AND &800 THEN A%=A% OR &1000
244 IF A% AND &200 THEN A%=A% OR &2000
246 CALL bas_code%+bcode_area,name$
249 DEF FNreloc=FNbas_call(bcode_reloc)
250 DEF FNnoReloc=FNbas_call(bcode_noReloc)
252 DEF FNentry=FNbas_call(bcode_entry)
254 REM ----- Literal handling --------------------------------------------------
258 bas_savedOpt%=USR(bas_code%+bcode_saveOpt)
278 [ opt 4: equs str$+CHR$0:]
281 DEF FNliterr(err%,str$)
283 [ opt 4: dcd err%: equs str$+CHR$0:]
289 CALL bas_code%+bcode_restoreOpt
295 =FNbas_call(bcode_lit)
300 CALL bas_code%+bcode_restoreOpt
306 =FNbas_call(bcode_lit)
308 DEF FNltorg=FNbas_call(bcode_ltorg)
310 REM ----- Initialising areas ------------------------------------------------
312 DEF FNalign=FNbas_call(bcode_align)
313 DEF FNreserve(A%)=FNbas_call(bcode_reserve)
317 IF FNbas_call(bcode_noReloc)
319 SYS "OS_File",16,file$,O%,0
322 IF FNbas_call(bcode_reloc)
327 SYS "OS_File",17,file$ TO ,,,,size%
330 REM ----- Laying out storage areas ------------------------------------------
336 DEF PROCws_base(start%)
345 bas_R%=(bas_R%+3) AND -4
352 DEF FNws_byte=FNws(1)
354 REM ----- Long directives ---------------------------------------------------
356 DEF FNadrl(r%,adr%)=FNaddccl(14,r%,15,adr%-P%-8)
357 DEF FNadrccl(cc%,r%,adr%)=FNaddccl(cc%,r%,15,adr%-P%-8)
358 DEF FNaddl(r%,b%,off%)=FNaddccl(14,r%,b%,off%)
359 DEF FNaddccl(cc%,r%,b%,off%)
361 [opt 4:addeq r%,b%,#off% AND 255:addeq r%,r%,#off% AND -256:]
363 [opt 4:subeq r%,pc,#(-off%) AND 255:subeq r%,r%,#(-off%) AND -256:]
365 !(O%-8)=!(O%-8) OR (cc%<<28)
366 !(O%-4)=!(O%-4) OR (cc%<<28)
369 DEF FNldrl(r%,adr%)=FNldrrccl(14,r%,15,adr%-P%-8)
370 DEF FNldrccl(cc%,r%,adr%)=FNldrrccl(cc%,r%,15,adr%-P%-8)
371 DEF FNldrrl(r%,b%,off%)=FNldrrccl(14,r%,b%,off%)
372 DEF FNldrrccl(cc%,r%,b%,off%)
374 [opt 4:addeq r%,b%,#off% AND -256:ldreq r%,[r%,#off% AND 255]:]
376 [opt 4:subeq r%,b%,#(-off%) AND -256:ldreq r%,[r%,#-((-off%) AND 255)]:]
378 !(O%-8)=!(O%-8) OR (cc%<<28)
379 !(O%-4)=!(O%-4) OR (cc%<<28)
382 REM ----- That's all, folks -------------------------------------------------