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

Username
  

Password
  





Search Forums

(Advanced Search)

Forum Statistics
» Members: 273
» Latest member: mindlin
» Forum threads: 1,085
» Forum posts: 6,486

Full Statistics

Online Users
There are currently 70 online users.
» 0 Member(s) | 67 Guest(s)
Applebot, Baidu, Bing

Latest Threads
location of heap manageme...
Forum: Help & Support
Last Post: boriel
2026-03-07, 12:13 AM
» Replies: 1
» Views: 216
non-paged supervisor code...
Forum: Help & Support
Last Post: sdo303
2026-02-20, 06:38 PM
» Replies: 8
» Views: 692
How to open fuse as an ex...
Forum: How-To & Tutorials
Last Post: Duefectu
2026-02-09, 01:52 PM
» Replies: 3
» Views: 1,069
Old zxbasic game errors
Forum: Help & Support
Last Post: boriel
2025-11-09, 11:52 AM
» Replies: 7
» Views: 1,678
Error: Undefined GLOBAL l...
Forum: Help & Support
Last Post: ardentcrest
2025-11-04, 05:46 PM
» Replies: 3
» Views: 812
A Fast(er) Plot Routine f...
Forum: How-To & Tutorials
Last Post: tubz74
2025-10-30, 03:16 PM
» Replies: 2
» Views: 935
Hall of Fame - Include fo...
Forum: How-To & Tutorials
Last Post: tubz74
2025-10-28, 03:48 PM
» Replies: 0
» Views: 475
[SOLVED] Array layout bug...
Forum: Bug Reports
Last Post: Zoran
2025-10-25, 05:48 PM
» Replies: 2
» Views: 945
3DOS Commands?
Forum: Help & Support
Last Post: boriel
2025-10-06, 02:54 PM
» Replies: 3
» Views: 1,109
CLS/Fade out ASM Sub-rout...
Forum: How-To & Tutorials
Last Post: tubz74
2025-10-05, 03:39 PM
» Replies: 2
» Views: 839

 
  The Client
Posted by: ardentcrest - 2015-02-23, 09:47 AM - Forum: Help & Support - No Replies

Hi Jose, can you take a look at this. To run it you need the spectranet running in fuse. but I'm getting a crash when running it. I think it has something to do with the way i'm using the DIM thekeys$

Code:
INK 7 : PAPER 0 : BORDER 0 : CLS
#include <times2.bas>
#include <print42.bas>
#include <print64.bas>
#include <input.bas>
#include <keys.bas>



dim thekeys$: let thekeys$="                                                            "
let length=60 : let rowx=0 : let xx$="<"

pause 10





plot 0,0 : draw 255,0 :  draw 0,175 : draw -255,0 : draw 0,-175
doubleSizePrint(0,4,"The Spectrum")
doubleSizePrint(2,10,"Client")

printat42(5,4)
Print42("Welcome to the The Spectrum Client.")
printat64(7,8)
print64("With this client YOU can access 2 online MUDS.")
printat64(8,12)
print64("The 8 Bit Mud, and the Star Wars Mud.")
printat64(9,3)
print64("With the 8 Bit Mud, we will be adding text adventure games")
printat64(10,23)
print64("from the spectrum.")
printat64(12,7)
print64("You can also access a BBS Bulletin Board System")
printat64(14,2)
print64("1 : The 8 Bit Mud.  2 : The Star Wars Mud.  3 : The 8 Bit BBS")


PRINT AT 20,1;"(1/2/3/Q) ";


MENUINPUT:
i$=INPUT(1)
if i$="1" then goto THEBITMUD : end if
if i$="q" or i$="Q" then stop : end if
goto MENUINPUT

THEBITMUD:

INK 7 : PAPER 0 : BORDER 0 : CLS
print at 0,0;"Ardent's Spectranet TCP Client Test"
print at 2,0;"Looking up Host The8bitmud.zapto.org"
goto THESTART
end

THESTART:



pause 50
opensocket()
pause 50

hostip()
pause 50

connect()
pause 50
sendfirst()
pause 100
INK 7 : PAPER 0 : BORDER 0 : CLS : CLS
print at 0,0;
MAIN:

NETmainloop()
gosub NETinputloop


goto MAIN





NETinputloop:

2008 print at 22,0;thekeys$( to rowx )+xx$+thekeys$( rowx+1 to )

