CPCWiki forum

General Category => Programming => Topic started by: duncan_bayne on 05:45, 31 January 13

Title: Calling a BASIC subroutine from assembler?
Post by: duncan_bayne on 05:45, 31 January 13
Hi All,

I've a very naive question: from an assembly language program, is it possible to invoke the BASIC ROM in such a way as to call a subroutine (essentially a GOSUB)?

I'm working on a game idea that has a user-programmable element.  It'd be nice to allow the user to write a subroutine in BASIC, and then call it from within my game.

I guess I know that it must be possible - after all, somewhere in the BASIC ROM there will be code that does this and can be called externally.  I'm hoping someone else will have tried it before, or even have a pointer to the relevant documentation or source code?

Yours,
Duncan
Title: Re: Calling a BASIC subroutine from assembler?
Post by: duncan_bayne on 05:56, 31 January 13
Having a look around http://cpcrulez.fr/firmware.txt (http://cpcrulez.fr/firmware.txt) it seems possible ... maybe with just a bit of hackery (fiddling with the BASIC stack etc.).  Fun project for the train ride home ...
Title: Re: Calling a BASIC subroutine from assembler?
Post by: duncan_bayne on 07:24, 31 January 13
This looks like it might be helpful ...

http://cpctech.cpc-live.com/docs/basic.asm (http://cpctech.cpc-live.com/docs/basic.asm)
Title: Re: Calling a BASIC subroutine from assembler?
Post by: AMSDOS on 09:46, 31 January 13
Unsure if that can be done. You can make it appear that the assembly has a connection with BASIC by setting up a variable in BASIC and assigning an Address to it and then you can just have you're assembly return values to that address, which can then be used in BASIC.


Space Storm 2 (or Meteor Storm II) is a nice example The bulk of the game is in Assembly, though that 10 Liner Shows that David Hall has setup a Variable 'd' and is assigning it to memory address '20000'. When the game finishes one way or another the relevant value is returned to that address and from there he does an SPEED INK switch depending on if you have died or completed the game along with a Message (from the text arrays) - if '1' is return the game is completed, otherwise '2' is returned if you have failed.
Title: Re: Calling a BASIC subroutine from assembler?
Post by: arnoldemu on 18:57, 31 January 13
Quote from: duncan_bayne on 05:45, 31 January 13
Hi All,

I've a very naive question: from an assembly language program, is it possible to invoke the BASIC ROM in such a way as to call a subroutine (essentially a GOSUB)?

I'm working on a game idea that has a user-programmable element.  It'd be nice to allow the user to write a subroutine in BASIC, and then call it from within my game.

I guess I know that it must be possible - after all, somewhere in the BASIC ROM there will be code that does this and can be called externally.  I'm hoping someone else will have tried it before, or even have a pointer to the relevant documentation or source code?

Yours,
Duncan
it will be hard to do if you call into the rom.

first problem is that there are different revisions of basic, so the rom structure has changed.
second problem is that you'll need to hack some variables to make basic happy.
and third problem is calling direct into the basic rom to get what you want.

there are some alternatives.

basic calls your program at the beginning. when you want to jump to a subroutine, you can do something like this:
Func is a var that you setup before you "exit" back to basic with a simple "return".
you'll need to remember IX into your code so you can access FUNC and poke it back when you return.


10 FUNC = 0
20 call yourcode, @FUNC
30 gosub FUNC
40 goto 10


this should work with all basics, but you'll need to be nice to basic (don't overwrite it's areas, use HIMEM to avoid it breaking your code).

how it's normally done:

script code is compiled down to byte codes, the data is embedded within your program. it is executed by an interpreter which you implement. you tell the interpreter of some functions and variables you are happy it can mess with.

one example like this is lua.

it may be possible to compile java down to byte codes and execute that, providing some fixed native functions that your code supports.

if you do implement your own script, you'll need to implement a compiler and interpreter effectively.
Title: Re: Calling a BASIC subroutine from assembler?
Post by: Bryce on 20:57, 31 January 13
Why don't you make a defined set of AI reactions. Then the basic "SDK" could compile machine code depending on the choice of available AI reactions and this could be poked in wherever you need it.

Bryce.
Title: Re: Calling a BASIC subroutine from assembler?
Post by: duncan_bayne on 22:29, 31 January 13
Quote from: arnoldemu on 18:57, 31 January 13
it will be hard to do if you call into the rom.

first problem is that there are different revisions of basic, so the rom structure has changed.
second problem is that you'll need to hack some variables to make basic happy.
and third problem is calling direct into the basic rom to get what you want.

Yeah, not easy ... but my idea (a game where people write AIs to compete against each other in an artificial ecosystem) absolutely requires providing users with a language in which to write their AIs.

I could probably squeeze a simple Forth implementation into 16K along with the game, but I'd much rather not ... I think I'll be lucky to get the game itself to fit.

It makes me appreciate modern development environments even more ... this'd be easy in Common Lisp, Scheme, Ruby, or Javascript.  But then that's part of the charm of retro computing, being creative in such a resource constrained environment! :)
Title: Re: Calling a BASIC subroutine from assembler?
Post by: cpcitor on 10:48, 01 February 13
Quote from: duncan_bayne on 05:56, 31 January 13
Having a look around http://cpcrulez.fr/firmware.txt (http://cpcrulez.fr/firmware.txt) it seems possible ... maybe with just a bit of hackery (fiddling with the BASIC stack etc.).  Fun project for the train ride home ...

Quote from: duncan_bayne on 07:24, 31 January 13
This looks like it might be helpful ...

http://cpctech.cpc-live.com/docs/basic.asm (http://cpctech.cpc-live.com/docs/basic.asm)

Thanks for these references. I put links on the wiki :
Where to learn? - CPCWiki (http://www.cpcwiki.eu/index.php/Where_to_learn%3F#CPC_memory_layout_and_usage)
Locomotive BASIC - CPCWiki (http://www.cpcwiki.eu/index.php/Locomotive_BASIC#Web_links)
Powered by SMFPacks Menu Editor Mod