Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
RANDOMIZE USR issue
#1
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?
Reply
#2
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?
Reply
#3
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!
Reply
#4
How do you put the Binary code within ZX Basic??
Reply
#5
...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.
Reply
#6
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.
Reply
#7
...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.
Reply
#8
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: glitch.png]
Reply
#9
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).
Reply
#10
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?
Reply
#11
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.
Reply
#12
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:
Reply
#13
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.
Reply
#14
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:
Reply
#15
Quote: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?!
Reply


Forum Jump:


Users browsing this thread: 4 Guest(s)