Page 1 of 2

RANDOMIZE USR issue

PostPosted: Thu Nov 23, 2017 8:16 pm
by LukeBord1
I'm trying to compile a short menu program including a RANDOMIZE USR command which calls an external assembly routine (tested).

Using both the latest ZXB v.1.7.2 and the previous v.1.6.12, the compiled program freezes. Recompiling it without the RANDOMIZE USR command, all goes ok!
Even trying to change the memory addresses, it seems the problem persists between the RANDOMIZE USR instruction and something inside the code...

  Code:
DIM y,a,i AS UBYTE
y=10: a=0: i=1

10 BORDER 0: PAPER 0: INK 0: CLS: POKE 32005,0
   RANDOMIZE USR (address of the external tested routine)

20 PRINT AT y,11; BRIGHT 1; OVER 1; INK i;"          "

   IF a < 10 THEN a=a+1
   ELSE a=0
   END IF

   IF a=10 THEN
   IF i < 7 THEN i=i+1
   ELSE i=1
   END IF: END IF

   IF (INKEY="1" AND y <> 10) THEN GOSUB 70: y=10: POKE 32005,0: END IF
   IF (INKEY="2" AND y <> 11) THEN GOSUB 70: y=11: POKE 32005,1: END IF
   IF INKEY="3" THEN BEEP .04,50: RANDOMIZE USR (game start address): GO TO 10: END IF
   GO TO 20

70 PRINT AT y,11; BRIGHT 0; OVER 1; INK 7;"          ": BEEP .04,50: RETURN


Thoughts?

Re: RANDOMIZE USR issue

PostPosted: Fri Nov 24, 2017 10:42 am
by boriel
What is the address of the USR routine? It seems it might be overlapping with something else.
How are you loading / inserting the binary code among with ZXB?

Re: RANDOMIZE USR issue

PostPosted: Fri Nov 24, 2017 6:09 pm
by LukeBord1
The program is an intro menu for an Arcade Game Designer game.
The first USR calls a compressed screen, which is correctly rendered.
The printed spaces work too, changing the colour through the a/i variables loop.
The INKEY is freezed: no way to choose an option by pressing any key!

Re: RANDOMIZE USR issue

PostPosted: Fri Nov 24, 2017 7:46 pm
by boriel
How do you put the Binary code within ZX Basic??

Re: RANDOMIZE USR issue

PostPosted: Sat Nov 25, 2017 8:23 am
by LukeBord1
...well i dont' include any binary into the ZXB code. I just have a relocatable bin file for the compressed screen, and the compiled menu including the RANDOMIZE USR call.

I use to assemble the bin parts (game, relocatable sounds, compressed screens etc) in a final TAP file and all should go.

Re: RANDOMIZE USR issue

PostPosted: Sat Nov 25, 2017 9:23 am
by boriel
Yes, but how do you load the relocatable binary code to be called then from ZX Basic??
Do you use LOAD "" CODE? or something?
If so, you have first to reserve memory space and then allocate the memory there.

Re: RANDOMIZE USR issue

PostPosted: Sat Nov 25, 2017 12:58 pm
by LukeBord1
...for test purposes, i just drag the bin files into Spectaculator. Even giving a CLEAR memory command, the problem persists.
All seems working except for the INKEY instructions, which work when the RANDOMIZE USR misses.

Re: RANDOMIZE USR issue

PostPosted: Sat Nov 25, 2017 3:34 pm
by LukeBord1
Just found a workaround!

  Code:
... RANDOMIZE USR (compressed screen address): GO TO 20 ...


Weird, isn't it?!... By adding a "GO TO (main loop)" after the RANDOMIZE USR, it doesn't freeze anymore the INKEY command!
A final note - while running, a graphic glitch appears on a line at the top middle part of the screen:

Image

Re: RANDOMIZE USR issue

PostPosted: Mon Nov 27, 2017 9:08 am
by boriel
I'm still not sure what you are doing. This seems not related to ZX Basic compiler, but to Sinclair BASIC :?:
Sorry, I can't help you there.

ZX Basic is a compiler that translates a BASIC program into machine code. You will end up with a .TAP file to load into an emulator.
CLEAR does nothing. Actually you should not use it, because your compiled program will be placed just after the CLEAR address and invoked with a RANDOMIZE USR, as any other machine code routine (like your screen routine).

Re: RANDOMIZE USR issue

PostPosted: Tue Nov 28, 2017 5:53 pm
by boriel
LukeBord1 wrote:...well i dont' include any binary into the ZXB code. I just have a relocatable bin file for the compressed screen, and the compiled menu including the RANDOMIZE USR call.
I use to assemble the bin parts (game, relocatable sounds, compressed screens etc) in a final TAP file and all should go.

Still don't understand how do you do the last part: "Assemble the bin parts in a final tap". What exactly are you doing here?

Re: RANDOMIZE USR issue

PostPosted: Sun Dec 03, 2017 11:04 pm
by LukeBord1
Well let's try to make my attempt as simple as possible...

- I need to inlcude various ASM calls inside an Arcade Game Designer project;

- these ASM calls evoke different machine code routines, so first of all I make the different bin parts located in a specific memory location (e.g. sound fx or compressed screens), then the various files are assembled in an unique TAP file, in order to have: a loader, the game machine code generated by AGD and the machine code which collects the various routines;

