Welcome, Guest
You have to register before you can post on our site.



Search Forums

(Advanced Search)

Forum Statistics
» Members: 255
» Latest member: smok
» Forum threads: 904
» Forum posts: 6,159

Full Statistics

Online Users
There are currently 71 online users.
» 1 Member(s) | 68 Guest(s)
Bing, Google

Latest Threads
Custom TAP loader with SC...
Forum: Help & Support
Last Post: boriel
3 hours ago
» Replies: 6
» Views: 27
Help with scroll.bas libr...
Forum: Help & Support
Last Post: boriel
Yesterday, 11:12 PM
» Replies: 3
» Views: 966
Printing an updated scree...
Forum: Help & Support
Last Post: boriel
01-14-2021, 09:14 PM
» Replies: 3
» Views: 69
Dim Array At Constant Iss...
Forum: Bug Reports
Last Post: Ljg701
01-14-2021, 04:49 PM
» Replies: 3
» Views: 71
First RND call is ignorin...
Forum: Bug Reports
Last Post: boriel
01-14-2021, 02:42 PM
» Replies: 3
» Views: 85
Documentation frequently ...
Forum: Documentation
Last Post: patters
01-13-2021, 12:01 PM
» Replies: 0
» Views: 28
Mixing variable types in ...
Forum: Help & Support
Last Post: boriel
01-06-2021, 08:10 PM
» Replies: 18
» Views: 345
Compiler Speed Trials
Forum: ZX Basic Compiler
Last Post: boriel
01-05-2021, 01:26 PM
» Replies: 74
» Views: 108,677
Bikers - ZX Spectrum Next
Forum: Gallery
Last Post: boriel
01-04-2021, 09:29 PM
» Replies: 3
» Views: 339
Declaring the length of a...
Forum: Help & Support
Last Post: patters
01-03-2021, 06:09 PM
» Replies: 2
» Views: 124

  Custom TAP loader with SCREEN$
Posted by: patters - Yesterday, 06:24 PM - Forum: Help & Support - Replies (6)

I have a Sinclair BASIC loader for my game which will CLEAR 32767, load a SCREEN$, LOAD ""CODE, and finally RANDOMIZE USR 32678. I have assembled the loader and the SCREEN$ into a TAP file - but how to I get zxbc.py to append its output to this TAP file? I can't seem to get it to work.

When I try:

./zxbc.py -t --append-binary ../loader+scr.tap ../arti12.bas
I get a file arti12.tap as expected but it doesn't load the machine code. If I browse the TAP file in Fuse emulator I see that zxbc.py appears to have prepended an additional self-contained TAP file into the loader TAP file, rather than appended the binary data. Am I doing this wrong, or is this a bug?

I have managed to work around the issue by producing a .bin file instead, and then Fuse's 'Import Binary Data' option and then saving the memory range back out to the mounted TAP file - but it would be much nicer to automate that with zxbc.py if possible.


Print this item

  Documentation frequently offline
Posted by: patters - 01-13-2021, 12:01 PM - Forum: Documentation - No Replies


I have been frequently referring to the ZX Basic documentation while I have been programming. I find that at random (but multiple times a day) the search feature on the wiki returns no results for a short period which is quite frustrating. It's happened again right now. During though outages, luckily I can consult the markdown files on GitHub. However, they don't have a search function, which is useful so I do prefer the wiki.

I also notice that the boriel.com landing site frequently drops off the Internet late at night too. Can you perhaps set up some kind of host monitoring to determine just how big a problem this is, or maybe raise a support ticket with the webhost?



Print this item

Bug First RND call is ignoring RANDOMIZE, subsequent calls are fine (*solved*)
Posted by: patters - 01-13-2021, 02:38 AM - Forum: Bug Reports - Replies (3)

I have noticed while testing my program that the very first random number is always the same when the compiled program is loaded into an emulator. Subsequent ones are indeed random.

