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

Username
  

Password
  





Search Forums

(Advanced Search)

Forum Statistics
» Members: 267
» Latest member: ConradoBadenas
» Forum threads: 1,083
» Forum posts: 6,472

Full Statistics

Online Users
There are currently 167 online users.
» 1 Member(s) | 163 Guest(s)
Baidu, Bing, Google, tubz74

Latest Threads
Old zxbasic game errors
Forum: Help & Support
Last Post: boriel
11 hours ago
» Replies: 5
» Views: 84
Error: Undefined GLOBAL l...
Forum: Help & Support
Last Post: ardentcrest
2025-11-04, 05:46 PM
» Replies: 3
» Views: 82
A Fast(er) Plot Routine f...
Forum: How-To & Tutorials
Last Post: tubz74
2025-10-30, 03:16 PM
» Replies: 2
» Views: 135
Hall of Fame - Include fo...
Forum: How-To & Tutorials
Last Post: tubz74
2025-10-28, 03:48 PM
» Replies: 0
» Views: 82
[SOLVED] Array layout bug...
Forum: Bug Reports
Last Post: Zoran
2025-10-25, 05:48 PM
» Replies: 2
» Views: 183
3DOS Commands?
Forum: Help & Support
Last Post: boriel
2025-10-06, 02:54 PM
» Replies: 3
» Views: 346
How to open fuse as an ex...
Forum: How-To & Tutorials
Last Post: zedex82
2025-10-05, 07:36 PM
» Replies: 2
» Views: 263
CLS/Fade out ASM Sub-rout...
Forum: How-To & Tutorials
Last Post: tubz74
2025-10-05, 03:39 PM
» Replies: 2
» Views: 259
ZX Basic Studio Bugs
Forum: Bug Reports
Last Post: Duefectu
2025-09-23, 04:07 PM
» Replies: 5
» Views: 1,049
Printing with FZX
Forum: Help & Support
Last Post: boriel
2025-07-17, 10:08 PM
» Replies: 1
» Views: 1,947

 
  Old zxbasic game errors
Posted by: ardentcrest - 2025-11-03, 09:32 PM - Forum: Help & Support - Replies (5)

trying Escape From Cnossus from 2013 getting this error

Error: 'subdivideHigh' is neither an array nor a function.

the line is

wall1 = subdivideHigh(x1, y1, x - 1, y2)

any help please

Print this item

  Error: Undefined GLOBAL label
Posted by: ardentcrest - 2025-11-02, 01:43 PM - Forum: Help & Support - Replies (3)

Looking over an old file of mine that once worked I'm now getting Error: Undefined GLOBAL label . each one is going to a fastcall.

ie

        ld hl, lineMSG
        ld bc, end1-lineMSG
        call myPrint42

calling 

SUB fastcall myPrint42()
ASM
myPrint42:
    push    af
    push    ix
    push    hl
    ld    ix, PRINT42
    CALL    IXCALL
    pop    hl
    pop    ix
    pop    af
    ret
END ASM
END SUB

gives me Error: Undefined GLOBAL label ".myPrint42"

any help please....

Print this item

  A Fast(er) Plot Routine for Boriel Basic
Posted by: tubz74 - 2025-10-28, 03:56 PM - Forum: How-To & Tutorials - Replies (2)

I orginally posted this on SpectrumComputing Forum - copied here in case anyone wants to play with it :-)

Hi

Hope this helps someone else :-)

I saw a post by Andy Dansby who writes at https://zxspectrumcoding.wordpress.com/

He has created a fast plot routine, (hellaplot), so I thought I'd try and convert it to a Boriel Basic (BB) subroutine, just for fun and learning - and as it was a single routine.

I had to do a little bit of reading, but also had to ask for help from the BB telegram community, as to begin with the code was crashing the emulator. Turns out it was a simple fix when you know how - FASTCALL was needed when passing parameters for ASM to use from a SUB routine.

Andy's code needs the x/y locations in DE, so I had to do a little bit to get them set up like this - I assume there might be some more efficiency if different registers were used as BB passes from the subroutine call, the first parameter into A, and the second parameter is the second item on the stack (the first being the return address).

When I started, xPos was the first parameter, and yPos the second (as I like x,y), but this meant to get them into DE, took another load (POP DE, LD E with D, LD D with A, compared to POP DE, LD E with A)

So some "non exact" timings - plot included as the library in BB takes about 15 seconds to fill up the screen with "points". Andy's one takes 5 seconds to do the same.

As far as Andy's code goes, I understand the comments, but not exactly how it works :-)

Anyway, code below :

SUB FASTCALL HellaPrint(yPos as UBYTE, xPos as UBYTE)
' HellaPrint prints an x,y pixel
' 0,0 is top left
' Original code by Andy Lansby
' https://zxspectrumcoding.wordpress.com/
' yPos is first, as it save a LD instruction when putting xPos and yPos into DE
ASM