- one of these routines should be a starting MENU, programmed in ZX Basic (just like the code in the above post), then compiled as a binary file to be included in the final TAP project;

- both trying to launch the compiled menu as a full project including the other routines, and as a stand-alone file, there's a problem with the INKEY command: there's a loop which blinks the colour of the text, and this part works; however, the INKEY command seems to freeze when using a RANDOMIZE USR command in the top part of the ZX Basic program: if the RANDOMIZE USR is removed, the INKEY works! That's the bug i'm trying to explain.

Re: RANDOMIZE USR issue

PostPosted: Mon Dec 04, 2017 10:00 am
by boriel
Okay, let's start with the simplest case: A single ZXBasic menu + single ASM routine.
You still don't tell how you integrate that routine into. But here is how you can do that:

  1. Include the ASM directly with:
      Code:
    DIM y,a,i AS UBYTE
    y=10: a=0: i=1

    10 BORDER 0: PAPER 0: INK 0: CLS: POKE 32005,0
       RANDOMIZE USR @asmstart : REM <------------- SEE the new @address!!

    [... rest of the MENU code]

    30 END: REM Needed to avoid the CPU entering the next area

    asmstart:  REM a label to mark the beginning of the next area
    REM now open an ASM context
    ASM
    #include "asmsource.asm"
    END ASM
  2. If your code is already assembled into a binary **RELOCATABLE** file, you can include the binary file directly:
      Code:
    DIM y,a,i AS UBYTE
    y=10: a=0: i=1

    10 BORDER 0: PAPER 0: INK 0: CLS: POKE 32005,0
       RANDOMIZE USR @asmstart : REM <------------- SEE the new @address!!

    [... rest of the MENU code]

    30 END: REM Needed to avoid the CPU entering the next area

    asmstart:  REM a label to mark the beginning of the next area
    REM now open an ASM context
    ASM
    #incbin "asmbinary.bin"
    END ASM

Notice the .bin at the end.

Other solutions are using LOAD "" CODE from *within* compiled ZX Basic (not from Sinclair BASIC): ZX Basic supports LOAD "" CODE.
Bear in mind that using LOAD "" CODE (either from ZX Basic or directly from Sinclair BASIC) won't mostly work (or have an erratic behaviour, like your example), unless you know very very well what's happening behind the scenes. Using CLEAR does not help. ZX Basic programs are also machine code, and must be above the CLEAR address. If you LOAD your own binaries after a ZX Basic program it's mostly likely you'll overwrite some memory area (i.e. Variables' space or The heap or even the ZX Basic program it self).

You can convert a ZX Basic program to assembler using --asm and see the generated code.
If you want further help, please send me a private msg with a .zip archive so I can examine it. :wink:

Re: RANDOMIZE USR issue

PostPosted: Mon Dec 04, 2017 10:55 pm
by LukeBord1
Awesome!!! The key was the *** END *** command!
So I've learned this important step: if a project includes various external ASM routines, then a ZX Basic program needs to be "terminated" in order to avoid a collision with those routines.

In my case (it's just a personal choice), I manage the other ASM routines outside ZX Basic, importing the various .bin files inside the emulator memory and then exporting an unique TAP file to be loaded as a final machine code block, after the main game block. Without the END, the assembled ZX Basic continues the run, leading to a crash with the following ASM.

Thanks Boriel, I always knew the solution should be simple; maybe some commands like the END one deserve a specific explanation in the ZX Basic identifiers page.

Re: RANDOMIZE USR issue

PostPosted: Tue Dec 05, 2017 11:07 am
by boriel
The END issue has been discussed in this forum already. The way you use the binaries (loading binaries from within an emulator?) is not related to ZX Basic. ZX Basic already provide same mechanisms to do that (explained before) :roll:
If you load them into an emulator as you said, I recommend you to first compile with --heap=1024 (for example) and see where ZX Basic heap ends (the heap is used as a temporary working memory for STRING variables and string related operations for example). Then load the binaries beyond that memory address or you'll be mostly like overwriting something.

Usually, if you don't reserve some memory to load binaries in advance, your program might randomly fail (despite it's apparently working for a while).
Also, ZX Basic already adds hidden END automatically at the end of your listing (it's called [i]code epilogue[/]).

I insist one last time: The safe way is to use INCBIN "filename.bin" within an ASM context.
Anyway, glad to hear it worked for you. :wink:

Re: RANDOMIZE USR issue

PostPosted: Fri Dec 08, 2017 10:24 am
by LukeBord1
The safe way is to use INCBIN "filename.bin" within an ASM context

Ok! It's the first ZXB menu I'm going to include in an AGD game (and probably the first attempt ever). Just a thought... so I cannot include a not-relocatable file.
An AGD project isn't relocatable; the AGD saved block starts always below 32000 but it needs to be called exactly at 32000 to run. So I'll have something like...
  Code:
...
RANDOMIZE USR @agd_block
...
agd_block:
ASM
#incbin "31018,26806_game.bin"
END ASM

...and two problems rise: how can I tell ZXB to start the bin from 32000, and can it work if it isn't relocatable?!