That first result is normal - you might think - because RND will be invoked at the same number of ticks after power-on each time. However, I use RANDOMIZE after an INPUT (which won't always be submitted at a consistent time by the user) before the first RND in the program is requested, so this should not happen. I presume this is a bug because after the first RND, it behaves as normal. If I deliberately insert a dummy RND before the RND values I need, then my program runs with the expected randomness.

Simple test case which demonstrates the issue:

#include <input.bas>

PRINT INT (RND*100) 'this number is consistent every time the emulator is launched with the tap file
PRINT INT (RND*100) 'this number will be random

When I run the tap file in Fuse on Mac OS I usually get 60 for the first random number. Very occasionally I get 61 though, so that may help for debugging. It's always those two values though. The second number will be in the range 0-99 as expected.

This issue is present in release version 1.14 and in 1.14beta9

Print this item

  Dim Array At Constant Issue (*fixed*)
Posted by: Ljg701 - 01-12-2021, 03:27 PM - Forum: Bug Reports - Replies (3)


I'm trying to dim an array at a specific address which has been defined as a constant of type uinteger, unless I add 0 to the constant the code does not compile. 

const tileStart as uinteger = $4000+384

dim tile(0 to 255) as uinteger at tileStart         'this fails to compile with "Address must be a numeric constant expression" 
'dim tile(0 to 255) as uinteger at tileStart+0         compiles OK

print at 0,0;str(tileStart)

Am I missing something?

This is version: [v1.14.0]

Print this item

  Printing an updated screenful in one go
Posted by: worcestersource - 01-11-2021, 09:09 PM - Forum: Help & Support - Replies (3)

Hello everyone,

I'm loving the discovery of zxbc and having a great time working on the game I always wanted to make! Thanks Boriel!

I've written code that randomly generates a map (well, its floor), which is stored in an array. To keep the size in memory down, I store the rows as bits and have written a routine to make reading this back in the game code nice and simple. I can easily determine if any given coordinate is floor or not. I'm really happy with this. Bit operators are brilliant!

I'm now at the stage where I need to start putting my graphics on the screen. Using the map floor as a reference, I intend to display the walls and floor of the dungeon using 3x3 character blocks, with each successive row overprinting the bottom of the row before it. This way I should be able to display a 9 x 9 view with a pseudo 3D view and the player in the middle.

Using the floor as the starting point, what's I'm trying to work out right now is the best way to could assemble the whole view of this and print it to the screen in one go so the player doesn't see it redraw tile by tile. As the game is turn based, I don't mind if preparing and moving the updated screen isn't instant.

I've thought of two methods:

  1. Dynamically create a string and colour it in using control codes, to set everything up that is then printed in one go.
  2. Scroll the screen, a tile in whatever direction needed and then fill in the space.
I think the first would give the best results, if it's possible, and the second should be achievable with the scroll routines I've been reading about.

My questions are whether there are any other approaches I could take and if anyone kindly has any advice on manipulating and embedding control chars into strings. I've read some other posts but these don't go as far as constructing a string.



I'm probably going to keep throwing my thoughts into this thread (sorry - I do this on car forums when I'm fixing my old car!).

If I'm treating the string as a fake screen, could I use chr$ 22 as if it were AT? Does the string reorder itself if I do something like

LET s$ = s$ + chr$(22, y, x, 17, 1, 65)

And replace the 1 and the 65 with values from an array that stores the colour swatch and characters?

I'm then curious how the string is stored. Is it the logical concatenation of all of the statements like the above that I'll loop through 81 times or does it reorder itself if the AT equivalents were presented in a non-linear fashion?

Print this item

  Mixing variable types in a numerical calculation
Posted by: patters - 01-05-2021, 12:50 AM - Forum: Help & Support - Replies (18)

My program is calculating attribute memory addresses for screen characters. In the interests of only DIMing what I need, I store the screen coordinates as UBYTE since I only need numbers from 0-32 at most.

I have spent a long time to find that the compiler doesn't perform the maths properly when these UBYTE variables are used with larger numbers in a calculation - even though I'm never asking for that UBYTE variable to be made any larger. See this example:

