Menu

#3734 __banked calls fail when hl modified in set_bank

open
nobody
None
Z80
5
2024-06-17
2024-05-20
Under4Mhz
No

Using the __ banked keyword fails for me.

My set_bank function calls a C function that modifies hl. sdcc_bcall_ehl assumes hl is not modified by set_bank.

My system hardware doesn't store support reading the current the bank, so I need to store it in a global variable for use later.

It would be preferable for the sdcc_bcall_ehl code to add push/pop hl around the call to set_bank. That way it won't be dependent on the set_bank implementation, or require the programmer to remember to do it.

The work around is to add push/pop hl in the set_bank call.

The C code callback is:

///< sdcc auto bank switching
void set_bank() __naked {

    __asm
set_bank::
        call _vdu_bank_set
        ret
    __endasm;
}

void vdu_bank_set( uint8_t bank ) {

    vdu_interrupt_enable();
    current_bank = bank;
    vdu_bank_start( bank );
}

which generates the hl modifying call:

_vdu_bank_set::
    ld  c, a
    push    bc
    call    _vdu_interrupt_enable
    pop bc
    ld  hl, #_current_bank
    ld  a,c
    ld  (hl),a            ; oops, jumps to memory location on return
    jp  _vdu_bank_start

The sdcc_bcall_ehl code from sdcc for reference:

___sdcc_bcall_ehl::
        call    get_bank
        push    af
        inc     sp
        call    ___sdcc_bjump_ehl
        dec     sp
        pop     bc
        push    af
        ld      a, b
        call    set_bank
        pop     af
        ret
;
___sdcc_bjump_ehl:
        ld      a, e
        call    set_bank    ; this changes hl. add push/pop here?
        jp      (hl)        ; goes awry
sdcc -v
SDCC : z80/sm83/z80n/mos6502/mos65c02 TD- 4.4.1 #14863 (Linux)

Discussion

  • sverx

    sverx - 2024-05-29

    I think it's expected for set_bank to do not change any Z80 register.
    Did you try writing set_bank as:

    set_bank::
            ld (#_current_bank),a
            ret
    
     
    • Under4Mhz

      Under4Mhz - 2024-05-31

      Systems like the ColecoVision don't support reading the current bank from the hardware. Setting it is simple enough. However, in order to return a value in get_bank I have to store the bank into a variable.

      It's not really a problem, I can store hl in the set_bank and the problem is fixed.

      This may be a feature request. When I find myself looking at dissembled z80 code to figure out an issue, I like to write a bug request so others don't have to spend time on it. With that push/pop hl, I wouldn't have even noticed.

      If only all systems were as well designed as the Sega Master System.

       

      Last edit: Under4Mhz 2024-05-31
      • sverx

        sverx - 2024-06-17

        yes, sorry my reply wasn't clear enough - my point was that to save the bank in a variable (current_bank in my source) and use that later in get_bank::

         

Log in to post a comment.

Monday.com Logo