Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Best way to put UDG in my program ?
#1
Hi

I'm trying to write a kind of space shooter from scratch, i kind of wrote it in Sinclair BASIC first and in there I use UDGs
in the usual way by POKEing the usual UDG area at 65368. How do I do this in Boriel ZX ? It didn't like me doing it manually
causing random crashes and giving me "Out of Memory" when I tried to use inline ASM call. Thanks Smile
Reply
#2
To do this, there are several ways. ZX Basic does not support READ / DATA / RESTORE yet.
The traditional way is to POKE USR "a" + n, byte for UDG "a" and so on. To do this, you should compile with --sinclair parameter (which will make ZX Basic as much compatible as possible with original Sinclair BASIC.

Try this:
Code:
FOR i = 0 TO 7
    POKE USR "a" + i, BIN 01010101
    PRINT "\a": REM you can use "\x" for UDG x
NEXT i

Compile the above with:
Code:
zxb --sinclair -taB udg.bas
This should work as expected.

Another (more advanced) way is to store all the UDG data in an array and then do POKE UInteger 23672 with the address of the array data.
This is done in this example:
<!-- m --><a class="postlink" href="http://www.boriel.com/wiki/en/index.php/ZX_BASIC:Snake.Bas">http://www.boriel.com/wiki/en/index.php ... :Snake.Bas</a><!-- m -->

You don't need to use --sinclair in this 2nd case.
Hope this clarifies how to use UDGs in ZX Basic
Reply
#3
Hi Boriel, thanks for the help first of all. It's very strange what's going on. This is what I originally had in my program. For the UDGs
I put this in at the start of my BASIC listing
Code:
ASM

LD HL, 65368
LD DE, DATA
LD B,56      <-- I have 7 characters
LOOP:
LD A,(DATA)
LD (HL),A
INC HL
INC DE
DEC B
JR NZ,LOOP
DATA:
DEFB udg 1
DEFB udg 2
etcc...

END ASM
This causes the Speccy show me a black screen when I run it or It crashes, If I change the B to 32 and only have 4 udgs everything is fine! I tried the example you mention from SNAKE.BAS and something else strange happens. Line goes like this for
7 udg chars
DIM udg(6,7) AS UINTEGER =>{{UDG1},{UDG2},...{UDG7}}
POKE UINTEGER 23675,@udg(0,0)
when I tried this in my program all the graphics looked weird as if every second row was drawn but the program didn't crash.
What do you guys use for debugging btw? I just tend to delete lines till works again or do lots of PRINT statements Big Grin
Reply
#4
Well I tried the method you mentioned using --sinclair so I've done this instead and seems to work well so thank you Smile

SUB startUDG()
DIM d(7,8) AS UINTEGER =>{{UDG1},{UDG2},...{UDG7}}
DIM b AS UINTEGER
FOR i=0 to 55
LET b=d(1,i)
POKE USR "a"+i,b
NEXT i
END SUB
Reply
#5
It does work even without the --sinclair compile option, but you have to change the indexes in the array around. The old does the
array index start from 1 or 0 Smile
Reply
#6
ivanb303 Wrote:It does work even without the --sinclair compile option, but you have to change the indexes in the array around. The old does the
array index start from 1 or 0 Smile
Yes. In "modern" Basic (see FreeBASIC) arrays starts from 0 like in C. This is slightly faster and simplifies some programs.
You can explicitly tell the compiler to start from 1. For example an array from 1 TO 8 will be:
Code:
DIM myArray(1 TO 8)
If you omit the "1 TO", it will use "0 TO" as default. If you're copying a Sinclair BASIC listing, it's better to use --sinclair.
If you're starting from scratch, the modern BASIC dialect is recommended. ZX Basic tries to follow Visual Basic / FreeBasic dialects as much as possible.
Reply
#7
ivanb303 Wrote:
Code:
ASM

LD HL, 65368
LD DE, DATA
LD B,56      <-- I have 7 characters
LOOP:
LD A,(DATA)
LD (HL),A
INC HL
INC DE
DEC B
JR NZ,LOOP
DATA:
DEFB udg 1      ; <--- LOOK OUT
DEFB udg 2
etcc...

END ASM
That code is ok... except that once the loop is finished de CPU will run into your DEFB udg 1 and will execute those bytes as if they were assembler instructions.
You should jump somewhere else, RETurn or something.
Reply
#8
Yes that makes sense but I don't where it should jump or RETurn. It would have to be after the JR NZ. I would want it to then continue the ZX listing past the END ASM. Can you jump to labels outside the ASM from inside the ASM section ?
Reply
#9
ivanb303 Wrote:Yes that makes sense but I don't where it should jump or RETurn. It would have to be after the JR NZ. I would want it to then continue the ZX listing past the END ASM. Can you jump to labels outside the ASM from inside the ASM section ?

I'm a bit lost as to where you'd put a RET because in the other thread where you told me not to put a RET in my ASM section cause you have to let the Boriel compiler return by itself. I guess I could add a jump to just past the DEFB ?
Reply
#10
I think it's time to refer peeps to my unfinished tutorial - this covers use of UDG. (And multiple banks of UDG)

<!-- m --><a class="postlink" href="https://docs.google.com/document/d/1vUneCCC18oXLglzoRcJdrMDUSh7vaO_tGDjzjOc8IhU">https://docs.google.com/document/d/1vUn ... DjzjOc8IhU</a><!-- m -->
Reply
#11
ivanb303 Wrote:
ivanb303 Wrote:Yes that makes sense but I don't where it should jump or RETurn. It would have to be after the JR NZ. I would want it to then continue the ZX listing past the END ASM. Can you jump to labels outside the ASM from inside the ASM section ?

I'm a bit lost as to where you'd put a RET because in the other thread where you told me not to put a RET in my ASM section cause you have to let the Boriel compiler return by itself. I guess I could add a jump to just past the DEFB ?

Maybe you can - you could put a :labelname at the end and use jp labelname before the defb statements. Assuming you didn't mess up the contents of registers the compiler would assume are there, mind. This is why adding in code can be tricky.

I suspect something like this shouldn't be in the main code path, and should be a called subroutine of its own, probably.
Reply
#12
ivanb303 Wrote:
ivanb303 Wrote:Yes that makes sense but I don't where it should jump or RETurn. It would have to be after the JR NZ. I would want it to then continue the ZX listing past the END ASM. Can you jump to labels outside the ASM from inside the ASM section ?

I'm a bit lost as to where you'd put a RET because in the other thread where you told me not to put a RET in my ASM section cause you have to let the Boriel compiler return by itself. I guess I could add a jump to just past the DEFB ?
True, a Jump in this case, but most of the time you want to put this code in a SUBroutine.
Also have a look to Britlion's tutorial! It starts almost from scratch and goes up to a very high / expert level. :roll: 8)
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)