JP START ; Put this in as it's like this on the Wiki ASM desciption - can it be avoided?
X_PositionBits: defb 128,64,32,16,8,4,2,1
; Might there be a quicker way to do the above, so it's not needed every time the program is run? or does it not work like this and is created once at compile time?

START: ; plot d = x-axis, e = y-axis
; A contains the yPos, xPos is on stack.
POP HL ; Pops the return address into HL
POP DE ; xPos is on the stack, and it needs to be in D
LD E, A ; A has our first paramter (yPos), load it into E. D should be Xpos, E should be yPos
PUSH HL ; Puts the return address back onto stack ...
; 166 T states per pixel
XOR A ; reset A to 0 and flags to default
LD A,E ; load Y plot point
RRA ; rotate Right --- divide in half
SCF ; turn on Carry flag-
RRA ; rotate right with the carry flag
OR A ; set flag S on - C flag off
RRA ; rotate Right --- divide in half

LD L,A ; temp store in L
XOR E ; XOR the Y value
AND %11111000 ; mask out bottom 3 bits
XOR E ; XOR the Y value

LD H,A ; store High byte
LD A,D ; load X plot point
XOR L ; XOR the temp value
AND %00000111 ; mask out unwanted bits
XOR D ; XOR the X value
RRCA ; divide by 2
RRCA ; divide by 4
RRCA ; divide by 8

LD L,A ; store Low byte
; now we have the full address
; now use LUT to find which bit to set
LD A,D ; load X plot point
AND %00000111 ; mask out unwanted bits

; use a LUT to quickly find the bit position for the X position
LD DE,X_PositionBits ; load LUT address into DE
ADD A,E ; Add A to E to get offset into table
LD E,A ; E now points to the LUT entry
LD A,(DE) ; load answer into A

; output to screen
OR (HL) ; or with contents of address HL
LD (HL),A ; load address HL with Answer from A
END ASM
END SUB

Print this item

  Hall of Fame - Include for ZX Basic
Posted by: tubz74 - 2025-10-28, 03:48 PM - Forum: How-To & Tutorials - No Replies

Hi

HOF.zxbas - Hall of fame procedures
main.zxbas - a demo

Attached is a little "library" for a Hall of Fame / High Score table.

To use it - you need to create two Arrays (at least 2 ...)

Array 1 = UInteger, for scores
Array 2 = String, for names

Probably best to keep to 10 entries, but could be more.  You can have more than 1 HOF, so could have Array2, Arry3 etc etc for say Easy Score, Medium Scores, Hard Scores.  As it passes the Arrays by reference, no other variables are needed.

Completely and utterly free to use, adapt, change, republish how ever you want.

Arraybase is 0

SUB HOF_IntialiseHOF(BYREF HOF_Scores() AS UINTEGER, BYREF HOF_Names() AS STRING, HOF_IntialTopScore as UINTEGER,HOF_InitialName AS STRING)
Use this to initialise the two HOF arrays - with a "highest score, working down to a low score and gives each entry "InitialName".

FUNCTION HOF_HighScore_CheckEntry (HOF_Scores() AS UINTEGER, NewHighScore as UINTEGER) AS BYTE
Returns 1 if the High Score can g into the Arrays.

SUB HOF_HighScore_NewEntry (BYREF HOF_Scores() AS UINTEGER, BYREF HOF_Names() AS STRING, NewHighScore as UINTEGER, NewHighScoreName AS STRING)
Puts the new entries (name & score) into the HOF array.

SUB HOF_Print(BYREF HOF_Scores() AS UINTEGER, BYREF HOF_Names() AS STRING, YPOS as INTEGER, XPOS as INTEGER)
A simple print location, witch prints the Score and Names.  Will carry on printing if you have many entries ...

SUB HOF_PrintSpecial(BYREF HOF_Scores() AS UINTEGER, BYREF HOF_Names() AS STRING)
A "pretty High Score screen", that prints the top 10 scores.

