CPCWiki forum

General Category => Programming => Topic started by: Fran123 on 09:55, 16 September 23

Title: injecing basic program in memory
Post by: Fran123 on 09:55, 16 September 23
Hello,

I want to write a basic program in memory from assembler at position &170. So when I exit the assembler program I have a basic program loaded and I can run it.
When I run it with RUN, the program fails, it is as if the first line is missing or wrong.

Do you know how to do that?

Thank you.
Title: Re: injecing basic program in memory
Post by: lightforce6128 on 20:26, 16 September 23
Maybe the operating system uses some internal state to organize basic code? Did you only write the (compreted) BASIC program to address &170 or did you also update something else?

The error messages given by the OS or BASIC are not quite meaningful. But what did it write?

If you list your created program, what do you see?
Title: Re: injecing basic program in memory
Post by: Fran123 on 11:13, 17 September 23
I wrote a basic program and saved it the memory from &170 to last three zeros with winape.
Title: Re: injecing basic program in memory
Post by: lightforce6128 on 01:28, 18 September 23
In the book "ROM-Listing CPC 464/664/6128" (can also be found in the Wiki (https://www.cpcwiki.eu/index.php/ROM-Listing_CPC_464/664/6128); for reading I suggest to download the PDF file) I found something on page 137, section 4.1.3. It tells that there is a management data structure for BASIC lines. For example, &AE81 (&AE64 for 664/6128) contains the 16-bit start address of the BASIC program, followed by the 16-bit end address. Just placing the BASIC line in memory is not enough, also this data structure needs to be updated.

In the same book, on page 517, I found a system routine at address &E6D2 in the upper ROM that needs the line number in DE and the program line as string pointed to by HL and inserts this in the BASIC program. Because this is a routine in a ROM it cannot simply be called, but the ROM configuration needs to be updated first. For this, restart 2 should be the right one (see page 81, section 3.1.6).

But I never used this approach and cannot tell if this is the right or best way to build up a BASIC program.
Title: Re: injecing basic program in memory
Post by: norecess464 on 02:12, 18 September 23
@arnoldemu provides the best source codes available online. It's always clear and concise, direct to the point, covering an impressive number of topics. I learnt a lot from those examples.

The example called "Running BASIC programs from assembly" might interest you.

http://www.cpctech.cpc-live.com/source.html
Title: Re: injecing basic program in memory
Post by: eto on 09:02, 18 September 23
Quote from: norecess464 on 02:12, 18 September 23It's always clear and concise
While I love the examples, I don't get this particular one.

Does it expect the BASIC program already to be loaded to 170? (I guess so)
Why does it copy parts of itself to &a000? (meant to be run from ROM?)
What do the symbols start_rom, old_addr and length refer to? They are not defined in the source.


Title: Re: injecing basic program in memory
Post by: lightforce6128 on 23:58, 20 September 23
A small, almost working example:

In BASIC, block the memory for the small assembler program:
MEMORY &7FFF
Then assemble this small program (I used WinAPE for this. But as well you can load the program from disk):
NOLIST
ORG &8000

;; Set parameters.
LD DE, 10 ;; line number
LD HL, sourceCode

;; Call routine in upper (BASIC) ROM.
;; Select the right address depending on the machine type!
;; Do not forget to clear the upper two bits!
RST 2 : DEFW &E7A5 AND &3FFF ;; 464:E6D2 / 664:E7AA / 6128:E7A5

RET

sourceCode:
    DEFB 'PRINT "Hello!"', 0

Now you can call the assembler program from BASIC:
CALL &8000
It will output a "Syntax error", currently I don not know, why. But it will create the one-line BASIC program. You can list and run it:
LIST
RUN
Title: Re: injecing basic program in memory
Post by: Bread80 on 22:54, 25 September 23
Quote from: lightforce6128 on 23:58, 20 September 23NOLIST
ORG &8000

;; Set parameters.
LD DE, 10 ;; line number
LD HL, sourceCode

;; Call routine in upper (BASIC) ROM.
;; Select the right address depending on the machine type!
;; Do not forget to clear the upper two bits!
RST 2 : DEFW &E7A5 AND &3FFF ;; 464:E6D2 / 664:E7AA / 6128:E7A5

RET

sourceCode:
    DEFB 'PRINT "Hello!"', 0


If you want to tokenise and execute a line call &c0cd (6128).
To insert a line into the program add the line number into the string and call &c0b7 (6128).

The latter will either execute or insert/replace depending on whether there is a line number in the buffer or not.
Title: Re: injecing basic program in memory
Post by: Bread80 on 22:58, 25 September 23
Quick follow up.
To do what you're doing - line number in DE, call &c0c2.
Powered by SMFPacks Menu Editor Mod