2010 let k=code inkey$ : if k then beep .2,0 : end if
2011 if k>31 and k<128 then goto 2264 : end if
2012 if k=13 then goto 2036  :end if
2013 if k=8 then goto 2026  :end if
2014 if k=9 then goto 2028  :end if
2015 if k=10 then goto 2030  :end if
2016 if k=11 then goto 2032  :end if
2017 if k=12 then goto 2034  :end if

2019 return


2026 if rowx=0 then goto 2010 : end if
2027 let rowx=rowx-1 : goto NETinputloop
2028 if rowx=length then goto 2010 :end if
2029 let rowx=rowx+1 : goto NETinputloop
2030 if rowx+32>length then goto 2010 :end if
2031 let rowx=rowx+32 : goto NETinputloop
2032 if rowx<32 then goto 2010 : end if
2033 let rowx=rowx-32 : goto NETinputloop
2034 if not rowx then goto 2010 : end if
2035 let rowx=rowx-1 : goto 2041
2036 gosub senddata : gosub NETrestart : return
2038 goto 2010
2040 if rowx=length then goto 2010 : end if
2041 let thekeys$( rowx+1 to )=thekeys$( rowx+2 to ) : let thekeys$(length)="" : goto 2008
2264 if rowx=length then goto 2010 : end if

let thekeys$(rowx)=chr$(k)

2265 let rowx=rowx+1 : if rowx<length then let thekeys$( rowx+1 to )=thekeys$( rowx to ) : end if


goto 2008
2499 goto 2010


NETrestart:
let rowx=0: let thekeys$="                                                            "
return


senddata:
let p=len(z$) - 1
ttt:
if thekeys$(p)=" " then let p=p-1 : goto ttt :end if



    FOR ii = 0 TO p:  
           POKE @MyLabel + ii, CODE thekeys(ii)
    NEXT ii
poke @MyLabel2,p




return


SUB fastcall opensocket()
    ASM

        ld c, 1
        ld hl, SOCKET
        call HLCALL
        ld (v_sockfd), a
        ret

    END ASM
END SUB

SUB fastcall hostip()
    ASM

        ld hl, serverhost
        ld de, ip_buffer
        ld ix, GETHOSTBYNAME
        call IXCALL
        ret
    END ASM
END SUB

SUB fastcall connect()
    ASM
        ld hl, connectingMSG
        ld    bc, end3-connectingMSG
        call myPrint42
    
        ; now actually connect...
        ld a, (v_sockfd)                ; get back the socket file descriptor
        ld de, ip_buffer                ; point to the dotted ip notation we got previously
        ld bc, serverport                ; the port I want to use to connect on... (22528 as is heh)
        ld hl, CONNECT
        call HLCALL                    ; call the Spectranet CONNECT ROM routine, :D
        ;jp c, commerror                ; carry is set if there is an error (fingers crossed k)
    
        ; CONNECTED !!!
        xor a
        inc a
        ld (connected), a
    
        ld hl, connectedMSG
        ld bc, end5-connectedMSG
        call myPrint42
END ASM
END SUB

SUB fastcall sendfirst()
    ASM
        ld a, (v_sockfd)
        ld de, garbage
        ld bc, garbageend-garbage
        ld hl, SEND
        call HLCALL
    END ASM
END SUB



SUB fastcall send2()
    ASM
        ld a, (v_sockfd)
        ld de, garbage2
        ld bc, garbageend2-garbage2
        ld hl, SEND
        call HLCALL
    END ASM
END SUB


SUB fastcall NETmainloop()
ASM

    ; main receive loop, :/
.tightloop:
    ; poll the socket to see if data is waiting
    call    pollSocket
    jr c, .no_data1
    ; there is data to be collected
.gData2:
    call    clearBuffer
    ld a, (v_sockfd)
    ld de, responseBuffer
    ld bc, responseBufferEnd-responseBuffer
    ld hl, RECV
    call HLCALL
    jp c, commerror
    ld hl, responseBuffer            ; get the address of the buffer
    add hl, bc                    ; add on the number of received bytes
    inc hl
    ld (hl), msgEND                ; mark that point as the end of the text
    call    displayData                ; and just display that, :D
    jr .tightloop
.no_data1:    
scf
;    xor a
; .checkkeys:    

;    jr nc, .tightloop

    ; now close the socket, dunno why cos I ain't never ever gonna give you up, err, I mean drop to BASIC
                ; green indicates complete run through worked ok...
    ret
;========================================================================    

pollSocket:
    ; returns carry clear if data to be fetched
    ; or set carry to indicate no data...
    ld    a, (v_sockfd)
    ld    hl, POLLFD
    CALL HLCALL
    jr    z, .nodata
    scf
    ccf
    ret