Can probably be improved and made much more efficient.  There are porbably bugs as well (for example not sure what would happen if you had 100 entries with a first high score of 10 ... i think it's probably overflow to 655555 etc.  It includes string.bas and input.bas - not sure if the library needs both of those.



Attached Files Thumbnail(s)
   

.zip   HOF.zip (Size: 2.98 KB / Downloads: 20)
Print this item

  [SOLVED] Array layout bug - regression in 1.18.3
Posted by: Zoran - 2025-10-24, 11:24 PM - Forum: Bug Reports - Replies (2)

Please take a look at this simple programme:


Code:
dim a(5) as ubyte => {0, 1, 2, 3, 4, 5}
dim b(5) as ubyte
dim i as uinteger

for i = 0 to 5
    poke @b + i, a(i)
next

cls

for i = 0 to 5
    print a(i), b(i)
next

When compiled with zxbasic 1.18.2 this works as expected - both arrays are same. See the attached image:
   
However, with zxbasic 1.18.3, the programme fails miserably and crashes the Spectrum

In both cases compiled with 
Quote: Wrote:--optimize 2  --output-format=tzx --BASIC --autorun --explicit --strict

Now, this is the simple case made to illustrate the bug. The main problem I have is with character arrays -- I have custom font with cyrilic letters designed in ZXBasicStudio, stored as two dimensional array (95, 7) -- when I want to write cyrilic text I poke the system variable 5C36 to the address of the array minus 256 (@array - $100) and when I want to print latin text, I just poke this variable back to default value  $3C00. This worked perfectly until version 1.18.3 came out. Now, everything is broken, as the characters in the array are obviously not stored continuously in memory.
What happend with array layout?




Now I tried to see the address of the array itself, compared with the addresses of array elements:
Code:
dim a(5) as ubyte => {0, 1, 2, 3, 4, 5}
dim i as uinteger
cls
print "@a = "; @a
print "------------"
for i = 0 to 5
  print "@a("; i; ") = "; @a(i)
next

The attached image shows the output with zxbasic 1.18.2 compared with zxbasic 1.18.3:
   

It seems that in zxbasic 1.18.3, there are eight bytes between the address of the array itself (@a) and the first element (@a(0) ). The array elements are stored continuously after all.

So, I can workaround the problem with the custom character set that I mentioned in my previous post using:
Code:
poke (uinteger $5c36, @charset(0,0) - $100) ' the address of the first element
instead of
Code:
poke (uinteger $5c36, @charset - $0100) ' the address of the array

But still, is there a reason for this, or is it just a bug?

Print this item

  3DOS Commands?
Posted by: tubz74 - 2025-10-05, 10:33 PM - Forum: Help & Support - Replies (3)

Hi

I'm looking at using some 3DOS commands, starting to see how I can cat a disk.

I've takend the below code from the +3 manula (pg 200 to 203) which should allow me to get the CAT into memory - the code looks to activate the disk (and for example if I don't attach a disk, it give me abort/retry) but then "reboots"/crashes the emulator back to the +3 menu.

I'm assuming that there might be some incompatibility somewhere between, starting reading, and returning contorl to the program.  Code is below.

Any thoughts?

