Beebasm requests

Development tools discussion area.
Post Reply
Kevin Edwards
Posts: 97
Joined: Tue Mar 14, 2006 9:16 pm
Contact:

Beebasm requests

Post by Kevin Edwards » Tue Jul 17, 2018 11:46 am

Hi,

I'm not sure if this is the right place for Beebasm requests, hopefully it is.

Basically, i'm moving some old BBCBasic style 6502 assembly source code over to beebasm and found that it would be really useful if there were some re-definable variables that i could make use of - A% to Z% would be ideal candidates. P% is already present for the 'program counter', I just wondered if it would be possible to add the rest of them - A% to Z%?

I have some DEFFN 'macros' that need to update one or more persistent variables that are used again and again, typically accumulating a 'counter'. I did this using the persistent % variables.

Thought i'd ask here rather than start hacking the source myself in a haphard way!

BTW Really loving beebasm and Visual Studio Code as a dev environment. I use Visual Studio on a day to day basis, and couldn't even think about going back to the BBC Basic editor / environment!

I'd also be interested to know how people are debugging Beeb code using PC emulators / dev environment. I'm currently building an SSD and deploying to B-Em. Is there a nice way of debugging - breakpoints ( PC and data ), single stepping etc.

Thanks in advance for any information!

Cheers,
Kevin.

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

Re: Beebasm requests

Post by Rich Talbot-Watkins » Tue Jul 17, 2018 11:56 am

Hey Kevin

The problem with supporting mutable variables in BeebAsm is that, even though it is implemented as a two-pass assembler, it doesn't present itself as such. Thus when symbols are forward referenced, the expectation is that they will have unambiguously one and only one value.

Seems to me that mutable variables would have to be a different type of 'thing' which weren't allowed to be forward referenced and were treated distinctly (probably with some kind of prefix or suffix on them to distinguish them from regular symbols). This is in fact the case anyway with the resident integer variables, in as much as they are always defined, and persistent.