.nodata:
    scf
    ret


displayData:
    ;ld a, 3
    ;out ($fe), a
    ld hl, responseBuffer
    call myPrint42
    ret

END ASM
END SUB

SUB fastcall clearBuffer()
ASM
clearBuffer:
    ld    hl, responseBuffer
    ld    de, responseBuffer+1
    ld    bc, responseBufferEnd-responseBuffer-1
    ld    (hl), 32
    ldir
    ret
END ASM
END SUB

SUB fastcall commerror()
    ASM
        commerror:
        ld a, 2
        out ($fe), a                    ; turn border red to indicate error... :/
        ld hl, errorMSG
        call myPrint42                ; print the error msg
        ld a, (v_sockfd)
        and a                        ; do we have a socket?
        ret z                        ; nope, so return ;NOTE: This may cause a ret to BASIC, grr, will sort it later, :p
        ld hl, CLOSE                    ; we have a socket, so clean it up
        call HLCALL
        ;call end_interrupts            ; reset interrupts back to im 1..
        ret
    END ASM
END SUB

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



ASM

msgEND            EQU 0
msgCR                  EQU 10

RET_OK            EQU 0
RET_SOCKERR        EQU 1
RET_PORTERR        EQU 2
RET_RECEIVEERR    EQU 4
RET_UNKNOWN        EQU 128

SOCK_STREAM        EQU 1
SOCK_DGRAM        EQU 2
SOCK_RAW            EQU 3
CALLBAS            EQU 0x10
STACK_BC            EQU $2D2B
PRINT_FP            EQU $2DE3



MODULECALL             equ $3FF8
MODULECALL_NOPAGE    equ $28
PAGEIN                 equ $3FF9
PAGEOUT               equ $007C
HLCALL                equ $3FFA
IXCALL                equ $3FFD

; Port defines
CTRLREG                equ $033B
CPLDINFO               equ $023B

; Jump table entry points
SOCKET                equ $3E00      ; Allocate a socket
CLOSE                 equ $3E03      ; Close a socket
LISTEN               equ $3E06      ; Listen for incoming connections
ACCEPT                 equ $3E09      ; Accept an incoming connection
BIND                equ $3E0C      ; Bind a local address to a socket
CONNECT                equ $3E0F      ; Connect to a remote host
SEND                equ $3E12      ; Send data
RECV                equ $3E15      ; Receive data
SENDTO              equ $3E18      ; Send data to an address
RECVFROM            equ $3E1B      ; Receive data from an address
POLL                equ $3E1E      ; Poll a list of sockets
POLLALL             equ $3E21      ; Poll all open sockets
POLLFD              equ $3E24      ; Poll a single socket
GETHOSTBYNAME       equ $3E27      ; Look up a hostname
PUTCHAR42           equ $3E2A      ; 42 column print write a character
PRINT42             equ $3E2D      ; 42 column print a null terminated string
CLEAR42             equ $3E30      ; Clear the screen and reset 42-col print
SETPAGEA            equ $3E33      ; Sets page area A
SETPAGEB            equ $3E36      ; Sets page area B
LONG2IPSTRING       equ $3E39      ; Convert a 4 byte big endian long to an IP
IPSTRING2LONG       equ $3E3C      ; Convert an IP to a 4 byte big endian long
ITOA8               equ $3E3F      ; Convert a byte to ascii
RAND16              equ $3E42      ; 16 bit PRNG
REMOTEADDRESS       equ $3E45      ; Fill struct sockaddr_in
IFCONFIG_INET       equ $3E48      ; Set IPv4 address
IFCONFIG_NETMASK     equ $3E4B      ; Set netmask
IFCONFIG_GW         equ $3E4E      ; Set gateway
INITHW              equ $3E51      ; Set the MAC address and initial hw registers
GETHWADDR           equ $3E54      ; Read the MAC address
DECONFIG            equ $3E57      ; Deconfigure inet, netmask and gateway
MAC2STRING          equ $3E5A      ; Convert 6 byte MAC address to a string
STRING2MAC          equ $3E5D      ; Convert a hex string to a 6 byte MAC address
ITOH8               equ $3E60      ; Convert accumulator to hex string
HTOI8               equ $3E63      ; Convert hex string to byte in A
GETKEY              equ $3E66      ; Get a key from the keyboard, and put it in A
KEYUP               equ $3E69      ; Wait for key release
INPUTSTRING         equ $3E6C      ; Read a string into buffer at DE
GET_IFCONFIG_INET     equ $3E6F      ; Gets the current IPv4 address
GET_IFCONFIG_NETMASK     equ $3E72      ; Gets the current netmask
GET_IFCONFIG_GW     equ $3E75      ; Gets the current gateway address
SETTRAP                equ $3E78      ; Sets the programmable trap
DISABLETRAP         equ $3E7B      ; Disables the programmable trap
ENABLETRAP          equ $3E7E      ; Enables the programmable trap
PUSHPAGEA           equ $3E81      ; Pages a page into area A, pushing the old one
POPPAGEA            equ $3E84      ; Restores the previous page in area A
PUSHPAGEB           equ $3E87      ; Pages into area B pushing the old one
POPPAGEB            equ $3E8A      ; Restores the previous page in area B
PAGETRAPRETURN      equ $3E8D      ; Returns from a trap to page area B
TRAPRETURN          equ $3E90      ; Returns from a trap that didn't page area B
ADDBASICEXT         equ $3E93      ; Adds a BASIC command
STATEMENT_END       equ $3E96      ; Check for statement end, exit at syntax time
EXIT_SUCCESS        equ $3E99      ; Use this to exit successfully after cmd
PARSE_ERROR         equ $3E9C      ; Use this to exit to BASIC with a parse error
RESERVEPAGE         equ $3E9F      ; Reserve a page of static RAM
FREEPAGE            equ $3EA2      ; Free a page of static RAM
REPORTERR           equ $3EA5      ; report an error via BASIC




