Date : Fri, 06 Nov 2009 15:15:16 +0100
From : rick@... (Rick Murray)
Subject: Basic6809 1.00
Phill Harvey-Smith wrote:
> Why do people still use assembler embedded in basic programs to build
> stuff with ? Especially considdering some of the limitations of such ?
Flexibility.
Say you have a block of memory. You want it to be a table. A sine lookup
table. How many assemblers do you think will be able to handle that.
You'd probably, in most cases, need to "include" a prebuilt table, which
I guess is fine if you happen to have one...
...with BASIC, roll some code, tell it to stick the output at &xxxx, run
the thing right there during the assembly.
Flexibility.
It is a real programming language. You can use all sorts of constructs,
and constants can even be the result of BASIC functions. If you've ever
used Acorn's objasm (ARM assembler), you'll appreciate that a powerful
macro-capable assembler is both a blessing and a curse.
With BASIC, the only limitations that I've come across are:
1. You need to tell it where to store the code. This is because the
BASIC assembler also has to perform the "link" stage. You can
mitigate a lot of this by setting P% once and just chaining the
bits of code.
2. Two-pass assembly for resolving addresses. Not necessary if you
write code like PASCAL suggests, but most sane people start at the
top of file #1, not the end of it all! Again, this is something
a linker would do.
3. Not natively APCS capable. Only relevant to ARM code, and there's
ways and means there too. :-)
> Moreso on the BBC than on the Arch, as at least the arch doesn't have
> the limitations of memory that the BBC does.
Any which way you slice the cake, the BBC will hit you with limitations.
It is more evident in the BBC because you are using a machine with quite
a small specification. But it is not limited to the BBC - for example...
The Acorn Pocketbook "Word" processor is only capable of dealing with
files up to about 30K or about 60K (I don't remember if it is a signed
int or not), whatever, I've maxed that a number of times.
Several of my OPL programs ( www.heyrick.co.uk/software/pb2/ ) are too
big to be translated on the organiser itself, so I use the PC software
to do it.
My old Am?lie system emulator is a TurboC++ project, as the files grew
too large (>~62K) for TurboC to cope with. Both are now freebies on
Borland's site, but DOS-only.
Because my eeePC uses an SSD as opposed to a harddisc, it is set to the
sensible option of NOT using any swapfile. Plenty will fit into 1Gb RAM.
However, start Firefox, open half a dozen tabs, hardcore surf, and see
how long it takes Firefox to crash. First all the pictures and icons
will 'vanish'. Windows may or may not report some bollocks like "Virtual
memory is running low... Windows will increase the size of your virtual
memory paging file". Then Firefox will eventually crash. But it crashes
very politely, and in most cases a reload restores everything (gee, does
that sound like a hell of a memory leak?!?) and you can go right back to
where you were. Nice feature.
Anyway. Everything has limitations. Work with them rather than against them.
Here's an example. NOBODY except a total dweeb or somebody writing a
utility to fit in a spare kilobyte or two writes ONE source file. It
makes a lot more sense to write in a modular sense. Let's assume I am
writing some whizzy teletext software for the Beeb:
$.BUILD_IT
Starts the process. Defines some global memory locations.
Calls...
$.IIC
Functions to bit-bash IIC on the user port.
Calls...
$.TUNER
Routines for tuning in.
Calls...
$.EUROTTX
Routines for talking to the teletext decoder chip.
Calls...
$.PGFETCH
Routines for looking for pages.
Calls...
$.TTXDISP
Routines for displaying the teletext content.
Calls...
$.TSDP
Routines for handling service data packets.
Calls...
...and so on for all the user interface garbage, load/save/print, whatever.
Doing it like this, the modules can be small, can fit in available
memory (remember, alongside the actual code being built!), and because
it is modular...
There are three known types of Ground Control teletext receiver. The
first (my 'dead' one) is a UTA-1. There is a UTA-2 which I know nothing
about. My working receiver is a UTA-3.
Now the UTA-1 used a CITAC chip to create tuning voltages or whatever it
is to send to a basic tuning module. The UTA-3, on the other hand, works
in very much the same way, only the tuning module accepts IIC data and
tunes itself.
The code is not compatible between them. All of my teletext software
(RISC OS, DOS, Windows) will speak to the tuner in the UTA-3. It won't
talk to the older CITAC.
Now, imagine some design modification affected your software. Do you
hunt around a huge mess of code looking for what to alter, or do you
simply rewrite $.TUNER accordingly?
Likewise, the user might actually have something else on the user port,
this requiring you to bit bang IIC somewhere else. The printer port?
Some latches on a daughterboard that plugs into the 1MHz bus? Not a
problem - just rewrite $.IIC as required.
There's another benefit. Your company sells these teletext gadgets in
two configurations - a user port one and a 1MHz bus one. BASIC can help
here. It shouldn't be too hard to set up variables so the entire build
process happens twice, generating $.TELETEXT and $.TTX1MHZ. All you need
to do is call $.BUILT_IT and go turn the kettle on...
Also, you can PRINT stuff along the way (many assemblers are rather
limited in custom user screen output). You can just print something like
"PGFETCH ( 5/16)", or you can spit loads of info. You can make inline
assert() clones. You can do loads of stuff.
> I have tried understanding the code of some projects (the menu program
> for BeebMMC is one example that springs to mind), but the total lack of
> formatting, comments and meaningfull names (all due to lack of memory),
> make this task very difficult,
Lack of properly disciplined programming. Space is nowhere near as
exuberant as on a RISC OS machine, but none the less, there is no decent
excuse (except for squeezing a lot of BASIC into a small space) that
would justify single-digit variable names. If you're making an assembled
program, split the source into modules. Give yourself time and space.
For your memory might be an amazing thing capable of knowing exactly
what m% and q$ refer to, but are you going to know all of this in a
year's time?
> in some ways I feel I would be better working from a dissasembily,
> at least that way I know it's just code :)
I've been searching, looking, grovelling for anybody who might stand a
chance of having any version of the FileStore firmware source codes. The
6502's instruction set ranges from 1 to 3 bytes. These can be at any
address, as opposed to the ARM's word alignment. Furthermore, as there
are no obvious 'trends' (like the ARM's condition code nibble), it makes
GETTING a reliable disassembly quite difficult. You could, with my
FileStore emulator, open the memory dump (after the emulator has done
the EPROM->RAM copy) and Page Down (I think?) a random number of times
until you are at any random page. Pick one with no visible ASCII strings.
Is that code? Is it data? A mixture of both? Where?
Here's a bit of disassembly. It is code intended for a Rockwell 65C02,
hence the BBR instruction.
Tell me the significance of this code snippet:
&3954 36 35 ROL &35,X
&3956 30 32 BMI &398A
&3958 20 72 6F JSR &6F72
&395B 6F 6C 7A BBR6 &6C,&39D8
&395E 20 6F 6B JSR &6B6F
&3961 21 20 AND (&20,X)
&3963 3A DEA
&3964 2D 29 00 AND &0029
> Personally I prefer to use assemblers like BeebASM(6502) and
> Toolshed(6809) as they allow me to not limit the size of my source
> files, and so make my source more maintainable as I can lay it out in a
> way that is easier to understand, plus I can add verbose comments
> without fear of overflowing the memory limits of the assembler.
All of which you can do with BASIC! CHAIN"" is a very useful thing.
> I'm probably going to get branded a heritc for this, but so what I feel
> the question has to be asked :)
It's called "knowing your tools" (or maybe "knowing your options"?).
Granted, an assembler is easier to use as you don't (usually) need to
dick around setting up OPT and P% and writing a two-pass loop that could
span a dozen files... but once that boilerplate code is in place, the
other source files can be little more complicated than:
10 [ OPT opt%
20 \ blah!
30 ]
40 CHAIN "NextOne"
In fact, the only real benefit I can see for an assembler is that it
ought to be able to assemble to disc (as opposed to
in-memory-and-save-after). This will give you more room to play around
in. But it's not an insurmountable issue.
Best wishes,
Rick.
--
Rick Murray, eeePC901 & ADSL WiFI'd into it, all ETLAs!
BBC B: DNFS, 2 x 5.25" floppies, EPROM prog, Acorn TTX
E01S FileStore, A3000/A5000/RiscPC/various PCs/blahblah...