Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Calling non-ZXB code with RANDOMIZE USR
#1
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! :-)
Reply
#2
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.
Reply
#3
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.
Reply
#4
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.
------------------------------------------------------------
http://lcd-one.da.ru redirector is dead
Visit my http://members.inode.at/838331/index.html home page!
Reply
#5
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.
Reply
#6
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.
Reply
#7
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


Attached Files
.zip   MusicTest.zip (Size: 5.88 KB / Downloads: 316)
Reply
#8
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.
Reply
#9
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!
Reply
#10
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
Reply
#11
Both will work! Smile
Reply
#12
Fantastic, that's sorted out my final "blocking" issue, then! Many, many thanks, boriel! 8)
Reply
#13
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
Reply
#14
Will do. It's actually pretty easy aside from those one or two fiddly bits.
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)