connectingMSG:        defm "Connecting..."
                defm 13
end3:                defm 0

allocatingMSG:        defm "Allocating resources..."
                defm 13
end4:                defm 0

connectedMSG:        defm "Connected. "
                defm 13
end5:                defm 0

receivngMSG:        defm "Receiving data."
                defm 13
end6:                defm 0

errorMSG:            defm "Failed."
                defm 13
end7:                defm 0

doneMSG:            defm "Done"
                defm 13
end8:                defm 0

waitingMSG:        defm "I iz waitingz k :p"
                defm 13
end9:                defm 0

crMSG:            defm 13
end10:            defm 0


v_sockfd:            defb 0                  ; storage for socket file descriptor
serverport            equ 16384
serverhost:        defb "the8bitmud.zapto.org"
more:                ds 60
connected:            defb 0                ; 0 means not connected, 1 means connected
ip_buffer:           defb 0, 0, 0, 0            ; leave 4 bytes free for an IP address








garbage:            defm ""
defm 10
garbageend:        defb 0


defm 10
garbageend2:        defb 0

responseBuffer:        ds 1024
responseBufferEnd:    defm 0
garbage2:            defm "ardentcrest"
END ASM

    MyLabel:
    ASM
    text1:
    ds 1024  ;  1024 bytes of space MAX!!
    END ASM


    MyLabel2:
    ASM
    lenth1:
    ds 1  ;  1024 bytes of space MAX!!
    END ASM

I hope you can help, as I feel if it cant be fixed I'm going to have to rework the inkey routine all over again, this time poking it right to memory, and I've no idea how to do that.

Print this item

  Weird DEFB bug (*solved*)
Posted by: einar - 2015-02-22, 04:25 AM - Forum: Bug Reports - Replies (3)

Try running this program:

Code:
GO TO 10

sample:
    asm
       defb "A(B)CD"
    end asm

10  DIM a,i AS UBYTE
    FOR i = 0 TO 5
    LET a=PEEK(@sample+i)
    PRINT a;" '";CHR$(a);"'"
    NEXT i

It was supposed to produce this output:

Code:
65 'A'
40 '('
66 'B'
41 ')'
67 'C'
68 'D'

However it will produce this output instead:

Code:
65 'A'
32 ' '
40 '('
66 'B'
41 ')'
67 'C'

Apparently this extra space (code 32) mysteriously appears whenever there's parenthesis inside a defb string.

Tested using latest version 1.4.0s1902. This problem always happens regardless of optimization level for compilation.

Print this item

  Nexting a For from an IF...THEN
Posted by: ardentcrest - 2015-02-17, 02:36 PM - Forum: Help & Support - Replies (2)

Me again Big Grin

Code:
2004 for xx=length to 1 step -1
2006    if z$(xx)=" " then next xx

Syntax Error. Unexpected token 'NEXT' <NEXT>



Why are the hard thing easy, and what should be easy hard Tongue

Print this item

  Using inkey
Posted by: ardentcrest - 2015-01-20, 03:31 PM - Forum: Help & Support - Replies (13)

Any one know how to do something like this

