Reducing Basic Program Size

bbc micro/electron/atom/risc os coding queries and routines
User avatar
Richard Russell
Posts: 1701
Joined: Sun Feb 27, 2011 10:35 am
Location: Downham Market, Norfolk
Contact:

Re: Reducing Basic Program Size

Post by Richard Russell » Wed Feb 12, 2020 2:05 pm

Rich Talbot-Watkins wrote:
Wed Feb 12, 2020 12:57 pm
Do you remember if the BBC BASIC specification required this to work, or whether it's just an undefined consequence of how BBC BASIC implements variable assignment (allocating a new variable and defaulting it to zero prior to evaluating the RHS)?
The 'specification' didn't go into that much detail, but it did imply the behaviour by calling for a good degree of compatibility with the Microsoft BASICs of the day. In those BASICs it was legitimate to write:

Code: Select all

      A = A + 1
(where A wasn't previously defined) because all numeric variables initially 'exist', with a value of zero. There is nothing comparable to a 'No such variable' error; the very first line of a program could be:

Code: Select all

      PRINT A
which would print zero, not raise an error as it would in BBC BASIC. This behaviour has survived to the present day in languages like Liberty BASIC in which all variables - even arrays with up to 10 elements - initially 'exist' but with values of zero or an empty string as appropriate.

In practice it's extremely useful to have a way of forcing a variable to exist if it doesn't, but not changing its value if it does (for example when releasing resources in a 'cleanup' routine). I tend to use the compound += operator, introduced in BBC BASIC V, for this:

Code: Select all

      var% += 0
      IF var% THEN PROCrelease(var%)
I am suffering from 'cognitive decline' and depression. If you have a comment about the style or tone of this message please report it to the moderators by clicking the exclamation mark icon, rather than complaining on the public forum.

User avatar
Rich Talbot-Watkins
Posts: 1679
Joined: Thu Jan 13, 2005 5:20 pm
Location: Palma, Mallorca
Contact:

Re: Reducing Basic Program Size

Post by Rich Talbot-Watkins » Wed Feb 12, 2020 6:18 pm

I guess I have the C++ orthodoxy of "declare all variables before using them" too ingrained!

User avatar
LordVaderUK
Posts: 208
Joined: Thu Jan 31, 2019 12:26 am
Location: Hampshire
Contact:

Re: Reducing Basic Program Size

Post by LordVaderUK » Mon Jun 01, 2020 1:07 pm

One way programs can use space unnecessarily is having two copies of things in memory: one copy in a program statement defining it, and another copy in its intended location in memory.
As you mentioned, the classic example is DATA statements - the data exists twice, in the DATA statements themselves, and in the variable heap once they've been read. A lot of DATA use can be rewitten to avoid this duplication, for example the classic "day of week" function can be written:
DEF FNmon(mon%)=MID$("JanFebMarAprMayJunJulAugSepOctNovDec",mon%*3-2,3)

See http://beebwiki.mdfs.net/Data_without_DATA
Wow this is a GREAT tip. I just managed to get rid of a 6 element string array with this little tip :-) Struggling to ensure my code fits into a BBC B. Thanks!
Loving my BBC Master 128

joachim
Posts: 181
Joined: Wed Jun 21, 2006 2:20 am
Location: Germany
Contact:

Re: Reducing Basic Program Size

Post by joachim » Mon Jun 01, 2020 3:47 pm

jgharston wrote:
Sun Dec 15, 2019 10:03 pm
julie_m wrote:
Sun Dec 15, 2019 6:59 pm
One way programs can use space unnecessarily is having two copies of things in memory: one copy in a program statement defining it, and another copy in its intended location in memory.
As you mentioned, the classic example is DATA statements - the data exists twice, in the DATA statements themselves, and in the variable heap once they've been read. A lot of DATA use can be rewitten to avoid this duplication, for example the classic "day of week" function can be written:
DEF FNmon(mon%)=MID$("JanFebMarAprMayJunJulAugSepOctNovDec",mon%*3-2,3)
Sphinx Adventure (IIRC) solves the problem in the opposite way: it stores the room descriptions in DATA statements but doesn't make an in-memory copy. How? Well, when you're in room L% and need a description, it does what amounts to:

Code: Select all

RESTORE L%: READ LOC$: PROCprint(LOC$)
That's right, the data for location number L% is stored in line L% (or the next valid data line after it).

cmorley
Posts: 1348
Joined: Sat Jul 30, 2016 8:11 pm
Location: Oxford
Contact:

Re: Reducing Basic Program Size

Post by cmorley » Mon Jun 01, 2020 4:44 pm

I use DATA & RESTORE without copying to other memory in RTool for the menu.

Code: Select all

REPEAT
PRINT"? ";:K$=GET$:IF K$>"`":K$=CHR$(ASCK$-32)
F$="unrecognised":A$=""
RESTORE
REPEAT:READ key$,func$,arg$,help$:IF key$=K$ THEN F$=func$:A$=arg$
UNTIL key$=""
PRINT K$;" ";
IF A$<>"" THEN INPUT LINE ""A$:A%=VAL(A$):IF A$=""THENF$="argument"
PRINT EVAL("FN"+F$)
UNTIL FALSE

DATA I,romlist,,List ROMs
DATA *,oscli,<cmd>,Issue user OS Command
DATA .,cat,,Catalogue filesystem (*.)
DATA D,drive,<drive>,Change drive
DATA L,load,<afsp>,Load ROM image from file
DATA S,save,<afsp>,Save ROM image to file
DATA R,read,<bank>,Read ROM image
DATA P,program,<bank>,Write ROM image
DATA V,verify,<bank>,Verify ROM image
DATA E,erase,<bank>,Erase complete 64K EEPROM
DATA K,lock,<bank>,Lock (write protect) SRAM
DATA U,unlock,<bank>,Unlock (write enable) SRAM
DATA Q,quit,,Quit
DATA B,reset,,Reboot computer
DATA ?,help,,Display this help
DATA ,,,

User avatar
sa_scott
Posts: 161
Joined: Wed Feb 09, 2011 11:34 pm
Location: Witley, Surrey, UK
Contact:

Re: Reducing Basic Program Size

Post by sa_scott » Wed Nov 25, 2020 7:21 pm

I wanted to pick up further on a point made with regards to storing DATA statements into a memory location.

My Androidz game has 20 levels of compressed level data. Each level occupies 65 bytes. How would I go about pushing this into a given location, .e.g. &A00, and keep it in memory once I load the main game file? Can I then refer to this memory location, for unpacking and displaying the data?

Currently, the data looks like this:

DATA VVVVV/...ISZfzMA...OA```O8/.IL8...L8/.ILA```OA...OSZfzM/...IVVVVV

I've looked at magazine listings over various magazines, but can't seem to find an example of one that has done this technique before. I would prefer to keep everything 'in listing' for this particular game, rather than have separate data files. Call me a traditionalist.

20 levels would equate to 1300 bytes (20 x 65 characters), I was planning on using &A00 onwards for the storage.

I'm still keen on using MODE2 for the game, but without removing the data from the listing, this can't happen!

Thanks in advance
Stephen
--
Stephen Scott, Digital Media Professional
www.sassquad.net

User avatar
lurkio
Posts: 3032
Joined: Wed Apr 10, 2013 12:30 am
Location: Doomawangara
Contact:

Re: Reducing Basic Program Size

Post by lurkio » Wed Nov 25, 2020 7:32 pm

sa_scott wrote:
Wed Nov 25, 2020 7:21 pm
My Androidz game has 20 levels of compressed level data. Each level occupies 65 bytes. How would I go about pushing this into a given location, .e.g. &A00, and keep it in memory once I load the main game file? Can I then refer to this memory location, for unpacking and displaying the data?
http://mdfs.net/Docs/Comp/BBC/AllMem

http://mdfs.net/Docs/Comp/BBC/Disk/DFSMem

:idea:

User avatar
sa_scott
Posts: 161
Joined: Wed Feb 09, 2011 11:34 pm
Location: Witley, Surrey, UK
Contact:

Re: Reducing Basic Program Size

Post by sa_scott » Wed Nov 25, 2020 8:52 pm

Thanks Lurkio.

Looks like I can use &A00 (1300 or &514 bytes) takes me into &E08, which I think is ok.