(PS If the ASM didn't crash, the program wouldn't actually do anything anyway yet, as I've not sorted any output, or any caribles)


Code:
#include <input.bas>
#include <screen.bas>
#INCLUDE <keys.bas>

PRINT "This is the start"
main()


SUB main()
    LET YesNo = "n"
    PRINT "do you want to CAT disk"
    YesNo = INPUT(1)
    IF YesNo="y" then
        Catalogue()
    END IF
    PRINT "Ed#nd Main"
END SUB



SUB Catalogue()
    ASM
        PUSH IX ; dos catalog corrupts ix
        PROC
       
        LOCAL   MYSTACK
        LOCAL   STACKSTORAGE
        LOCAL   BANKM
        LOCAL   PORT1
        LOCAL   CATBUFF
        LOCAL   DOS_CATALOG
       
       
        MYSTACK         EQU     9fffh ;
        STACKSTORAGE    EQU     9000h ; save pointer
        BANKM           EQU     5b5ch ; system var that holds last value output to 7ff0h
        PORT1           EQU     7ffdh ; address of rom/ram switching port
        CATBUFF         EQU     8000h ; location for dos to output
        DOS_CATALOG     EQU     011Eh ; DOS routine to call
   
        JP start
        stardstar:  defb "*.*",255                   
        dosret:     defw 0
   
        start:
            DI
            LD (STACKSTORAGE),SP
            LD BC,PORT1         ;
            LD A,(BANKM)        ; current switch state
            RES 4,A             ; move right to left in horizontal rom switch (3 to 2)
            OR 7                ; switch in ram page 7
            LD (BANKM),A        ; keep system var up to date
            OUT (C),A           ; switch ram and rom
            LD SP,MYSTACK       ; make sure stack is above 4000h and below bfeoh
            EI                  ; enable interrupts
            ;
   
  
            LD HL,CATBUFF
            LD DE,CATBUFF+1
            LD BC,1024
            LD (HL),0
            LDIR
            LD B,64
            LD C,1
            LD DE, CATBUFF
            LD HL,stardstar             ;file name *.*
            CALL DOS_CATALOG            ;call dos catalog
            PUSH AF
            POP HL
            LD (dosret),HL              ; put here so can be seen from basic
            LD C,B                      ; number of files in catalog, low byte of bc
            LD B,0                      ; returned to basic by usr functio
   
            DI
            PUSH BC
            LD BC, PORT1
            LD A, (BANKM)
            SET 4, A                    ; move left to right (riom 2 to 3)
            AND 48h                     ; ram page 9
            LD (BANKM),A                ; update syste value
            OUT (C),A                   ;switch
            POP BC                      ; get back saved number of files
            LD SP,(STACKSTORAGE)        ;
            EI
            ;RET ; not sure if thisis needed
        ENDP
        POP IX
        ;RET ; Not sure if this is needed here
    END ASM
END SUB

Print this item

  How to open fuse as an external emulator in ZXBasic Studio for +2a/b/+3- Windows 11
Posted by: tubz74 - 2025-10-05, 07:13 PM - Forum: How-To & Tutorials - Replies (2)

ZXStudio doesn't support +3/+2a etc in the included emulator. Requires at least Beta 6 of ZXBasicStudio

Use Project/Configure Project to configure.

Example Compiler Parameters

-O 0 -S 32768 -H 4768  -f tap -B -a

(The bold was auto generated, underscore are the options added "-f tap" to create a tap file, "-B -a" required to Generate the basic file and auto start.

Example Launch External Emulator

C:\zx\projects\DOSTesting\ZXStartFuse.bat

This has to be a batch file, rather than direct to the emulator, %1 and %2 are passed into the batch file for ZXBasicStudio - %1 is the path, and %2 the filename excluding the extension.

ZXStartFuse.bat created in the OS, and renamed to .bat, as it was txt file.

Code:
ECHO OFF
"C:\Program Files (x86)\Fuse\fuse.exe" -m plus3 --auto-load %1%2.tap


This would open a plus3 spectrum in fuse and run the tap file.

(Thanks to support from telegram for getting this to work ..)

Print this item

  CLS/Fade out ASM Sub-routine
Posted by: tubz74 - 2025-10-05, 02:37 PM - Forum: How-To & Tutorials - Replies (2)

This is a small clear screen, that sort of fades out the screen pixel by pixel to the background colour.  I took it from one of the Melbourne house books, can't remember which one though.

No idea if it breaks anything else, but I've not had any issues.

Code:
SUB CLSFadeOut()
' Fade out Screen Clearing

    ASM

        LD DE,08feh
        NXTFADE:
            LD A,E
            RLCA
            RLCA
            RLCA
            LD E,A
            LD HL,4000H
            LD BC,0018H
            NXT:
                LD A, (HL)
                AND E
                LD (HL),A
                INC HL
            DJNZ NXT
            DEC C
            JR NZ,NXT
            DEC D
        JR NZ,NXTFADE
        LD A,(5C8DH)
        LD (HL),A
        LD D,H
        LD E,L
        INC DE
        LD BC,02C0H
        LDIR
        LD A,(5C48H)
        LD (HL),A
        LD C,3FH
        LDIR
    END ASM

END SUB

Print this item

  ZX Basic Studio Bugs
Posted by: ZXPeter - 2025-09-19, 04:21 PM - Forum: Bug Reports - Replies (5)

Don't know if this is the correct place for this post  but I'm sure someone will let me know if not.

This post relates to ZX Basic Studio builds 1.0.8702.19933 2023-10-29 and 1.5.9168.37638 2025-02-06 which ,for brevity, I shall call buildA and buildB respectively.

Following the instructions for creating a project from pages 47 to 53 of the "Boriel Basic for ZX Spectrum" book I have the following observations:

(1)
With buildA the Main.bas file appears in the explorer window when it is created,as described in the book. 

With buildB it does not. Closing the displayed code by clicking the X next to the "Main.bas" file name removes the code from view and there is no way of re-opening 
it from the explorer window (as it isn't listed there). One way to make the file name visible in the explorer window is to close then re-open the project.

(2)
For both buildA and buildB running the book's example code (page 51) without debug results in the expected coloured block of X's.
Running the code under debug with a breakpoint set as shown on page 52, neither build produces the full block (stops after 3 and a bit rows).

Hope this information is useful.

Print this item

  Printing with FZX
Posted by: solar penguin - 2025-07-14, 04:45 PM - Forum: Help & Support - Replies (1)

Hi, I'm new, so these are probably stupid questions. But, I'm confused about printing with printFzxStr. Is there any way to to get it to word wrap neatly? It's breaking to a new line in the middle of a word (or even the middle of a letter)

As a last resort, I guess I could have a go at writing my own word-wrap routine if I knew where to find the different widths of all the characters and the position of the text-printing cursor along the row. How would I go about finding them?

One final question. Is there a way to make FZX scroll when it reaches the bottom of the screen instead of just stopping ZX81-style with an error message?

Thanks

Print this item