I'm looking to use inkey$ to create a line of text while the program is doing some other things Ie

LOOP
DO THING 1
INKEY(text string)
DO THING 2
IF ENTER PRINT(text String)
GOTO LOOP

any help on this

Print this item

  SAVE inside SUB freezes the program (*solved*)
Posted by: juanjo - 2015-01-13, 06:59 AM - Forum: Bug Reports - Replies (4)

I'm making a program to print customized labels with the ZX Printer. I was going to make load/save of label data.
The problem is when using SAVE in any of its variants inside a SUB. It freezes after saving is done, and the saved data is different from when the SAVE is done in the 'main block'.

The LOAD command does work inside a SUB.

I don't know if it has some relation to the previous bug report about SAVE:
<!-- l --><a class="postlink-local" href="https://forum.boriel.com/bug-reports/save-bug-solved-t858.html">bug-reports/save-bug-solved-t858.html</a><!-- l -->

Here is a little program that reproduces the error:

Code:
dim variableToSave as uinteger
variableToSave = 1234

sub saveSomething()
    ' This freezes the program AFTER saving is done
    save "test1" DATA variableToSave
    
    ' This freezes the program AFTER saving is done and shows a funny "demo"
    'save "test1" screen$
end sub

sub waitForAKey()

    while inkey$=""
    end while
    
    while inkey$<>""
    end while

end sub


print "Press any key to start save..."
waitForAKey()

saveSomething()

'This works (in the main block)
'save "test1" DATA variableToSave

print "Save done. Press any key to continue..."
waitForAKey()

' Do some random stuff (the Spectrum freezes before reaching here):
dim i as uinteger
i = 2 + 2
print "i = "; i

print "Press any key to exit..."
waitForAKey()

Print this item

  [pv1000] Simon
Posted by: nitrofurano - 2015-01-06, 03:24 PM - Forum: Other Archs - Replies (6)

the first game i'm coding for Casio PV1000, adapting a type-in code from MicroHobby magazine



Attached Files
.zip   simon_pv1000.zip (Size: 48.26 KB / Downloads: 1294)
Print this item

  Array initialization bug (*solved*)
Posted by: einar - 2014-12-23, 03:28 AM - Forum: Bug Reports - Replies (8)

My next ZX BASIC game requires a lookup table for variable sized data.

The simplest solution would be something like this:

Code:
data1:
    asm
        defb 0,1,2,3,4,5
    end asm
data2:
    asm
        defb 6,7,8
    end asm
data3:
    asm
        defb 9,10,11,12
    end asm

DIM array(1 TO 3) AS UINTEGER = { @data1, @data2, @data3 }

But compiling this program using latest version of ZX BASIC (incorrectly) produces the following error messages:

Code:
prog.bas:14: Initializer expression is not constant.
prog.bas:14: Initializer expression is not constant.
prog.bas:14: Initializer expression is not constant.

Another alternative would be declaring the lookup table directly in ASM, but ZX BASIC doesn't support mapping arrays to memory addresses either:

Code:
DIM array(1 TO 3) AS UINTEGER AT @data

For now, I'm implementing everything "manually" instead of using ZX BASIC arrays. But it would be nice if this problem could be fixed in future releases! Smile

Print this item

  [pv1000] first test
Posted by: nitrofurano - 2014-12-19, 03:17 PM - Forum: Other Archs - Replies (3)

first test for the Casio PV-1000 game console - i still don’t know how the joystick works



Attached Files
.zip   example01d_io_notworking.zip (Size: 29.73 KB / Downloads: 1084)
Print this item

  [capcom-vulgus] first test
Posted by: nitrofurano - 2014-11-20, 06:39 PM - Forum: Other Archs - Replies (1)

first test for the Capcom’s Vulgus arcade machine
( the wiki page related to this thread is at <!-- m --><a class="postlink" href="http://www.boriel.com/wiki/en/index.php/ZX_BASIC:Released_Programs_-_CapcomVulgus">http://www.boriel.com/wiki/en/index.php ... pcomVulgus</a><!-- m --> )



Attached Files
.zip   example01f_working.zip (Size: 130.98 KB / Downloads: 1235)
Print this item

  [zx81] first test (not working yet)
Posted by: nitrofurano - 2014-11-16, 05:22 PM - Forum: Other Archs - No Replies

first test for ZX81 - it shows something, but i really have no idea what is wrong there - stack and variables area? bios routines call? something that might be missing?



Attached Files
.zip   example01f.zip (Size: 12.82 KB / Downloads: 1037)
Print this item