This old game - Gold Mine - http://bbcmicro.co.uk//game.php?id=1590 - uses some data file loaded into &2200. The BASIC code then pokes at this memory location to grab the level layout. I can always try this as well. Notably, the game sets HIMEM to a location just below &2200 to prevent the data being polluted.

I was also very intrigued by this game - Rabbit Run - http://bbcmicro.co.uk//game.php?id=843 - that has very similar mechanics to mine, except the &FFEE screen poke routine is not only in machine code, but the enemies home in on your position also using machine code. The code can only be disassembled, and I can't make head nor tail of it, unfortunately. My homing code is all BASIC, and rather slow and flickery. I suspect it will be even slower if I make the jump to Mode 2.

Stephen
--
Stephen Scott, Digital Media Professional
www.sassquad.net

User avatar
lurkio
Posts: 3032
Joined: Wed Apr 10, 2013 12:30 am
Location: Doomawangara
Contact:

Re: Reducing Basic Program Size

Post by lurkio » Wed Nov 25, 2020 8:55 pm

sa_scott wrote:
Wed Nov 25, 2020 8:52 pm
Looks like I can use &A00 (1300 or &514 bytes) takes me into &E08, which I think is ok.
Not if you're using disc rather than tape.

See the second link in my previous post.

See also: viewtopic.php?f=2&t=13345&p=174350&hili ... ge#p174350

:idea:

User avatar
sa_scott
Posts: 161
Joined: Wed Feb 09, 2011 11:34 pm
Location: Witley, Surrey, UK
Contact:

Re: Reducing Basic Program Size

Post by sa_scott » Wed Nov 25, 2020 9:01 pm

Thanks, I'm getting confused. &E00 is where DFS starts.

My screen data has some repetition - the top and bottom lines of each level are always filled in, and are therefore not necessary. This will shave some data off. I'll keep stabbing away at this.

bbcmicro.co.uk is immensely useful for this type of thing - much more handy than rifling through old magazines!

Stephen
--
Stephen Scott, Digital Media Professional
www.sassquad.net

User avatar
lurkio
Posts: 3032
Joined: Wed Apr 10, 2013 12:30 am
Location: Doomawangara
Contact:

Re: Reducing Basic Program Size

Post by lurkio » Wed Nov 25, 2020 9:05 pm

sa_scott wrote:
Wed Nov 25, 2020 9:01 pm
Thanks, I'm getting confused. &E00 is where DFS starts.
Beware of &D00 when running from disc! See the "AllMem" link I posted above.

:!:

User avatar
sa_scott
Posts: 161
Joined: Wed Feb 09, 2011 11:34 pm
Location: Witley, Surrey, UK
Contact:

Re: Reducing Basic Program Size

Post by sa_scott » Wed Nov 25, 2020 9:24 pm

I'm currently setting PAGE to &1100 when running the main game file - the first file displays the instructions, and has page set at &1900. I'm assuming a BBC DFS system.

If I could, I would relocate page to &E00, but when the game is over, a third part is loaded containing your verdict, which needs your score tally from the game. Therefore, setting to &E00 would lose the ability to load that part.

This is where the Rabbit Run reference comes in, as it also gives you a verdict, but is all self contained.
--
Stephen Scott, Digital Media Professional
www.sassquad.net

User avatar
lurkio
Posts: 3032
Joined: Wed Apr 10, 2013 12:30 am
Location: Doomawangara
Contact:

Re: Reducing Basic Program Size

Post by lurkio » Thu Nov 26, 2020 11:30 am

sa_scott wrote:
Wed Nov 25, 2020 9:24 pm
If I could, I would relocate page to &E00, but when the game is over, a third part is loaded containing your verdict, which needs your score tally from the game. Therefore, setting to &E00 would lose the ability to load that part.
There are ways around that. For example, in the main game (with PAGE at &E00) you could define function key 10 (the Break key) with *KEY10... to load the third part. And then CALL!-4 to trigger a Break and activate the function-key definition. PAGE should be reset on Break.

Or you might not need to define Break at all. It might be enough to define *KEY0PAGE=&1900|M*DISC|MCHAIN"VERDICT"|M and then trigger f0 with *FX138,0,128 as the last thing you do in the main game before END.

:idea:

Post Reply

Return to “programming”