Changing behaviour of BLOAD

By cax

Prophet (3736)

cax's picture

16-07-2005, 07:41

I have a question to MSX gurus:

how would you hook the BLOAD operator so it will do something else instead of the default operation ?

I tried to patch each BLOAD statement with CMD and define CMD operator, but I also failed to do it correctly - when I return from CMD I always get "Illegal function call". Also I cannot be sure I am patching the BLOAD operator code or something else (and by doing this I am breaking the BASIC program).

Please help me to find a working solution.

Login or register to post comments

By BiFi

Enlighted (4348)

BiFi's picture

16-07-2005, 09:07

the minimum CMD handler looks like this:

CALL H.CMD     ; FE0D
JP   ERROR5    ; 475A = Illegal function call

solution: remove the return address to the error generation from the stack before you return.

What command would you like to make?

By cax

Prophet (3736)

cax's picture

16-07-2005, 09:33

BiFi: 10x for suggestion, but how can I find all BLOADs in the tokenized BASIC program ?
Just patching all 0xCF (BLOAD) bytes with 0xD7 (CMD) won't work, because not every 0xCF in a program is a BLOAD.

By BiFi

Enlighted (4348)

BiFi's picture

16-07-2005, 09:58

I had 2 lucky things with that _MUS2AUD on the fly patcher:

  1. the text to patch was in ASCII
  2. the text had the same length

If either of those things were different I couldn't have made that patch tool.

What you want it to add change BLOAD into CMD BLOAD (or is it BLOAD into just CMD?)

I used the H.GONE (FF43) hook for that. Register A contains the token in process, and HL points to that token in the BASIC text. You can only do this on the fly if you want to change BLOAD into CMD. Changing BLOAD into CMD BLOAD requires manual changing... or one free byte within close reach...

If the token in process is the BLOAD token you can change that into CMD before you actually execute it.

By cax

Prophet (3736)

cax's picture

16-07-2005, 10:10

The purpose of all this is not to replace BLOAD with CMD at any price, but just to execute custom code instead of BLOADing. Let's say I use H.GONE hook and check whether A equals to 0xCF (BLOAD), then I execute my code; but how to skip the BLOAD itself ? Can I replace (HL) with code of REM or there exists another way to skip ?

By BiFi

Enlighted (4348)

BiFi's picture

16-07-2005, 10:14

You can do a CHRGTR (address 4666h) call yourself. Replacing BLOAD with REM isn't adviseable since the REM will make everything after it remark.

But you can, of course, change the H.BINL (FE76) hook which is executed when a BLOAD is done.

By cax

Prophet (3736)

cax's picture

16-07-2005, 15:20

Hook H.GONE works OK, but skipping BLOAD is still not easy.
I am trying to do this by calling CHRGTR until A=0 (end of statement) and then if it's ":" I just call CHRGTR one more time,
but if the end of statement is the end of line, how can I recognize the place where the 1st operator of the next line starts ?

By ARTRAG

Enlighted (6565)

ARTRAG's picture

16-07-2005, 15:27

try to pop the ret address from the stack
this should terminate the bload statement when
you end your hook routine

By BiFi

Enlighted (4348)

BiFi's picture

16-07-2005, 16:24

ARTRAG: I already posted that and Cax wasn't referring to that.

Cax: You need to have the BASIC interpreter evaluate the parameters. You need to check for a ',' yourself.

A few BASIC interpreter addresses which might be interresting to use. These seem to be the same in all ROMs and the names are unofficial:

BASERR  406F
ERROR2  409B
CHRGTR  4666  In : HL = BASIC pointer
              Out: A  = token or character read
                   HL = updated BASIC pointer
ERROR5  475A
FRMEVL  4C64  In : HL = BASIC pointer
              Out: DAC, VALTYP
                   HL = updated BASIC pointer
BYTEVL  521C  In : HL = BASIC pointer
              Out: A  = evaluated value
                   HL = updated BASIC pointer
WRDEVL  542F  In : HL = BASIC pointer
              Out: DE = evaluated value
                   HL = updated BASIC pointer
BASRUN  73AC

By cax

Prophet (3736)

cax's picture

16-07-2005, 16:33

Popping ret address in the end of H.GONE handler didn't work.

And I don't need to evaluate the parameters of BLOAD - I just want to skip it all, so BASIC will continue from the next statement, being it on the same line after ":" or on the beginning of the next line.

And thanks for pointing out the fact BASRUN is the same in all ROMs - I am using it to run the program.

By BiFi

Enlighted (4348)

BiFi's picture

16-07-2005, 16:56

The safest way to skip it is to evaluate it and don't do anything with it.

and removing the return address from the stack was for the CMD handler.

and BASERR has E for input... which contains the error code.