<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
		<title><![CDATA[Boriel Basic Forum - Portal]]></title>
		<link>https://forum.boriel.com/</link>
		<description><![CDATA[Boriel Basic Forum - https://forum.boriel.com]]></description>
		<pubDate>Tue, 07 Jul 2026 07:17:43 +0000</pubDate>
		<generator>MyBB</generator>
		<item>
			<title><![CDATA[GuSprites]]></title>
			<link>https://forum.boriel.com/showthread.php?tid=2655</link>
			<pubDate>Sat, 13 Jun 2026 08:36:59 +0000</pubDate>
			<dc:creator><![CDATA[<a href="https://forum.boriel.com/member.php?action=profile&uid=2220">zedex82</a>]]></dc:creator>
			<guid isPermaLink="false">https://forum.boriel.com/showthread.php?tid=2655</guid>
			<description><![CDATA[After a little while away from Boriel and am returning to it. I have been looking at GuSprites, but the documentation is limited. Is there any tutorials or documentation that would help a beginner?]]></description>
			<content:encoded><![CDATA[After a little while away from Boriel and am returning to it. I have been looking at GuSprites, but the documentation is limited. Is there any tutorials or documentation that would help a beginner?]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[New video Couse / Nuevo curso en vídeo]]></title>
			<link>https://forum.boriel.com/showthread.php?tid=2654</link>
			<pubDate>Wed, 29 Apr 2026 22:02:22 +0000</pubDate>
			<dc:creator><![CDATA[<a href="https://forum.boriel.com/member.php?action=profile&uid=239">Duefectu</a>]]></dc:creator>
			<guid isPermaLink="false">https://forum.boriel.com/showthread.php?tid=2654</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">English</span><br />
I’m creating a video course on Boriel Basic.<br />
You can find it at: <a href="https://youtu.be/nBo3eu4XNFY?si=uo7Nz9DhEAToEdNE" target="_blank" rel="noopener" class="mycode_url">https://youtu.be/nBo3eu4XNFY?si=uo7Nz9DhEAToEdNE</a><br />
<br />
-------------------------------------------------------------------<br />
<span style="font-weight: bold;" class="mycode_b">Español</span><br />
Estoy creando un curso de Boriel Basic en vídeo.<br />
Lo tenéis disponible en: <a href="https://youtu.be/8AkYffB--bk?si=eL9yz9oPLpi6y0wE" target="_blank" rel="noopener" class="mycode_url">https://youtu.be/8AkYffB--bk?si=eL9yz9oPLpi6y0wE</a>]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">English</span><br />
I’m creating a video course on Boriel Basic.<br />
You can find it at: <a href="https://youtu.be/nBo3eu4XNFY?si=uo7Nz9DhEAToEdNE" target="_blank" rel="noopener" class="mycode_url">https://youtu.be/nBo3eu4XNFY?si=uo7Nz9DhEAToEdNE</a><br />
<br />
-------------------------------------------------------------------<br />
<span style="font-weight: bold;" class="mycode_b">Español</span><br />
Estoy creando un curso de Boriel Basic en vídeo.<br />
Lo tenéis disponible en: <a href="https://youtu.be/8AkYffB--bk?si=eL9yz9oPLpi6y0wE" target="_blank" rel="noopener" class="mycode_url">https://youtu.be/8AkYffB--bk?si=eL9yz9oPLpi6y0wE</a>]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[location of heap management code...]]></title>
			<link>https://forum.boriel.com/showthread.php?tid=2652</link>
			<pubDate>Tue, 24 Feb 2026 13:17:50 +0000</pubDate>
			<dc:creator><![CDATA[<a href="https://forum.boriel.com/member.php?action=profile&uid=2568">sdo303</a>]]></dc:creator>
			<guid isPermaLink="false">https://forum.boriel.com/showthread.php?tid=2652</guid>
			<description><![CDATA[I'd like to use strings and arrays in my paged code, but I seem to have reached a blockage whereby, even though my paged-code looks like:<br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>#PRAGMA push(case_insensitive)
#PRAGMA case_insensitive = True
#define STANDALONE  ' remove ROM initialization and SysVars...

Asm
    org &#36;6000
    di
End Asm
s_stage_init()
Asm
    ret
End Asm


#include "constants.bas"
#include "globals.bas"
#include "stage-include.bas"


Sub s_init_keyboard_table_ZX_keys()
    ' effect: populates the lookup table for the 40-key spectrum matrix
    ' row 0: port &#36;FEFE
    gub_zxkeys(0)  = 0   ' caps shift
'...
    gub_zxkeys(55) = 127 ' delete (standard)
End Sub


Sub s_init_keyboard_table_ZX_symkeys()
    ' row 0: z, x, c, v
    gub_zxsymkeys(1)  = 58  ' :
'...
    gub_zxsymkeys(55) = 127 ' delete (standard)
End Sub


Sub s_init_title_screen()
    ' footer prompt
    s_print_string_at( 28, 21, "Press any key to begin..."  , UB_BRIGHT_YELLOW )

    ' wait for player input
    s_get_key()
    ' check if the one-hour timeout occurred
    If guw_key_code = 0 Then gub_core_end = true
End Sub


Sub s_stage_init()
    s_init_keyboard_table_ZX_keys()
    s_init_keyboard_table_ZX_symkeys()

    s_init_title_screen()
End Sub</code></div></div><br />
and when I compile with :<br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>python &#36;Compiler "&#36;(&#36;Name).bas" -f bin -o "&#36;(&#36;Name).bin" --org 24576 -W150 --headerless --explicit --strict --zxnext -i --arch zxnext --opt-strategy size --heap-address 32000 --heap-size 767 -M "&#36;(&#36;Name).map"</code></div></div><br />
then I still seem to end up with some kind of header code that makes  a call to &#36;46A4...<br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>&gt;6001  CALL 46A4        PC  6001
 6004  NOP              SP  FFFA
 6005  NOP              AF  FFFF'3C40
 6006  NOP              SZ5H3PNC
 6007  NOP              HL  0001'3C44
 6008  NOP              DE  0000'FFFF
 6009  NOP              BC  0000'5393
 600A  LD BC, 6013      IX  FFF1
 600D  EX AF, AF'       IY  EFF3
 600E  LD B, A          IR  001B
 600F  NOP              IM1 IFF--
 6010  NOP              (HL) F3 00
 6011  NOP              (DE) 00 F3
                        (BC) 00 F3

(SP) 0C3C 010B 0000 F300 C300 0</code></div></div><br />
which I think must be some kind of heap management setup...<br />
<br />
...so please may I ask...<br />
<br />
Is there a compiler switch or directive whereby I can get the heap management code tacked on just after my code ends, so that I can have private heap management per 8KB segment of paged code ?<br />
<br />
Thank you.]]></description>
			<content:encoded><![CDATA[I'd like to use strings and arrays in my paged code, but I seem to have reached a blockage whereby, even though my paged-code looks like:<br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>#PRAGMA push(case_insensitive)
#PRAGMA case_insensitive = True
#define STANDALONE  ' remove ROM initialization and SysVars...

Asm
    org &#36;6000
    di
End Asm
s_stage_init()
Asm
    ret
End Asm


#include "constants.bas"
#include "globals.bas"
#include "stage-include.bas"


Sub s_init_keyboard_table_ZX_keys()
    ' effect: populates the lookup table for the 40-key spectrum matrix
    ' row 0: port &#36;FEFE
    gub_zxkeys(0)  = 0   ' caps shift
'...
    gub_zxkeys(55) = 127 ' delete (standard)
End Sub


Sub s_init_keyboard_table_ZX_symkeys()
    ' row 0: z, x, c, v
    gub_zxsymkeys(1)  = 58  ' :
'...
    gub_zxsymkeys(55) = 127 ' delete (standard)
End Sub


Sub s_init_title_screen()
    ' footer prompt
    s_print_string_at( 28, 21, "Press any key to begin..."  , UB_BRIGHT_YELLOW )

    ' wait for player input
    s_get_key()
    ' check if the one-hour timeout occurred
    If guw_key_code = 0 Then gub_core_end = true
End Sub


Sub s_stage_init()
    s_init_keyboard_table_ZX_keys()
    s_init_keyboard_table_ZX_symkeys()

    s_init_title_screen()
End Sub</code></div></div><br />
and when I compile with :<br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>python &#36;Compiler "&#36;(&#36;Name).bas" -f bin -o "&#36;(&#36;Name).bin" --org 24576 -W150 --headerless --explicit --strict --zxnext -i --arch zxnext --opt-strategy size --heap-address 32000 --heap-size 767 -M "&#36;(&#36;Name).map"</code></div></div><br />
then I still seem to end up with some kind of header code that makes  a call to &#36;46A4...<br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>&gt;6001  CALL 46A4        PC  6001
 6004  NOP              SP  FFFA
 6005  NOP              AF  FFFF'3C40
 6006  NOP              SZ5H3PNC
 6007  NOP              HL  0001'3C44
 6008  NOP              DE  0000'FFFF
 6009  NOP              BC  0000'5393
 600A  LD BC, 6013      IX  FFF1
 600D  EX AF, AF'       IY  EFF3
 600E  LD B, A          IR  001B
 600F  NOP              IM1 IFF--
 6010  NOP              (HL) F3 00
 6011  NOP              (DE) 00 F3
                        (BC) 00 F3

(SP) 0C3C 010B 0000 F300 C300 0</code></div></div><br />
which I think must be some kind of heap management setup...<br />
<br />
...so please may I ask...<br />
<br />
Is there a compiler switch or directive whereby I can get the heap management code tacked on just after my code ends, so that I can have private heap management per 8KB segment of paged code ?<br />
<br />
Thank you.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[non-paged supervisor code calling paged application code]]></title>
			<link>https://forum.boriel.com/showthread.php?tid=2651</link>
			<pubDate>Sun, 15 Feb 2026 15:01:23 +0000</pubDate>
			<dc:creator><![CDATA[<a href="https://forum.boriel.com/member.php?action=profile&uid=2568">sdo303</a>]]></dc:creator>
			<guid isPermaLink="false">https://forum.boriel.com/showthread.php?tid=2651</guid>
			<description><![CDATA[Firstly, a proper thankyou to Boriel for the compiler.   And secondly, also a proper thankyou to Duefectu for the beginner's guide book (I bought a hard copy), which I have read cover to cover (but I did skip the sound/audio sections <img src="https://forum.boriel.com/images/smilies/smile.png" alt="Smile" title="Smile" class="smilie smilie_1" />).  And I bought a hard copy of Simon G's NextTech book too, again I have read it cover to cover (but skipped the sound/audio parts).<br />
<br />
Using Boriel ZXBasic and as little Z80 machine code as I can get away with (until I need to performance tune)... my project is that I am trying to write a quasi "character cell" based application, like being on an old VT100, whereby the application uses all 64KB of the Z80 for itself, and thus no ZX Spectrum ROM, and which internally leverages a poor man's virtual memory framework, whereby I have a supervisor layer of non-paged code running in MMU0/1, which boots from &#36;0000 and jumps over IM1 at &#36;0038 to begin my main code properly at say &#36;0050 where the application begins properly... and so I have my core non-paged system variables mapped in MMU2 and then I have my paged code to run from MMU3 - and then various different aspects of paged application data paging in and out MMU4/5/6, with finally MMU7 again being static non-paged to host the 5KB of screen tile map for an 80x32 screen, with the final 3KB of MMU7 being available for the stack pointer from &#36;FFFE downwards.<br />
phew...<br />
I know my code will never work first time, I get that... but I feel fairly sure that I have the basic (excuse the pun) initial structure of what I want to achieve, with all of my system variables (so far identified) defined at static addresses in MMU2, and my main supervisor MMU paging and also my screen updating routines and keyboard reading routines written (to be permanently resident in MMU0/1) and the first of my paged blocks of code to run from MMU3, and I have gotten the source code clean enough pass through zxbc without the compiler spitting any hard errors... (just lots and lots of warnings)... but I've now hit a roadblock...<br />
<br />
I get how I can have many separate pages of 8KB deposited across the ZX Next vast 200+ pages of 8KB across 1.75 MB of RAM, and I get how I can have my code paged in at MMU3 for my application to execute from &#36;6000, and I can get my non-paged supervisor layer code to make calls such as       uw_dummy = USR &#36;6000     to call my paged code in MMU3, and thus wait for a return... but what I don't understand is how I can have many different paged code blocks where each is aware of *ALL* of the available core supervisor routines and their parameter structures and thus able to makes calls back in to the supervisor to run any of the many core system routines...<br />
<br />
i.e. how can I make zxbc firstly compile the application core without dropping routines that zxbc thinks are unused, and yet also somehow get the compilations of many different "paged" application code to be aware of the core supervisor routines and their parameters and any return value data types (of functions).<br />
<br />
e.g. I get this from my compilation of my "core.bas":<br />
core.bas:115: warning: [W170] Function 's_crash' is never called and has been ignored<br />
core.bas:154: warning: [W170] Function 's_fc_ram_copy' is never called and has been ignored<br />
core.bas:165: warning: [W170] Function 's_clear_screen' is never called and has been ignored<br />
core.bas:126: warning: [W170] Function 's_print_char_at' is never called and has been ignored<br />
core.bas:143: warning: [W170] Function 's_print_string_at' is never called and has been ignored<br />
core.bas:217: warning: [W170] Function 's_display_monitor' is never called and has been ignored<br />
core.bas:283: warning: [W170] Function 'fub_key_get_minutes' is never called and has been ignored<br />
<br />
...and I get this for my first stage of my application:<br />
stage-include.bas:37: warning: [W170] Function 's_next_reg' is never called and has been ignored<br />
stage-include.bas:38: warning: [W170] Function 's_return_to_zxos' is never called and has been ignored<br />
stage-include.bas:39: warning: [W170] Function 's_crash' is never called and has been ignored<br />
stage-include.bas:40: warning: [W170] Function 's_fc_ram_copy' is never called and has been ignored<br />
stage-include.bas:42: warning: [W170] Function 's_clear_screen' is never called and has been ignored<br />
stage-include.bas:43: warning: [W170] Function 's_print_char_at' is never called and has been ignored<br />
stage-include.bas:44: warning: [W170] Function 's_print_string_at' is never called and has been ignored<br />
stage-include.bas:45: warning: [W170] Function 's_display_monitor' is never called and has been ignored<br />
stage-include.bas:47: warning: [W170] Function 'fub_key_get_minutes' is never called and has been ignored<br />
stage-include.bas:48: warning: [W170] Function 's_key_wait_for_vblank' is never called and has been ignored<br />
stage-include.bas:49: warning: [W170] Function 's_get_key' is never called and has been ignored<br />
...<br />
stage-init.bas:8: warning: [W170] Function 's_stage_init' is never called and has been ignored<br />
stage-init.bas:20: warning: [W170] Function 's_init_keyboard_table_ZX_keys' is never called and has been ignored<br />
stage-init.bas:21: warning: [W170] Function 's_init_keyboard_table_ZX_symkeys' is never called and has been ignored<br />
stage-init.bas:18: warning: [W170] Function 's_init_load_palette' is never called and has been ignored<br />
stage-init.bas:186: warning: [W170] Function 's_init_load_palette_entry' is never called and has been ignored<br />
stage-init.bas:223: warning: [W170] Function 's_init_clear_screen' is never called and has been ignored<br />
stage-init.bas:26: warning: [W170] Function 's_init_title_screen' is never called and has been ignored<br />
<br />
...where stage-include.bas was my attempt to make each "stage" aware of a jump-table of locations of core routines:<br />
<span style="color: #cccccc;" class="mycode_color"><span style="font-family: Consolas, 'Courier New', monospace;" class="mycode_font"><span style="color: #c586c0;" class="mycode_color">Asm</span><br />
    ; fixed jump table addresses <span style="color: #ce9178;" class="mycode_color">for</span> the linker<br />
    _s_main                          equ &#36;0050<br />
    _s_next_reg                      equ &#36;0053<br />
    _s_return_to_zxos                equ &#36;0056<br />
    _s_crash                         equ &#36;0059<br />
    _s_fc_ram_copy                   equ &#36;005C<br />
    _s_clear_screen                  equ &#36;005F<br />
    _s_print_char_at                 equ &#36;0062<br />
    _s_print_<span style="color: #b5cea8;" class="mycode_color">string</span>_at               equ &#36;0065<br />
    _s_display_monitor               equ &#36;0068<br />
    _fub_key_get_minutes             equ &#36;006B<br />
    _s_key_wait_for_vblank           equ &#36;006E<br />
    _s_get_key                       equ &#36;0071<br />
<span style="color: #c586c0;" class="mycode_color">End Asm</span></span></span><br />
<span style="font-family: Consolas, 'Courier New', monospace;" class="mycode_font"><br />
<span style="color: #6a9955;" class="mycode_color"><span style="color: #6a9955;" class="mycode_color">' implementation blocks to stop "not implemented" errors</span></span><br />
<span style="color: #6a9955;" class="mycode_color"><span style="color: #6a9955;" class="mycode_color">' these contain no code; the equate above handles the address</span></span><br />
<span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span> <span style="color: #dcdcaa;" class="mycode_color"><span style="color: #dcdcaa;" class="mycode_color">s_main</span></span><span style="color: #cccccc;" class="mycode_color">(): </span><span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">End</span></span> <span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span><br />
<span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span> <span style="color: #dcdcaa;" class="mycode_color"><span style="color: #dcdcaa;" class="mycode_color">s_next_reg</span></span><span style="color: #cccccc;" class="mycode_color">(reg As </span><span style="color: #b5cea8;" class="mycode_color"><span style="color: #b5cea8;" class="mycode_color">UByte</span></span><span style="color: #cccccc;" class="mycode_color">, </span><span style="color: #9cdcfe;" class="mycode_color"><span style="color: #9cdcfe;" class="mycode_color">value</span></span><span style="color: #cccccc;" class="mycode_color"> As </span><span style="color: #b5cea8;" class="mycode_color"><span style="color: #b5cea8;" class="mycode_color">UByte</span></span><span style="color: #cccccc;" class="mycode_color">): </span><span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">End</span></span> <span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span><br />
<span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span> <span style="color: #dcdcaa;" class="mycode_color"><span style="color: #dcdcaa;" class="mycode_color">s_return_to_zxos</span></span><span style="color: #cccccc;" class="mycode_color">(): </span><span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">End</span></span> <span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span><br />
<span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span> <span style="color: #dcdcaa;" class="mycode_color"><span style="color: #dcdcaa;" class="mycode_color">s_crash</span></span><span style="color: #cccccc;" class="mycode_color">(</span><span style="color: #9cdcfe;" class="mycode_color"><span style="color: #9cdcfe;" class="mycode_color">error_code</span></span><span style="color: #cccccc;" class="mycode_color"> As </span><span style="color: #b5cea8;" class="mycode_color"><span style="color: #b5cea8;" class="mycode_color">UByte</span></span><span style="color: #cccccc;" class="mycode_color">, </span><span style="color: #9cdcfe;" class="mycode_color"><span style="color: #9cdcfe;" class="mycode_color">error_text</span></span><span style="color: #cccccc;" class="mycode_color"> As </span><span style="color: #b5cea8;" class="mycode_color"><span style="color: #b5cea8;" class="mycode_color">String</span></span><span style="color: #cccccc;" class="mycode_color">): </span><span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">End</span></span> <span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span><br />
<span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span> <span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Fastcall</span></span><span style="color: #cccccc;" class="mycode_color"> s_fc_ram_copy(src_address </span><span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">As</span></span><span style="color: #cccccc;" class="mycode_color"> UInteger, dest_address </span><span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">As</span></span><span style="color: #cccccc;" class="mycode_color"> UInteger, byte_count </span><span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">As</span></span><span style="color: #cccccc;" class="mycode_color"> UInteger): </span><span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">End</span></span> <span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span><br />
<span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span> <span style="color: #dcdcaa;" class="mycode_color"><span style="color: #dcdcaa;" class="mycode_color">s_clear_screen</span></span><span style="color: #cccccc;" class="mycode_color">(): </span><span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">End</span></span> <span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span><br />
<span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span> <span style="color: #dcdcaa;" class="mycode_color"><span style="color: #dcdcaa;" class="mycode_color">s_print_char_at</span></span><span style="color: #cccccc;" class="mycode_color">(</span><span style="color: #9cdcfe;" class="mycode_color"><span style="color: #9cdcfe;" class="mycode_color">x</span></span><span style="color: #cccccc;" class="mycode_color"> As </span><span style="color: #b5cea8;" class="mycode_color"><span style="color: #b5cea8;" class="mycode_color">UByte</span></span><span style="color: #cccccc;" class="mycode_color">, </span><span style="color: #9cdcfe;" class="mycode_color"><span style="color: #9cdcfe;" class="mycode_color">y</span></span><span style="color: #cccccc;" class="mycode_color"> As </span><span style="color: #b5cea8;" class="mycode_color"><span style="color: #b5cea8;" class="mycode_color">UByte</span></span><span style="color: #cccccc;" class="mycode_color">, </span><span style="color: #9cdcfe;" class="mycode_color"><span style="color: #9cdcfe;" class="mycode_color">char</span></span><span style="color: #cccccc;" class="mycode_color"> As </span><span style="color: #b5cea8;" class="mycode_color"><span style="color: #b5cea8;" class="mycode_color">UByte</span></span><span style="color: #cccccc;" class="mycode_color">, </span><span style="color: #9cdcfe;" class="mycode_color"><span style="color: #9cdcfe;" class="mycode_color">colour</span></span><span style="color: #cccccc;" class="mycode_color"> As </span><span style="color: #b5cea8;" class="mycode_color"><span style="color: #b5cea8;" class="mycode_color">UByte</span></span><span style="color: #cccccc;" class="mycode_color">): </span><span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">End</span></span> <span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span><br />
<span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span> <span style="color: #dcdcaa;" class="mycode_color"><span style="color: #dcdcaa;" class="mycode_color">s_print_string_at</span></span><span style="color: #cccccc;" class="mycode_color">(</span><span style="color: #9cdcfe;" class="mycode_color"><span style="color: #9cdcfe;" class="mycode_color">x</span></span><span style="color: #cccccc;" class="mycode_color"> As </span><span style="color: #b5cea8;" class="mycode_color"><span style="color: #b5cea8;" class="mycode_color">UByte</span></span><span style="color: #cccccc;" class="mycode_color">, </span><span style="color: #9cdcfe;" class="mycode_color"><span style="color: #9cdcfe;" class="mycode_color">y</span></span><span style="color: #cccccc;" class="mycode_color"> As </span><span style="color: #b5cea8;" class="mycode_color"><span style="color: #b5cea8;" class="mycode_color">UByte</span></span><span style="color: #cccccc;" class="mycode_color">, </span><span style="color: #9cdcfe;" class="mycode_color"><span style="color: #9cdcfe;" class="mycode_color">text</span></span><span style="color: #cccccc;" class="mycode_color"> As </span><span style="color: #b5cea8;" class="mycode_color"><span style="color: #b5cea8;" class="mycode_color">String</span></span><span style="color: #cccccc;" class="mycode_color">, </span><span style="color: #9cdcfe;" class="mycode_color"><span style="color: #9cdcfe;" class="mycode_color">colour</span></span><span style="color: #cccccc;" class="mycode_color"> As </span><span style="color: #b5cea8;" class="mycode_color"><span style="color: #b5cea8;" class="mycode_color">UByte</span></span><span style="color: #cccccc;" class="mycode_color">): </span><span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">End</span></span> <span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span><br />
<span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span> <span style="color: #dcdcaa;" class="mycode_color"><span style="color: #dcdcaa;" class="mycode_color">s_display_monitor</span></span><span style="color: #cccccc;" class="mycode_color">(): </span><span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">End</span></span> <span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span><br />
<span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Function</span></span> <span style="color: #dcdcaa;" class="mycode_color"><span style="color: #dcdcaa;" class="mycode_color">fub_key_get_minutes</span></span><span style="color: #cccccc;" class="mycode_color">() As </span><span style="color: #b5cea8;" class="mycode_color"><span style="color: #b5cea8;" class="mycode_color">UByte</span></span><span style="color: #cccccc;" class="mycode_color">: </span><span style="color: #ce9178;" class="mycode_color"><span style="color: #ce9178;" class="mycode_color">return</span></span><span style="color: #cccccc;" class="mycode_color"> 0: </span><span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">End</span></span> <span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Function</span></span><br />
<span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span> <span style="color: #dcdcaa;" class="mycode_color"><span style="color: #dcdcaa;" class="mycode_color">s_key_wait_for_vblank</span></span><span style="color: #cccccc;" class="mycode_color">(): </span><span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">End</span></span> <span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span><br />
<span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span> <span style="color: #dcdcaa;" class="mycode_color"><span style="color: #dcdcaa;" class="mycode_color">s_get_key</span></span><span style="color: #cccccc;" class="mycode_color">(): </span><span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">End</span></span> <span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span></span><br />
<br />
<br />
But clearly there is something I'm not getting, and I've reached the limits of capability of AI helper tools.<br />
<br />
I had rationalised to myself that my build script should only call to zxbc to produce "-f asm" ASM files... as I expect to have to then somehow "link" the static core ASM and the many paged stage ASM together at some point... and I also seem to have rationalised that I may perhaps need to use     sjasmplus     to assemble my ".nex" package.<br />
<br />
Does the above sound achievable?  Or am I asking too much of the "Next" as a platform?  i.e. is the "Next" only any good for paging graphics data, and no good for paging application code?]]></description>
			<content:encoded><![CDATA[Firstly, a proper thankyou to Boriel for the compiler.   And secondly, also a proper thankyou to Duefectu for the beginner's guide book (I bought a hard copy), which I have read cover to cover (but I did skip the sound/audio sections <img src="https://forum.boriel.com/images/smilies/smile.png" alt="Smile" title="Smile" class="smilie smilie_1" />).  And I bought a hard copy of Simon G's NextTech book too, again I have read it cover to cover (but skipped the sound/audio parts).<br />
<br />
Using Boriel ZXBasic and as little Z80 machine code as I can get away with (until I need to performance tune)... my project is that I am trying to write a quasi "character cell" based application, like being on an old VT100, whereby the application uses all 64KB of the Z80 for itself, and thus no ZX Spectrum ROM, and which internally leverages a poor man's virtual memory framework, whereby I have a supervisor layer of non-paged code running in MMU0/1, which boots from &#36;0000 and jumps over IM1 at &#36;0038 to begin my main code properly at say &#36;0050 where the application begins properly... and so I have my core non-paged system variables mapped in MMU2 and then I have my paged code to run from MMU3 - and then various different aspects of paged application data paging in and out MMU4/5/6, with finally MMU7 again being static non-paged to host the 5KB of screen tile map for an 80x32 screen, with the final 3KB of MMU7 being available for the stack pointer from &#36;FFFE downwards.<br />
phew...<br />
I know my code will never work first time, I get that... but I feel fairly sure that I have the basic (excuse the pun) initial structure of what I want to achieve, with all of my system variables (so far identified) defined at static addresses in MMU2, and my main supervisor MMU paging and also my screen updating routines and keyboard reading routines written (to be permanently resident in MMU0/1) and the first of my paged blocks of code to run from MMU3, and I have gotten the source code clean enough pass through zxbc without the compiler spitting any hard errors... (just lots and lots of warnings)... but I've now hit a roadblock...<br />
<br />
I get how I can have many separate pages of 8KB deposited across the ZX Next vast 200+ pages of 8KB across 1.75 MB of RAM, and I get how I can have my code paged in at MMU3 for my application to execute from &#36;6000, and I can get my non-paged supervisor layer code to make calls such as       uw_dummy = USR &#36;6000     to call my paged code in MMU3, and thus wait for a return... but what I don't understand is how I can have many different paged code blocks where each is aware of *ALL* of the available core supervisor routines and their parameter structures and thus able to makes calls back in to the supervisor to run any of the many core system routines...<br />
<br />
i.e. how can I make zxbc firstly compile the application core without dropping routines that zxbc thinks are unused, and yet also somehow get the compilations of many different "paged" application code to be aware of the core supervisor routines and their parameters and any return value data types (of functions).<br />
<br />
e.g. I get this from my compilation of my "core.bas":<br />
core.bas:115: warning: [W170] Function 's_crash' is never called and has been ignored<br />
core.bas:154: warning: [W170] Function 's_fc_ram_copy' is never called and has been ignored<br />
core.bas:165: warning: [W170] Function 's_clear_screen' is never called and has been ignored<br />
core.bas:126: warning: [W170] Function 's_print_char_at' is never called and has been ignored<br />
core.bas:143: warning: [W170] Function 's_print_string_at' is never called and has been ignored<br />
core.bas:217: warning: [W170] Function 's_display_monitor' is never called and has been ignored<br />
core.bas:283: warning: [W170] Function 'fub_key_get_minutes' is never called and has been ignored<br />
<br />
...and I get this for my first stage of my application:<br />
stage-include.bas:37: warning: [W170] Function 's_next_reg' is never called and has been ignored<br />
stage-include.bas:38: warning: [W170] Function 's_return_to_zxos' is never called and has been ignored<br />
stage-include.bas:39: warning: [W170] Function 's_crash' is never called and has been ignored<br />
stage-include.bas:40: warning: [W170] Function 's_fc_ram_copy' is never called and has been ignored<br />
stage-include.bas:42: warning: [W170] Function 's_clear_screen' is never called and has been ignored<br />
stage-include.bas:43: warning: [W170] Function 's_print_char_at' is never called and has been ignored<br />
stage-include.bas:44: warning: [W170] Function 's_print_string_at' is never called and has been ignored<br />
stage-include.bas:45: warning: [W170] Function 's_display_monitor' is never called and has been ignored<br />
stage-include.bas:47: warning: [W170] Function 'fub_key_get_minutes' is never called and has been ignored<br />
stage-include.bas:48: warning: [W170] Function 's_key_wait_for_vblank' is never called and has been ignored<br />
stage-include.bas:49: warning: [W170] Function 's_get_key' is never called and has been ignored<br />
...<br />
stage-init.bas:8: warning: [W170] Function 's_stage_init' is never called and has been ignored<br />
stage-init.bas:20: warning: [W170] Function 's_init_keyboard_table_ZX_keys' is never called and has been ignored<br />
stage-init.bas:21: warning: [W170] Function 's_init_keyboard_table_ZX_symkeys' is never called and has been ignored<br />
stage-init.bas:18: warning: [W170] Function 's_init_load_palette' is never called and has been ignored<br />
stage-init.bas:186: warning: [W170] Function 's_init_load_palette_entry' is never called and has been ignored<br />
stage-init.bas:223: warning: [W170] Function 's_init_clear_screen' is never called and has been ignored<br />
stage-init.bas:26: warning: [W170] Function 's_init_title_screen' is never called and has been ignored<br />
<br />
...where stage-include.bas was my attempt to make each "stage" aware of a jump-table of locations of core routines:<br />
<span style="color: #cccccc;" class="mycode_color"><span style="font-family: Consolas, 'Courier New', monospace;" class="mycode_font"><span style="color: #c586c0;" class="mycode_color">Asm</span><br />
    ; fixed jump table addresses <span style="color: #ce9178;" class="mycode_color">for</span> the linker<br />
    _s_main                          equ &#36;0050<br />
    _s_next_reg                      equ &#36;0053<br />
    _s_return_to_zxos                equ &#36;0056<br />
    _s_crash                         equ &#36;0059<br />
    _s_fc_ram_copy                   equ &#36;005C<br />
    _s_clear_screen                  equ &#36;005F<br />
    _s_print_char_at                 equ &#36;0062<br />
    _s_print_<span style="color: #b5cea8;" class="mycode_color">string</span>_at               equ &#36;0065<br />
    _s_display_monitor               equ &#36;0068<br />
    _fub_key_get_minutes             equ &#36;006B<br />
    _s_key_wait_for_vblank           equ &#36;006E<br />
    _s_get_key                       equ &#36;0071<br />
<span style="color: #c586c0;" class="mycode_color">End Asm</span></span></span><br />
<span style="font-family: Consolas, 'Courier New', monospace;" class="mycode_font"><br />
<span style="color: #6a9955;" class="mycode_color"><span style="color: #6a9955;" class="mycode_color">' implementation blocks to stop "not implemented" errors</span></span><br />
<span style="color: #6a9955;" class="mycode_color"><span style="color: #6a9955;" class="mycode_color">' these contain no code; the equate above handles the address</span></span><br />
<span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span> <span style="color: #dcdcaa;" class="mycode_color"><span style="color: #dcdcaa;" class="mycode_color">s_main</span></span><span style="color: #cccccc;" class="mycode_color">(): </span><span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">End</span></span> <span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span><br />
<span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span> <span style="color: #dcdcaa;" class="mycode_color"><span style="color: #dcdcaa;" class="mycode_color">s_next_reg</span></span><span style="color: #cccccc;" class="mycode_color">(reg As </span><span style="color: #b5cea8;" class="mycode_color"><span style="color: #b5cea8;" class="mycode_color">UByte</span></span><span style="color: #cccccc;" class="mycode_color">, </span><span style="color: #9cdcfe;" class="mycode_color"><span style="color: #9cdcfe;" class="mycode_color">value</span></span><span style="color: #cccccc;" class="mycode_color"> As </span><span style="color: #b5cea8;" class="mycode_color"><span style="color: #b5cea8;" class="mycode_color">UByte</span></span><span style="color: #cccccc;" class="mycode_color">): </span><span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">End</span></span> <span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span><br />
<span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span> <span style="color: #dcdcaa;" class="mycode_color"><span style="color: #dcdcaa;" class="mycode_color">s_return_to_zxos</span></span><span style="color: #cccccc;" class="mycode_color">(): </span><span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">End</span></span> <span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span><br />
<span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span> <span style="color: #dcdcaa;" class="mycode_color"><span style="color: #dcdcaa;" class="mycode_color">s_crash</span></span><span style="color: #cccccc;" class="mycode_color">(</span><span style="color: #9cdcfe;" class="mycode_color"><span style="color: #9cdcfe;" class="mycode_color">error_code</span></span><span style="color: #cccccc;" class="mycode_color"> As </span><span style="color: #b5cea8;" class="mycode_color"><span style="color: #b5cea8;" class="mycode_color">UByte</span></span><span style="color: #cccccc;" class="mycode_color">, </span><span style="color: #9cdcfe;" class="mycode_color"><span style="color: #9cdcfe;" class="mycode_color">error_text</span></span><span style="color: #cccccc;" class="mycode_color"> As </span><span style="color: #b5cea8;" class="mycode_color"><span style="color: #b5cea8;" class="mycode_color">String</span></span><span style="color: #cccccc;" class="mycode_color">): </span><span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">End</span></span> <span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span><br />
<span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span> <span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Fastcall</span></span><span style="color: #cccccc;" class="mycode_color"> s_fc_ram_copy(src_address </span><span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">As</span></span><span style="color: #cccccc;" class="mycode_color"> UInteger, dest_address </span><span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">As</span></span><span style="color: #cccccc;" class="mycode_color"> UInteger, byte_count </span><span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">As</span></span><span style="color: #cccccc;" class="mycode_color"> UInteger): </span><span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">End</span></span> <span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span><br />
<span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span> <span style="color: #dcdcaa;" class="mycode_color"><span style="color: #dcdcaa;" class="mycode_color">s_clear_screen</span></span><span style="color: #cccccc;" class="mycode_color">(): </span><span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">End</span></span> <span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span><br />
<span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span> <span style="color: #dcdcaa;" class="mycode_color"><span style="color: #dcdcaa;" class="mycode_color">s_print_char_at</span></span><span style="color: #cccccc;" class="mycode_color">(</span><span style="color: #9cdcfe;" class="mycode_color"><span style="color: #9cdcfe;" class="mycode_color">x</span></span><span style="color: #cccccc;" class="mycode_color"> As </span><span style="color: #b5cea8;" class="mycode_color"><span style="color: #b5cea8;" class="mycode_color">UByte</span></span><span style="color: #cccccc;" class="mycode_color">, </span><span style="color: #9cdcfe;" class="mycode_color"><span style="color: #9cdcfe;" class="mycode_color">y</span></span><span style="color: #cccccc;" class="mycode_color"> As </span><span style="color: #b5cea8;" class="mycode_color"><span style="color: #b5cea8;" class="mycode_color">UByte</span></span><span style="color: #cccccc;" class="mycode_color">, </span><span style="color: #9cdcfe;" class="mycode_color"><span style="color: #9cdcfe;" class="mycode_color">char</span></span><span style="color: #cccccc;" class="mycode_color"> As </span><span style="color: #b5cea8;" class="mycode_color"><span style="color: #b5cea8;" class="mycode_color">UByte</span></span><span style="color: #cccccc;" class="mycode_color">, </span><span style="color: #9cdcfe;" class="mycode_color"><span style="color: #9cdcfe;" class="mycode_color">colour</span></span><span style="color: #cccccc;" class="mycode_color"> As </span><span style="color: #b5cea8;" class="mycode_color"><span style="color: #b5cea8;" class="mycode_color">UByte</span></span><span style="color: #cccccc;" class="mycode_color">): </span><span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">End</span></span> <span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span><br />
<span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span> <span style="color: #dcdcaa;" class="mycode_color"><span style="color: #dcdcaa;" class="mycode_color">s_print_string_at</span></span><span style="color: #cccccc;" class="mycode_color">(</span><span style="color: #9cdcfe;" class="mycode_color"><span style="color: #9cdcfe;" class="mycode_color">x</span></span><span style="color: #cccccc;" class="mycode_color"> As </span><span style="color: #b5cea8;" class="mycode_color"><span style="color: #b5cea8;" class="mycode_color">UByte</span></span><span style="color: #cccccc;" class="mycode_color">, </span><span style="color: #9cdcfe;" class="mycode_color"><span style="color: #9cdcfe;" class="mycode_color">y</span></span><span style="color: #cccccc;" class="mycode_color"> As </span><span style="color: #b5cea8;" class="mycode_color"><span style="color: #b5cea8;" class="mycode_color">UByte</span></span><span style="color: #cccccc;" class="mycode_color">, </span><span style="color: #9cdcfe;" class="mycode_color"><span style="color: #9cdcfe;" class="mycode_color">text</span></span><span style="color: #cccccc;" class="mycode_color"> As </span><span style="color: #b5cea8;" class="mycode_color"><span style="color: #b5cea8;" class="mycode_color">String</span></span><span style="color: #cccccc;" class="mycode_color">, </span><span style="color: #9cdcfe;" class="mycode_color"><span style="color: #9cdcfe;" class="mycode_color">colour</span></span><span style="color: #cccccc;" class="mycode_color"> As </span><span style="color: #b5cea8;" class="mycode_color"><span style="color: #b5cea8;" class="mycode_color">UByte</span></span><span style="color: #cccccc;" class="mycode_color">): </span><span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">End</span></span> <span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span><br />
<span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span> <span style="color: #dcdcaa;" class="mycode_color"><span style="color: #dcdcaa;" class="mycode_color">s_display_monitor</span></span><span style="color: #cccccc;" class="mycode_color">(): </span><span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">End</span></span> <span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span><br />
<span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Function</span></span> <span style="color: #dcdcaa;" class="mycode_color"><span style="color: #dcdcaa;" class="mycode_color">fub_key_get_minutes</span></span><span style="color: #cccccc;" class="mycode_color">() As </span><span style="color: #b5cea8;" class="mycode_color"><span style="color: #b5cea8;" class="mycode_color">UByte</span></span><span style="color: #cccccc;" class="mycode_color">: </span><span style="color: #ce9178;" class="mycode_color"><span style="color: #ce9178;" class="mycode_color">return</span></span><span style="color: #cccccc;" class="mycode_color"> 0: </span><span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">End</span></span> <span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Function</span></span><br />
<span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span> <span style="color: #dcdcaa;" class="mycode_color"><span style="color: #dcdcaa;" class="mycode_color">s_key_wait_for_vblank</span></span><span style="color: #cccccc;" class="mycode_color">(): </span><span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">End</span></span> <span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span><br />
<span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span> <span style="color: #dcdcaa;" class="mycode_color"><span style="color: #dcdcaa;" class="mycode_color">s_get_key</span></span><span style="color: #cccccc;" class="mycode_color">(): </span><span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">End</span></span> <span style="color: #c586c0;" class="mycode_color"><span style="color: #c586c0;" class="mycode_color">Sub</span></span></span><br />
<br />
<br />
But clearly there is something I'm not getting, and I've reached the limits of capability of AI helper tools.<br />
<br />
I had rationalised to myself that my build script should only call to zxbc to produce "-f asm" ASM files... as I expect to have to then somehow "link" the static core ASM and the many paged stage ASM together at some point... and I also seem to have rationalised that I may perhaps need to use     sjasmplus     to assemble my ".nex" package.<br />
<br />
Does the above sound achievable?  Or am I asking too much of the "Next" as a platform?  i.e. is the "Next" only any good for paging graphics data, and no good for paging application code?]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Old zxbasic game errors]]></title>
			<link>https://forum.boriel.com/showthread.php?tid=2649</link>
			<pubDate>Mon, 03 Nov 2025 20:32:31 +0000</pubDate>
			<dc:creator><![CDATA[<a href="https://forum.boriel.com/member.php?action=profile&uid=204">ardentcrest</a>]]></dc:creator>
			<guid isPermaLink="false">https://forum.boriel.com/showthread.php?tid=2649</guid>
			<description><![CDATA[trying Escape From Cnossus from 2013 getting this error<br />
<br />
Error: 'subdivideHigh' is neither an array nor a function.<br />
<br />
the line is <br />
<br />
wall1 =	subdivideHigh(x1, y1, x - 1, y2)<br />
<br />
any help please]]></description>
			<content:encoded><![CDATA[trying Escape From Cnossus from 2013 getting this error<br />
<br />
Error: 'subdivideHigh' is neither an array nor a function.<br />
<br />
the line is <br />
<br />
wall1 =	subdivideHigh(x1, y1, x - 1, y2)<br />
<br />
any help please]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Error: Undefined GLOBAL label]]></title>
			<link>https://forum.boriel.com/showthread.php?tid=2648</link>
			<pubDate>Sun, 02 Nov 2025 12:43:21 +0000</pubDate>
			<dc:creator><![CDATA[<a href="https://forum.boriel.com/member.php?action=profile&uid=204">ardentcrest</a>]]></dc:creator>
			<guid isPermaLink="false">https://forum.boriel.com/showthread.php?tid=2648</guid>
			<description><![CDATA[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.<br />
<br />
ie<br />
<br />
        ld hl, lineMSG<br />
        ld bc, end1-lineMSG<br />
        call myPrint42<br />
<br />
calling <br />
<br />
SUB fastcall myPrint42()<br />
ASM<br />
myPrint42:<br />
    push    af<br />
    push    ix<br />
    push    hl<br />
    ld    ix, PRINT42<br />
    CALL    IXCALL<br />
    pop    hl<br />
    pop    ix<br />
    pop    af<br />
    ret<br />
END ASM<br />
END SUB<br />
<br />
gives me Error: Undefined GLOBAL label ".myPrint42"<br />
<br />
any help please....]]></description>
			<content:encoded><![CDATA[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.<br />
<br />
ie<br />
<br />
        ld hl, lineMSG<br />
        ld bc, end1-lineMSG<br />
        call myPrint42<br />
<br />
calling <br />
<br />
SUB fastcall myPrint42()<br />
ASM<br />
myPrint42:<br />
    push    af<br />
    push    ix<br />
    push    hl<br />
    ld    ix, PRINT42<br />
    CALL    IXCALL<br />
    pop    hl<br />
    pop    ix<br />
    pop    af<br />
    ret<br />
END ASM<br />
END SUB<br />
<br />
gives me Error: Undefined GLOBAL label ".myPrint42"<br />
<br />
any help please....]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[A Fast(er) Plot Routine for Boriel Basic]]></title>
			<link>https://forum.boriel.com/showthread.php?tid=2647</link>
			<pubDate>Tue, 28 Oct 2025 14:56:34 +0000</pubDate>
			<dc:creator><![CDATA[<a href="https://forum.boriel.com/member.php?action=profile&uid=2556">tubz74</a>]]></dc:creator>
			<guid isPermaLink="false">https://forum.boriel.com/showthread.php?tid=2647</guid>
			<description><![CDATA[I orginally posted this on SpectrumComputing Forum - copied here in case anyone wants to play with it :-)<br />
<br />
Hi<br />
<br />
Hope this helps someone else :-)<br />
<br />
I saw a post by Andy Dansby who writes at <a href="https://zxspectrumcoding.wordpress.com/" target="_blank" rel="noopener" class="mycode_url">https://zxspectrumcoding.wordpress.com/</a><br />
<br />
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.<br />
<br />
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.<br />
<br />
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).<br />
<br />
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)<br />
<br />
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.<br />
<br />
As far as Andy's code goes, I understand the comments, but not exactly how it works :-)<br />
<br />
Anyway, code below :<br />
<br />
SUB FASTCALL HellaPrint(yPos as UBYTE, xPos as UBYTE)<br />
' HellaPrint prints an x,y pixel<br />
' 0,0 is top left<br />
' Original code by Andy Lansby<br />
' <a href="https://zxspectrumcoding.wordpress.com/" target="_blank" rel="noopener" class="mycode_url">https://zxspectrumcoding.wordpress.com/</a><br />
' yPos is first, as it save a LD instruction when putting xPos and yPos into DE<br />
ASM<br />
<br />
JP START ; Put this in as it's like this on the Wiki ASM desciption - can it be avoided?<br />
X_PositionBits: defb 128,64,32,16,8,4,2,1<br />
; 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?<br />
<br />
START: ; plot d = x-axis, e = y-axis<br />
; A contains the yPos, xPos is on stack.<br />
POP HL ; Pops the return address into HL<br />
POP DE ; xPos is on the stack, and it needs to be in D<br />
LD E, A ; A has our first paramter (yPos), load it into E. D should be Xpos, E should be yPos<br />
PUSH HL ; Puts the return address back onto stack ...<br />
; 166 T states per pixel<br />
XOR A ; reset A to 0 and flags to default<br />
LD A,E ; load Y plot point<br />
RRA ; rotate Right --- divide in half<br />
SCF ; turn on Carry flag-<br />
RRA ; rotate right with the carry flag<br />
OR A ; set flag S on - C flag off<br />
RRA ; rotate Right --- divide in half<br />
<br />
LD L,A ; temp store in L<br />
XOR E ; XOR the Y value<br />
AND %11111000 ; mask out bottom 3 bits<br />
XOR E ; XOR the Y value<br />
<br />
LD H,A ; store High byte<br />
LD A,D ; load X plot point<br />
XOR L ; XOR the temp value<br />
AND %00000111 ; mask out unwanted bits<br />
XOR D ; XOR the X value<br />
RRCA ; divide by 2<br />
RRCA ; divide by 4<br />
RRCA ; divide by 8<br />
<br />
LD L,A ; store Low byte<br />
; now we have the full address<br />
; now use LUT to find which bit to set<br />
LD A,D ; load X plot point<br />
AND %00000111 ; mask out unwanted bits<br />
<br />
; use a LUT to quickly find the bit position for the X position<br />
LD DE,X_PositionBits ; load LUT address into DE<br />
ADD A,E ; Add A to E to get offset into table<br />
LD E,A ; E now points to the LUT entry<br />
LD A,(DE) ; load answer into A<br />
<br />
; output to screen<br />
OR (HL) ; or with contents of address HL<br />
LD (HL),A ; load address HL with Answer from A<br />
END ASM<br />
END SUB]]></description>
			<content:encoded><![CDATA[I orginally posted this on SpectrumComputing Forum - copied here in case anyone wants to play with it :-)<br />
<br />
Hi<br />
<br />
Hope this helps someone else :-)<br />
<br />
I saw a post by Andy Dansby who writes at <a href="https://zxspectrumcoding.wordpress.com/" target="_blank" rel="noopener" class="mycode_url">https://zxspectrumcoding.wordpress.com/</a><br />
<br />
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.<br />
<br />
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.<br />
<br />
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).<br />
<br />
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)<br />
<br />
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.<br />
<br />
As far as Andy's code goes, I understand the comments, but not exactly how it works :-)<br />
<br />
Anyway, code below :<br />
<br />
SUB FASTCALL HellaPrint(yPos as UBYTE, xPos as UBYTE)<br />
' HellaPrint prints an x,y pixel<br />
' 0,0 is top left<br />
' Original code by Andy Lansby<br />
' <a href="https://zxspectrumcoding.wordpress.com/" target="_blank" rel="noopener" class="mycode_url">https://zxspectrumcoding.wordpress.com/</a><br />
' yPos is first, as it save a LD instruction when putting xPos and yPos into DE<br />
ASM<br />
<br />
JP START ; Put this in as it's like this on the Wiki ASM desciption - can it be avoided?<br />
X_PositionBits: defb 128,64,32,16,8,4,2,1<br />
; 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?<br />
<br />
START: ; plot d = x-axis, e = y-axis<br />
; A contains the yPos, xPos is on stack.<br />
POP HL ; Pops the return address into HL<br />
POP DE ; xPos is on the stack, and it needs to be in D<br />
LD E, A ; A has our first paramter (yPos), load it into E. D should be Xpos, E should be yPos<br />
PUSH HL ; Puts the return address back onto stack ...<br />
; 166 T states per pixel<br />
XOR A ; reset A to 0 and flags to default<br />
LD A,E ; load Y plot point<br />
RRA ; rotate Right --- divide in half<br />
SCF ; turn on Carry flag-<br />
RRA ; rotate right with the carry flag<br />
OR A ; set flag S on - C flag off<br />
RRA ; rotate Right --- divide in half<br />
<br />
LD L,A ; temp store in L<br />
XOR E ; XOR the Y value<br />
AND %11111000 ; mask out bottom 3 bits<br />
XOR E ; XOR the Y value<br />
<br />
LD H,A ; store High byte<br />
LD A,D ; load X plot point<br />
XOR L ; XOR the temp value<br />
AND %00000111 ; mask out unwanted bits<br />
XOR D ; XOR the X value<br />
RRCA ; divide by 2<br />
RRCA ; divide by 4<br />
RRCA ; divide by 8<br />
<br />
LD L,A ; store Low byte<br />
; now we have the full address<br />
; now use LUT to find which bit to set<br />
LD A,D ; load X plot point<br />
AND %00000111 ; mask out unwanted bits<br />
<br />
; use a LUT to quickly find the bit position for the X position<br />
LD DE,X_PositionBits ; load LUT address into DE<br />
ADD A,E ; Add A to E to get offset into table<br />
LD E,A ; E now points to the LUT entry<br />
LD A,(DE) ; load answer into A<br />
<br />
; output to screen<br />
OR (HL) ; or with contents of address HL<br />
LD (HL),A ; load address HL with Answer from A<br />
END ASM<br />
END SUB]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Hall of Fame - Include for ZX Basic]]></title>
			<link>https://forum.boriel.com/showthread.php?tid=2646</link>
			<pubDate>Tue, 28 Oct 2025 14:48:44 +0000</pubDate>
			<dc:creator><![CDATA[<a href="https://forum.boriel.com/member.php?action=profile&uid=2556">tubz74</a>]]></dc:creator>
			<guid isPermaLink="false">https://forum.boriel.com/showthread.php?tid=2646</guid>
			<description><![CDATA[Hi<br />
<br />
HOF.zxbas - Hall of fame procedures<br />
main.zxbas - a demo<br />
<br />
Attached is a little "library" for a Hall of Fame / High Score table.<br />
<br />
To use it - you need to create two Arrays (at least 2 ...)<br />
<br />
Array 1 = UInteger, for scores<br />
Array 2 = String, for names<br />
<br />
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.<br />
<br />
Completely and utterly free to use, adapt, change, republish how ever you want.<br />
<br />
Arraybase is 0<br />
<br />
SUB HOF_IntialiseHOF(BYREF HOF_Scores() AS UINTEGER, BYREF HOF_Names() AS STRING, HOF_IntialTopScore as UINTEGER,HOF_InitialName AS STRING)<br />
Use this to initialise the two HOF arrays - with a "highest score, working down to a low score and gives each entry "InitialName".<br />
<br />
FUNCTION HOF_HighScore_CheckEntry (HOF_Scores() AS UINTEGER, NewHighScore as UINTEGER) AS BYTE <br />
Returns 1 if the High Score can g into the Arrays.<br />
<br />
SUB HOF_HighScore_NewEntry (BYREF HOF_Scores() AS UINTEGER, BYREF HOF_Names() AS STRING, NewHighScore as UINTEGER, NewHighScoreName AS STRING)<br />
Puts the new entries (name &amp; score) into the HOF array.<br />
<br />
SUB HOF_Print(BYREF HOF_Scores() AS UINTEGER, BYREF HOF_Names() AS STRING, YPOS as INTEGER, XPOS as INTEGER)<br />
A simple print location, witch prints the Score and Names.  Will carry on printing if you have many entries ...<br />
<br />
SUB HOF_PrintSpecial(BYREF HOF_Scores() AS UINTEGER, BYREF HOF_Names() AS STRING)<br />
A "pretty High Score screen", that prints the top 10 scores.<br />
<br />
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.<br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://forum.boriel.com/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=362" target="_blank" title="">HOF.zip</a> (Size: 2.98 KB / Downloads: 164)
<!-- end: postbit_attachments_attachment --><br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://forum.boriel.com/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=363" target="_blank" title="">Hall Of Fame.png</a> (Size: 2.13 KB / Downloads: 258)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[Hi<br />
<br />
HOF.zxbas - Hall of fame procedures<br />
main.zxbas - a demo<br />
<br />
Attached is a little "library" for a Hall of Fame / High Score table.<br />
<br />
To use it - you need to create two Arrays (at least 2 ...)<br />
<br />
Array 1 = UInteger, for scores<br />
Array 2 = String, for names<br />
<br />
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.<br />
<br />
Completely and utterly free to use, adapt, change, republish how ever you want.<br />
<br />
Arraybase is 0<br />
<br />
SUB HOF_IntialiseHOF(BYREF HOF_Scores() AS UINTEGER, BYREF HOF_Names() AS STRING, HOF_IntialTopScore as UINTEGER,HOF_InitialName AS STRING)<br />
Use this to initialise the two HOF arrays - with a "highest score, working down to a low score and gives each entry "InitialName".<br />
<br />
FUNCTION HOF_HighScore_CheckEntry (HOF_Scores() AS UINTEGER, NewHighScore as UINTEGER) AS BYTE <br />
Returns 1 if the High Score can g into the Arrays.<br />
<br />
SUB HOF_HighScore_NewEntry (BYREF HOF_Scores() AS UINTEGER, BYREF HOF_Names() AS STRING, NewHighScore as UINTEGER, NewHighScoreName AS STRING)<br />
Puts the new entries (name &amp; score) into the HOF array.<br />
<br />
SUB HOF_Print(BYREF HOF_Scores() AS UINTEGER, BYREF HOF_Names() AS STRING, YPOS as INTEGER, XPOS as INTEGER)<br />
A simple print location, witch prints the Score and Names.  Will carry on printing if you have many entries ...<br />
<br />
SUB HOF_PrintSpecial(BYREF HOF_Scores() AS UINTEGER, BYREF HOF_Names() AS STRING)<br />
A "pretty High Score screen", that prints the top 10 scores.<br />
<br />
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.<br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://forum.boriel.com/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=362" target="_blank" title="">HOF.zip</a> (Size: 2.98 KB / Downloads: 164)
<!-- end: postbit_attachments_attachment --><br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://forum.boriel.com/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=363" target="_blank" title="">Hall Of Fame.png</a> (Size: 2.13 KB / Downloads: 258)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[[SOLVED] Array layout bug - regression in 1.18.3]]></title>
			<link>https://forum.boriel.com/showthread.php?tid=2645</link>
			<pubDate>Fri, 24 Oct 2025 22:24:41 +0000</pubDate>
			<dc:creator><![CDATA[<a href="https://forum.boriel.com/member.php?action=profile&uid=2327">Zoran</a>]]></dc:creator>
			<guid isPermaLink="false">https://forum.boriel.com/showthread.php?tid=2645</guid>
			<description><![CDATA[Please take a look at this simple programme:<br />
<br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>dim a(5) as ubyte =&gt; {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</code></div></div><br />
When compiled with zxbasic 1.18.2 this works as expected - both arrays are same. See the attached image:<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://forum.boriel.com/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=360" target="_blank" title="">arrays_zxbasic_1_18_2.png</a> (Size: 8.81 KB / Downloads: 243)
<!-- end: postbit_attachments_attachment --><br />
However, with zxbasic 1.18.3, the programme fails miserably and crashes the Spectrum<br />
<br />
In both cases compiled with <br />
<blockquote class="mycode_quote"><cite>Quote: Wrote:</cite>--optimize 2  --output-format=tzx --BASIC --autorun --explicit --strict</blockquote><br />
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 <a href="https://skoolkid.github.io/rom/asm/5C36.html" target="_blank" rel="noopener" class="mycode_url">the system variable 5C36</a> to the address of the array minus 256 (@array - &#36;100) and when I want to print latin text, I just poke this variable back to default value  &#36;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.<br />
What happend with array layout?<br />
<br />
<hr class="mycode_hr" />
<br />
<br />
Now I tried to see the address of the array itself, compared with the addresses of array elements:<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>dim a(5) as ubyte =&gt; {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</code></div></div><br />
The attached image shows the output with zxbasic 1.18.2 compared with zxbasic 1.18.3:<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://forum.boriel.com/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=361" target="_blank" title="">arrayAddresses.png</a> (Size: 14.42 KB / Downloads: 282)
<!-- end: postbit_attachments_attachment --><br />
<br />
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.<br />
<br />
So, I can workaround the problem with the custom character set that I mentioned in my previous post using:<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>poke (uinteger &#36;5c36, @charset(0,0) - &#36;100) ' the address of the first element</code></div></div>instead of<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>poke (uinteger &#36;5c36, @charset - &#36;0100) ' the address of the array</code></div></div><br />
But still, is there a reason for this, or is it just a bug?]]></description>
			<content:encoded><![CDATA[Please take a look at this simple programme:<br />
<br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>dim a(5) as ubyte =&gt; {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</code></div></div><br />
When compiled with zxbasic 1.18.2 this works as expected - both arrays are same. See the attached image:<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://forum.boriel.com/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=360" target="_blank" title="">arrays_zxbasic_1_18_2.png</a> (Size: 8.81 KB / Downloads: 243)
<!-- end: postbit_attachments_attachment --><br />
However, with zxbasic 1.18.3, the programme fails miserably and crashes the Spectrum<br />
<br />
In both cases compiled with <br />
<blockquote class="mycode_quote"><cite>Quote: Wrote:</cite>--optimize 2  --output-format=tzx --BASIC --autorun --explicit --strict</blockquote><br />
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 <a href="https://skoolkid.github.io/rom/asm/5C36.html" target="_blank" rel="noopener" class="mycode_url">the system variable 5C36</a> to the address of the array minus 256 (@array - &#36;100) and when I want to print latin text, I just poke this variable back to default value  &#36;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.<br />
What happend with array layout?<br />
<br />
<hr class="mycode_hr" />
<br />
<br />
Now I tried to see the address of the array itself, compared with the addresses of array elements:<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>dim a(5) as ubyte =&gt; {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</code></div></div><br />
The attached image shows the output with zxbasic 1.18.2 compared with zxbasic 1.18.3:<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://forum.boriel.com/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=361" target="_blank" title="">arrayAddresses.png</a> (Size: 14.42 KB / Downloads: 282)
<!-- end: postbit_attachments_attachment --><br />
<br />
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.<br />
<br />
So, I can workaround the problem with the custom character set that I mentioned in my previous post using:<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>poke (uinteger &#36;5c36, @charset(0,0) - &#36;100) ' the address of the first element</code></div></div>instead of<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>poke (uinteger &#36;5c36, @charset - &#36;0100) ' the address of the array</code></div></div><br />
But still, is there a reason for this, or is it just a bug?]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[3DOS Commands?]]></title>
			<link>https://forum.boriel.com/showthread.php?tid=2643</link>
			<pubDate>Sun, 05 Oct 2025 21:33:54 +0000</pubDate>
			<dc:creator><![CDATA[<a href="https://forum.boriel.com/member.php?action=profile&uid=2556">tubz74</a>]]></dc:creator>
			<guid isPermaLink="false">https://forum.boriel.com/showthread.php?tid=2643</guid>
			<description><![CDATA[Hi<br />
<br />
I'm looking at using some 3DOS commands, starting to see how I can cat a disk.<br />
<br />
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.<br />
<br />
I'm assuming that there might be some incompatibility somewhere between, starting reading, and returning contorl to the program.  Code is below.<br />
<br />
Any thoughts?<br />
<br />
(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)<br />
<br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>#include &lt;input.bas&gt;
#include &lt;screen.bas&gt;
#INCLUDE &lt;keys.bas&gt; 

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</code></div></div>]]></description>
			<content:encoded><![CDATA[Hi<br />
<br />
I'm looking at using some 3DOS commands, starting to see how I can cat a disk.<br />
<br />
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.<br />
<br />
I'm assuming that there might be some incompatibility somewhere between, starting reading, and returning contorl to the program.  Code is below.<br />
<br />
Any thoughts?<br />
<br />
(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)<br />
<br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>#include &lt;input.bas&gt;
#include &lt;screen.bas&gt;
#INCLUDE &lt;keys.bas&gt; 

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</code></div></div>]]></content:encoded>
		</item>
	</channel>
</rss>