POKE attrMem,16 'red paper, black ink

The result should be a red square AT 18,4. However, it is printed in the wrong location on the screen unless I change variables x and y to type INTEGER. Why would this be, since I am not asking for y or x to be expanded beyond their existing values? Is this expected behaviour, or a bug? I haven't really programmed any languages which have needed me to be so specific about number types before, so apologies if this is a silly question.

Print this item

  Declaring the length of a string
Posted by: patters - 01-03-2021, 01:55 AM - Forum: Help & Support - Replies (2)

In Sinclair BASIC you can DIM the length of a string using
DIM a$(5)

If I try something similar in Boriel BASIC

the compiler seems to interpret this as an array declaration.

Sometimes it's useful to declare the largest expected length of a string if you want to build it up of component pieces. e.g. In Sinclair BASIC:

10 DIM a$="hello"
20 DIM b$(8)
30 LET b$=a$
40 LET b$(4 TO 8)="p me!"
50 PRINT b$

If I try to do this in Boriel BASIC I can't declare the length, nor does it expand when needed. I seem to have to do it in two steps, one for overwriting the parts of the existing string, and a separate step to glue an addition to the end of the string.
DIM a$, b$
b$(3 TO 4)="p "

Is this expected? Or is there a better way of building b$ from a$ in this example in only one step?

Print this item

Bug PRINT bug using CHR$(22) for inline positioning (*solved*)
Posted by: patters - 12-30-2020, 01:09 AM - Forum: Bug Reports - Replies (13)

It seems as if the compiler gets this wrong when the x coord is greater than 27. See example:

DIM a$, b$ AS String
a$=CHR(22,17,27,65,66) 'PRINT AT 17,27;"AB" - fine
b$=CHR(22,18,28,67,68) 'PRINT AT 18,28;"CD" - wrong location (19,0)
c$=CHR(22,19,29,69,70) 'PRINT AT 19,29;"EF" - wrong location (20,0)
PRINT a$;b$;c$
PRINT AT 20,28;"GH"                        '- fine
PRINT AT 18,0;"--"                         '- fine

At x=28 there is adequate space to print the two characters "CD" before the line wrap,  but strangely they end up being PRINTed AT 19,0 instead of AT 18,28. I presume it's because the compiler is forgetting that CHR$(22) and the following two special characters do not count towards the PRINTed length of the string. Will this error also occur for the other inline control codes for INK, PAPER, BRIGHT, OVER, etc.?

This error is present in the the latest stable release 1.13.2, and the betas for 1.14 (which I gather had some PRINT changes). Being able to set the coordinates and attributes inline like this is useful for manipulating pre-formed sprites.

Print this item

Bug Function to edit a string (*solved*)
Posted by: patters - 12-29-2020, 05:13 PM - Forum: Bug Reports - Replies (8)

I'm having trouble passing a string to a Function in order to edit it. The code which works fine outside of a Function just won't modify the string inside the Function for some reason. Any idea what I'm doing wrong?

DIM a$ AS String

FUNCTION editStringFN(stringToEdit$ AS String, position AS Integer, newLetter$ AS String) AS String
    RETURN stringToEdit$

PRINT a$; "- original string"

'try to edit string via the function
a$=editStringFN(a$, 1, "i")
PRINT a$; "- function fails to edit"

'same edit without using the function
PRINT a$; "- works as regular code"

Print this item

Bug PAUSE not working (*solved*)
Posted by: patters - 12-29-2020, 03:56 AM - Forum: Bug Reports - Replies (15)

In my program PAUSE doesn't seem to work. Is that normal? I would find it useful to delay execution a bit while my program prints an error on screen when the result of an INPUT isn't compliant. I can't see any mention of PAUSE in the wiki. I mean I can use a FOR loop to count to 10,000 instead, but I thought the aim of Boriel BASIC is to be a faster superset of Sinclair BASIC so it's surprising this seems to be missing.

Print this item