Note that P% is only supported in this way so that programs in BBC BASIC would assemble with BeebAsm with the least possible work! (and it doesn't even support O% either). I tend to use ORG rather than P%=... to set the assembly address, and use '*' to mean 'current location'.

Can you paste in the code you want to port, in case there's some other way of doing what you want?

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

Re: Beebasm requests

Post by Rich Talbot-Watkins » Tue Jul 17, 2018 12:00 pm

(Incidentally, I don't think this would be particularly different to implement either; A%..Z% could live in the symbol table like any other symbol, and be force created and initialized to zero at the beginning of each pass. Then the assignment code could make a special case of them. BeebAsm already recognises symbols with a '%' suffix as a valid symbol name.)
Last edited by Rich Talbot-Watkins on Tue Jul 17, 2018 12:01 pm, edited 1 time in total.

Kevin Edwards
Posts: 97
Joined: Tue Mar 14, 2006 9:16 pm
Contact:

Re: Beebasm requests

Post by Kevin Edwards » Tue Jul 17, 2018 12:15 pm

Hi Rich,

Thanks for the quick response. I can see why re-definable 'normal' variables would be problematic!

If support for A% to Z% could be added then that would be so cool. I also use B% below to keep track of the start of the code block in each source file so i can see how large each block of object code is.

Here's the code in question. The two 'FN macros' generate lo/hi byte lookup tables for the 'graphics' data described by the macro parameters:-

Thanks!
Kevin.



\\ B%=P%
\\ [OPT pass

.TSpGraLo
OPT FNMkGraVecLo(Expl,4*16,6) \ 0 to 11 Explosion

OPT FNMkGraVecLo(MyShip,4*16,1) \ 12 to 17 My ship(s)
OPT FNMkGraVecLo(0,4*16,1)
OPT FNMkGraVecLo(0,4*16,1)

OPT FNMkGraVecLo(Aliens,4*16,1) \ 18 to 19 Jelly mon
OPT FNMkGraVecLo(0,4*16,1) \ 20 to 21
OPT FNMkGraVecLo(0,4*16,1) \ 22 to 23
OPT FNMkGraVecLo(0,4*16,1) \ 24 to 25
OPT FNMkGraVecLo(0,4*16,1) \ 26 to 27
OPT FNMkGraVecLo(0,4*16,1) \ 28 to 29
OPT FNMkGraVecLo(0,4*16,1) \ 30 to 31
OPT FNMkGraVecLo(0,4*16,1) \ 32 to 33
OPT FNMkGraVecLo(0,4*16,1) \ 34 to 35
OPT FNMkGraVecLo(0,4*16,1) \ 36 to 37
OPT FNMkGraVecLo(0,4*16,2) \ 38 to 41 Feature object
OPT FNMkGraVecLo(0,4*7,1) \ 42 to 43 1000pts
OPT FNMkGraVecLo(0,3*8,1) \ 44 to 45 Xtra Life
OPT FNMkGraVecLo(0,2*8,2) \ 46 to 49 Flash bomb

OPT FNMkGraVecLo(BigAl,4*32,1) \ 50 to 51 Big Alien 1 Part 1
OPT FNMkGraVecLo(0,4*32,1) \ 52 to 53 Big Alien 1 Part 2
OPT FNMkGraVecLo(0,4*32,1) \ 54 to 55 Big Alien 2 Part 1
OPT FNMkGraVecLo(0,4*32,1) \ 56 to 57 Big Alien 2 Part 2

.TSpGraHi
OPT FNMkGraVecHi(Expl,4*16,6)

OPT FNMkGraVecHi(MyShip,4*16,1)
OPT FNMkGraVecHi(0,4*16,1)
OPT FNMkGraVecHi(0,4*16,1)

OPT FNMkGraVecHi(Aliens,4*16,1) \ Jelly mon
OPT FNMkGraVecHi(0,4*16,1)
OPT FNMkGraVecHi(0,4*16,1)
OPT FNMkGraVecHi(0,4*16,1)
OPT FNMkGraVecHi(0,4*16,1)
OPT FNMkGraVecHi(0,4*16,1)
OPT FNMkGraVecHi(0,4*16,1)
OPT FNMkGraVecHi(0,4*16,1)
OPT FNMkGraVecHi(0,4*16,1)
OPT FNMkGraVecHi(0,4*16,1)
OPT FNMkGraVecHi(0,4*16,2) \ Feature object
OPT FNMkGraVecHi(0,4*7,1)
OPT FNMkGraVecHi(0,3*8,1)
OPT FNMkGraVecHi(0,2*8,2) \ Flash bomb

OPT FNMkGraVecHi(BigAl,4*32,1) \ Big Alien 1 Part 1
OPT FNMkGraVecHi(0,4*32,1) \ Big Alien 1 Part 2
OPT FNMkGraVecHi(0,4*32,1) \ Big Alien 2 Part 1
OPT FNMkGraVecHi(0,4*32,1) \ Big Alien 2 Part 2

\ This table converts 'Graphic Type' values into 'ObjGra' offsets for
\ the base graphic of their frames

.TGTypConv
EQUB 0:EQUB 12:EQUB 14:EQUB 16
EQUB 18:EQUB 20:EQUB 22:EQUB 24:EQUB 26
EQUB 28:EQUB 30:EQUB 32:EQUB 34:EQUB 36
EQUB 38:EQUB 42:EQUB 44:EQUB 46:EQUB 50
EQUB 52:EQUB 54:EQUB 56

\ -------------------------------------

.Expl
\\ OPT FNLoadDat0("Section.ObExpl",&300)
INCBIN "Section\ObExpl.o"

.MyShip
\\ OPT FNLoadDat0("Section.ObMyShip",&180)
INCBIN "Section\ObMyShip.o"

.Aliens
\\ OPT FNLoadDat0("Section.ObAliens",&6A8)
INCBIN "Section\ObAliens.o"

.BigAl
\\ OPT FNLoadDat0("Section.ObBigAl",&400)
INCBIN "Section\ObBigAl.o"

\\ ]

\\ PRINT"Sp Graphic from &";~B%;" to &";~P%-1;" (";P%-B%;")"
\\ PAGE=PG%
\\ RETURN

\\ DEFFNLoadDat0(file$,size%)
\\ IFpass>=6 OSCLI"LOAD "+file$+" "+STR$~(O%)
\\ O%=O%+size%:P%=P%+size%
\\ =pass

\\ DEFFNMkGraVecLo(Strt%,Size%,Num%)
\\ IFStrt%<>0 N%=Strt%
\\ FORL%=Num%-1TO0STEP-1
\\ [OPT pass
\\ EQUB (N%+L%*Size%) MOD 256
\\ ]NEXT
\\ M%=Num%*Size%
\\ FORL%=Num%-1TO0STEP-1
\\ [OPT pass
\\ EQUB (N%+M%+L%*Size%) MOD 256
\\ ]NEXT
\\ N%=N%+2*M%
\\ =pass

\\ DEFFNMkGraVecHi(Strt%,Size%,Num%)
\\ IFStrt%<>0 N%=Strt%
\\ FORL%=Num%-1TO0STEP-1
\\ [OPT pass
\\ EQUB (N%+L%*Size%) DIV 256
\\ ]NEXT
\\ M%=Num%*Size%
\\ FORL%=Num%-1TO0STEP-1
\\ [OPT pass
\\ EQUB (N%+M%+L%*Size%) DIV 256
\\ ]NEXT
\\ N%=N%+2*M%
\\ =pass

[\b]

User avatar
kieranhj
Posts: 724
Joined: Sat Sep 19, 2015 10:11 pm
Location: Farnham, Surrey, UK
Contact:

Re: Beebasm requests

Post by kieranhj » Tue Jul 17, 2018 12:20 pm

If I had mutable variables then I'd be able to implement the Elite checksum calculation code directly in the BeebAsm source (ala the BBC BASIC assembler) without having to resort to Python. I've just realised I can likely abuse the COPYBLOCK command to poke individual byte values back into the output as well...
Bitshifters Collective | Retro Code & Demos for BBC Micro & Acorn computers | https://bitshifters.github.io/

Kevin Edwards
Posts: 97
Joined: Tue Mar 14, 2006 9:16 pm
Contact:

Re: Beebasm requests

Post by Kevin Edwards » Tue Jul 17, 2018 12:28 pm

COPYBLOCK, sounds interesting! Can't find it in the docs, but noticed it in the version history.
Not that i'd ever use it for any hackery :lol:

User avatar
kieranhj
Posts: 724
Joined: Sat Sep 19, 2015 10:11 pm
Location: Farnham, Surrey, UK
Contact:

Re: Beebasm requests

Post by kieranhj » Tue Jul 17, 2018 1:31 pm

Use COPYBLOCK start, end, destination to assemble code at the correct location and then copy it to a different location for loading. Gets around the lack of O%.
Bitshifters Collective | Retro Code & Demos for BBC Micro & Acorn computers | https://bitshifters.github.io/

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

Re: Beebasm requests

Post by Rich Talbot-Watkins » Tue Jul 17, 2018 2:58 pm

For now I'd just be inclined to rewrite the macros within BeebAsm's limitations and change the 0s in the callsites to start+<whatever>. BeebAsm's maintained by the community here these days - I haven't touched it in years - so not sure when you might be able to get these changes in (although feel free to try yourself!).

Code: Select all

MACRO MkGraVecLo start, size, num
    FOR l, num-1, 0, -1
        EQUB LO(start+l*size)
    NEXT
    FOR l, num-1, 0, -1
        EQUB LO(start+(l+num)*size)
    NEXT
ENDMACRO

MACRO MkGraVecHi start, size, num
    FOR l, num-1, 0, -1
        EQUB HI(start+l*size)
    NEXT
    FOR l, num-1, 0, -1
        EQUB HI(start+(l+num)*size)
    NEXT
ENDMACRO

.TSpGraLo
MkGraVecLo Expl, 4*16, 6      ; 0 to 11 Explosion

MkGraVecLo MyShip, 4*16, 1   ; 12 to 17 My ship(s)
MkGraVecLo MyShip+2*4*16, 4*16, 1
MkGraVecLo MyShip+4*4*16, 4*16, 1

MkGraVecLo Aliens, 4*16, 1    ; 18 to 19 Jelly mon
MkGraVecLo Aliens+2*4*16, 4*16, 1   ; 20 to 21
MkGraVecLo Aliens+4*4*16, 4*16, 1   ; 22 to 23
MkGraVecLo Aliens+6*4*16, 4*16, 1   ; 24 to 25
etc

Not brilliant but not horrendous either. Don't know if you discovered BeebSpriter, but that's a little Windows app I wrote for sprite editing and exporting, the advantage being it can also export a file with symbol definitions for each sprite, BeebAsm style, which can be directly INCLUDEd in your source code.

I'm guessing that the second table built by each macro is the sprite shifted right 2 pixels for smoother movement in MODE 5, amiright?

I discreetly added COPYBLOCK one day when I needed it for my Chuckie Egg source code in BeebAsm (not even sure what happened to that!). Like most of BeebAsm, it just grew from my own wishlist one Christmas break and evolved like that, so it's not really clearly thought out in many ways. The parser in particular is horrible, and the over-reliance on C++ exceptions to handle unexceptional cases. I wrote it very quickly back then, and wouldn't do it the same way now!

User avatar
tricky
Posts: 2768
Joined: Tue Jun 21, 2011 8:25 am
Contact:

Re: Beebasm requests

Post by tricky » Tue Jul 17, 2018 5:18 pm

Kevin Edwards wrote:
Tue Jul 17, 2018 11:46 am
...BTW Really loving beebasm and Visual Studio Code as a dev environment. I use Visual Studio on a day to day basis, and couldn't even think about going back to the BBC Basic editor / environment!

I'd also be interested to know how people are debugging Beeb code using PC emulators / dev environment. I'm currently building an SSD and deploying to B-Em. Is there a nice way of debugging - breakpoints ( PC and data ), single stepping etc...
I use straight VS (nmake project), not got as far as VSCode.
For debugging I export the global labels from the game and then I have hacked beebem to load them.
I have tweaked breakpoints and watches in beebem to use the labels, so you can use the .name or a address which is then converted to a label+/-offset.
The watches and breakpoints are loaded on startup and exported as they are added in the debugger.
When they are reloaded, the new address is calculated using the new value of the label so that they (mostly) don't need to be changed from run to run.
The labels are also displayed in the log window as you step through the code, making it easier to know where you are.

To run, I have "Debug" launch beebem and "Release" b-em, both with the .ssd.
I'm sure there are better ways to do these things, as my methods have just grown as I have done more beeb development.

If you are happy with your build system, or don't wish to be horrified, stop here!

For building, I have a .bat called from the command line specified in the nmake text box, no make files.
The .bat is overkill really, but it just keeps getting added to with each game!

Code: Select all

SETLOCAL ENABLEEXTENSIONS
SETLOCAL ENABLEDELAYEDEXPANSION
all my .bat have this

Code: Select all

IF "%~1"=="-v" (
	..\Tools\beebasm.exe -i game.asm %1 %2 %3 %4 %5 %6 %7 %8 %9
	goto :EOF
)
I set rebuild to pa -V as the first argument, so that it just dumps the assembled code to the output window and doesn't do anything else. This is handy as a reference when debugging.

Code: Select all

..\Tools\beebasm.exe -i game.asm -d >labels.txt
if ERRORLEVEL 1 goto :EOF
for /F "tokens=1,* delims=: " %%L IN (labels.txt) DO if "%%L"=="ERROR" (echo.%%L:%%M & EXIT 1)
dump the global labels to labels.txt - I keep meaning to add local labels to this. This is read later by my modified beebem. Stop if error

Code: Select all

call :DUMP gfx/status.equb status_bar.bin
if ERRORLEVEL 1 goto :EOF
assemble gfx/status.equb starting at 0 and write the generated data to status_bar.bin - usually used for gfx. Stop if error.

Code: Select all

..\tools\beebop.exe status_bar.bin
if ERRORLEVEL 1 goto :EOF
compress status_bar.bin, which will be decompressed to display the status bar in Scramble. Stop if error.

Code: Select all

for /F "tokens=1,2,3,4,5" %%P IN ('..\Tools\beebasm.exe -i game.asm') DO set "name=%%P" & set "load=%%Q" & set "end=%%R" & set "exec=%%S" & set "reload=%%T"
if ERRORLEVEL 1 goto :EOF
echo.name=!name! load=!load! end=!end! exec=!exec!
Assemble the game again (only takes a second) to read some variables (using .bat arcane runes) PRINTed by the asm. Dump them to the output. Stop if error.

Code: Select all

for /F "tokens=1,2,4,5,6" %%P IN ('..\tools\beebop.exe Scrambl') DO set "name=%%P" & set "uncom=%%Q" & set "comp=%%R" & set "pad=%%S" & set "equb=%%T"
if ERRORLEVEL 1 goto :EOF
Compress the main game, recording info needed to decompress on load. Stop if error.

Code: Select all

echo.name=!name! uncom=!uncom! comp=!comp! pad=!pad! equb=!equb!
echo.load=!load! >build.asm
echo.exec=!exec! >>build.asm
echo.len=!end!-!load! >>build.asm
echo.uncom=!uncom! >>build.asm
echo.comp=!comp! >>build.asm
echo.pad=!pad! >>build.asm
echo.INCLUDE "make_rom.asm" >>build.asm
..\tools\beebasm.exe -i build.asm -do Scramble.ssd -boot Scrambl
if ERRORLEVEL 1 goto :EOF
Make a loader that can also be a ROM that will disable interrupts etc and decompress the game. Stop if error.

Code: Select all

..\utils\ssd_titler.exe Scramble.ssd "Scramble"
Change the title on the .ssd (this can be done in beebasm now).

Code: Select all

goto :EOF
.bat for END.

Code: Select all

:DUMP
echo.ORG 0 >dump.asm
echo.INCLUDE "%~1" >>dump.asm
echo.SAVE 0, P%% >>dump.asm
..\Tools\beebasm.exe -i dump.asm -o "%~2"
goto :EOF
For other games, I reconvert all the graphics each build, but as they are all tiny, my biggest build (AstroBlaster with all the speech and program compression) takes about 3 seconds.

Kevin Edwards
Posts: 97
Joined: Tue Mar 14, 2006 9:16 pm
Contact:

Re: Beebasm requests

Post by Kevin Edwards » Tue Jul 17, 2018 10:08 pm

Thanks Rich for the code changes. I shall plug them in. I may have a go at implementing the A% to Z% variables, but my time is in short supply at present.

Cheers, tricky for details about your build process. Looks like something i will investigate once i've got the current project in a buildable state - not much more to do now!

I'd prefer to build using the 'full' Visual Studio. VS Code is OK, but a bit basic when it comes to features and plug-in support.

All the best,
Kevin.

Post Reply