Forum
Calling non-ZXB code with RANDOMIZE USR - Printable Version

+- Forum (https://www.boriel.com/forum)
+-- Forum: Compilers and Computer Languages (https://www.boriel.com/forum/forumdisplay.php?fid=12)
+--- Forum: ZX Basic Compiler (https://www.boriel.com/forum/forumdisplay.php?fid=11)
+---- Forum: Help & Support (https://www.boriel.com/forum/forumdisplay.php?fid=16)
+---- Thread: Calling non-ZXB code with RANDOMIZE USR (/showthread.php?tid=352)



Calling non-ZXB code with RANDOMIZE USR - LTee - 05-13-2011

Hi all, it's been a while but I've been kind of busy. :-)

My game project is almost complete, I just wanted to add some music. I wrote a couple of (quite bad) tunes with Beepola, compiled with the Music Box engine. I've loaded these high into memory (64000 up), well away from my ZXB code and I'm calling them with 'randomize usr X' from within ZXB. The player is configured to play the tune once and then return control to the caller.

I'm having a small problem that I can get around, but I wanted to ask about. If I call the music player from within a SUB or a FUNCTION, the Spectrum crashes after playing the tune. If I call it from OUTSIDE a SUB or FUNCTION (i.e. just from within the main code) then it returns fine.

For example:
Code:
cls
pause 0
print "test"
randomize usr 64000
pause 0
print "test 2"
test()
stop

SUB test()
    randomize usr 64000
END SUB

In the above code (surmising that the player is loaded at 64000), the tune plays and returns correctly after "test" is printed, but crashes after playing the tune after "test2" is printed.

Is calling external code via "randomize usr" actually supported? It's not in the Wiki, so I'm thinking 'not'. If it is supported, is there something else I should be doing before making such a call? Or is there a better way of doing this?

My main concern is that the call which appears to be working is actually doing something bad that I'm just not seeing immediately and might cause unexpected problems later.

Thanks for any insights! :-)


Re: Calling non-ZXB code with RANDOMIZE USR - LTee - 05-13-2011

Incidentally, using a GO SUB also works okay:

e.g.
Code:
10 go sub 5000
20 stop
5000 randomize usr 64000
5010 return
... seems fine.


Re: Calling non-ZXB code with RANDOMIZE USR - boriel - 05-25-2011

Hi, Ltee

I was to New York (Holidays 8) ) and arrived last sunday.
GOSUB works *incidentally* Confusedhock: so, while the stack is preserved, etc. it should go ok.

RANDOMIZE USR should also work (it was implemented with that purpose in mind: allow external machine code to be called as we did with Sinclair BASIC). This need to be examined carefully... I'll have a look.


Re: Calling non-ZXB code with RANDOMIZE USR - LCD - 05-25-2011

boriel Wrote:Hi, Ltee

I was to New York (Holidays 8) ) and arrived last sunday.
Welcome back in the civilised world Wink. We hope, you regained power and strength.


Re: Calling non-ZXB code with RANDOMIZE USR - boriel - 05-25-2011

LCD Wrote:
boriel Wrote:Hi, Ltee

I was to New York (Holidays 8) ) and arrived last sunday.
Welcome back in the civilised world Wink. We hope, you regained power and strength.
Well, a bit jet-lagged indeed... 8) also have lot of work piled up so little time for the compiler at the moment, but still here Tongue
Will check this ASAP. My 1st priority is to make the FOR static as we previously discussed. Release it as 1.3.8 and start a new development cycle.


Re: Calling non-ZXB code with RANDOMIZE USR - LTee - 05-26-2011

Thanks for the reply, boriel - hope you had a good holiday! :-)

I'll put together a few test programs that demonstrate this in case you need to see it in action.


Re: Calling non-ZXB code with RANDOMIZE USR - LTee - 07-21-2011

Hi Boriel!

Sorry for vanishing for a while there, life got... complicated. :-(

Anyway, did you have any further thoughts on this problem? I've tried the new build (1.2.8-706) and I'm still getting the same issue. I've attached a file to this post called MusicTest.zip which contains an example of this in action. Load 'musictest-full.tap' to try it out, 'maketest.bat' will build it, 'musictest.bas' is the source.

Code:
cls
print "press any key"
pause 0
print "test 1"
randomize usr 64000
print "success"
pause 0
print "test 2"
go sub 9000
print "success"
pause 0
print "test 3"
test()
print "success"
print "done"

stop

SUB test()
    randomize usr 64000
END SUB

9000 RANDOMIZE USR 64000
9010 RETURN

There is a Music Box jingle (created with Beepola) loaded into memory at 64000 which is set up to play once then return control to the calling program. The test code calls this three times - from outside a sub/function, as part of a GO SUB and as a sub call. The sub call will fail (the music player does not return properly once the tune has finished and crashes the Spectrum) even though the others succeed.

Any ideas greatly appreciated! Smile


Re: Calling non-ZXB code with RANDOMIZE USR - boriel - 07-21-2011

The problem is your routine at 64000 corrupts the IX register. If you're using BEEP rom routine, remember that routine corrupts IX register, and that you must push/pop it to preserve it's value, since IX is used to manage the stack frame in a function scope.

If you call USR 64000 *outside* a function (test 1 & 2) then IX value does not need to be preserved. But if you call it from within a function body, then yes, you must preserve IX register.


Re: Calling non-ZXB code with RANDOMIZE USR - LTee - 07-22-2011

I see. So I'd need to alter the routine to push IX before it begins and pop it again as it ends. I surmise I'd have to do that within the music routine itself and couldn't somehow do it using an ASM block within the BASIC?

I might go back to trying to get the assembly versions of the Beepola output to work, tweaking the binary output is going to be overly complicated by the looks of it. Or I might just write some tunes using normal BEEP commands. :-D

Thanks for explaining that, boriel!


Re: Calling non-ZXB code with RANDOMIZE USR - LTee - 07-22-2011

Oh.... or maybe it is that easy? Is this alteration to the original source valid? It seems to work:

Code:
SUB test()
    asm
        push ix
    end asm
    randomize usr 64000
    asm
        pop ix
    end asm
END SUB

Edit: Or, indeed, this one (which seems a bit neater):

Code:
SUB test()
    asm
        push ix
        call 64000
        pop ix
    end asm
END SUB



Re: Calling non-ZXB code with RANDOMIZE USR - boriel - 07-22-2011

Both will work! Smile


Re: Calling non-ZXB code with RANDOMIZE USR - LTee - 07-22-2011

Fantastic, that's sorted out my final "blocking" issue, then! Many, many thanks, boriel! 8)


Re: Calling non-ZXB code with RANDOMIZE USR - boriel - 07-22-2011

Please post a tutorial on how to integrate beepola! Tongue (I would like to learn it!) If you finally do, put it in the HowTo folder, and I will stick it! Smile


Re: Calling non-ZXB code with RANDOMIZE USR - LTee - 07-22-2011

Will do. It's actually pretty easy aside from those one or two fiddly bits.