Exporting a far pointer in assembler

Other misc things
Post Reply
vmorilla
New member
Posts: 7
Joined: Sun Feb 11, 2024 7:15 pm

Exporting a far pointer in assembler

Post by vmorilla »

Hello,

I am struggling to declare a far pointer within my assembly code. Basically, I would like to export two far pointers to data I am including with the INCBIN directive:

Code: Select all

SECTION rodata_user

PUBLIC _pic1, _pic2

SECTION BANK_04

_pic1:
    INCBIN "../assets/pic1.lz77"

SECTION BANK_05

_pic2:
    INCBIN "../assets/pic2.lz77"
So, I would like "_pic1" and "_pic2" to be treated as far pointers in their corresponding banks. Is this possible?

Thanks in advance
User avatar
dom
Well known member
Posts: 2148
Joined: Sun Jul 15, 2007 10:01 pm

Re: Exporting a far pointer in assembler

Post by dom »

You're not the only one who's struggling! I think I've missed handling of that scenario out, but since I'm guessing you're on +zx where it's all a bit complicated and non-linear in terms of mapping statically placed data to a far pointer it may be for the best.

The far pointer code uses the banks in this order:

Code: Select all

pages:
   ; Support up to 96k of heap, but...
   ; last 32k conflict with other things
    defb    1,3,4,6,0,7
So we end up with far pointers mapping as follows:

* 0x010000 -> 0x013fff = bank 1
* 0x014000 -> 0x017fff = bank 3
* 0x018000 -> 0x01bfff = bank 4
* 0x01c000 -> 0x01ffff = bank 6

So we can see for _pic1 we need to construct an address somewhere in the range 0x18000 -> 0x1bfff

So, here's a workaround:

Code: Select all

SECTION BANK_04

_pic1:
    INCBIN "../assets/pic1.lz77"

Code: Select all

char *__far getpic1() __naked
{
#asm
        EXTERN _pic1
        ld      hl,+((_pic1 % 65536) & 0xbfff)
        ld      de,1
        ret
#endasm
}

void func()
{
    far char * __far ptr = getpic1();

    ....
}
I'll need to figure out how to make it automatic, but hopefully this will get you unstuck.
vmorilla
New member
Posts: 7
Joined: Sun Feb 11, 2024 7:15 pm

Re: Exporting a far pointer in assembler

Post by vmorilla »

Oh, I see. Thanks a lot. That's very useful.

I thought I might be overseeing something.
User avatar
dom
Well known member
Posts: 2148
Joined: Sun Jul 15, 2007 10:01 pm

Re: Exporting a far pointer in assembler

Post by dom »

I've raised #2544 and have a branch implementing this. Some example usage is here: https://github.com/z88dk/z88dk/blob/Iss ... farspace.c

Absolute addresses can also be used:

Code: Select all

__at (0x071234) __banked char xyz;
which would access address 0x1234 in bank 7

I want to do a bit more work on it, and add handling for more than +zx but feedback welcome.
vmorilla
New member
Posts: 7
Joined: Sun Feb 11, 2024 7:15 pm

Re: Exporting a far pointer in assembler

Post by vmorilla »

Thanks a lot, Dom. I was checking the example, but sorry if my question is a bit naive... where are the extern variables declared in the code (func2, arr, I, ptr) defined?
User avatar
dom
Well known member
Posts: 2148
Joined: Sun Jul 15, 2007 10:01 pm

Re: Exporting a far pointer in assembler

Post by dom »

That example is part of a testsuite to validate the code generation - it's not actually a running program so they're never actually defined, try something like this:

Code: Select all

// bank.c
//
// Note pragma bank doesn't change the DATA section (it would create invalid programs for ROM compiles). To move the data and
// bss segments into banked RAM do this as well:
// #pragma dataseg DATA_4
// #pragma bssseg BSS_4

#pragma bank 4

const int banked_val = 4

Code: Select all

// main.c

extern __banked const int banked_val;

int func()
{
   return banked_val;
}
User avatar
dom
Well known member
Posts: 2148
Joined: Sun Jul 15, 2007 10:01 pm

Re: Exporting a far pointer in assembler

Post by dom »

I merged the __banked -> __far conversion this weekend, and support is now available for the ZX Spectrum, MSX and Aquarius+ targets.
Post Reply