When assigning banked functions to a pointer, the banked keyword is not respected. When a banked function is assigned to a banked pointer, no banking is performed.
This could be considered a feature request. If so, it would be preferable if the compiler complained it's not supported.
/// GPL 2.0 or later
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
void ArRun() __banked;
void GlRun() __banked;
void GameLoop();
void (*gameList[])(void) __banked = {ArRun, GlRun };
void GameSet2( int game ) {
switch( game ) {
case 0: ArRun();
case 1: GlRun();
}
}
void GameSet( int game ) {
void (*callback)(void) __banked = gameList[game];
(*callback)();
(*gameList[game])();
}
///< Identical first 16K between roms
int main() {
int game = 1;
GameSet( game );
}
// sdcc -mz80 --fverbose-asm ./bank_function_ptr.c -o bank_function_ptr.ihx
Produces the following assembly:
;./bank_function_ptr.c:15: void GameSet2( int game ) {
; ---------------------------------
; Function GameSet2
; ---------------------------------
_GameSet2::
;./bank_function_ptr.c:17: switch( game ) {
ld a, h
or a, l
jr z, 00101$
ld a, l
dec a
or a, h
jr z, 00102$
ret
;./bank_function_ptr.c:19: case 0: ArRun();
00101$:
ld e, #b_ArRun
ld hl, #_ArRun
call ___sdcc_bcall_ehl
;./bank_function_ptr.c:20: case 1: GlRun();
00102$:
ld e, #b_GlRun
ld hl, #_GlRun
;./bank_function_ptr.c:21: }
;./bank_function_ptr.c:22: }
jp ___sdcc_bcall_ehl
;./bank_function_ptr.c:24: void GameSet( int game ) {
; ---------------------------------
; Function GameSet
; ---------------------------------
_GameSet::
;./bank_function_ptr.c:26: void (*callback)(void) __banked = gameList[game];
ld bc, #_gameList+0
add hl, hl
add hl, bc
ld c, (hl)
inc hl
ld b, (hl)
dec hl
;./bank_function_ptr.c:27: (*callback)();
push hl
ld l, c
ld h, b
call ___sdcc_call_hl
pop hl
;./bank_function_ptr.c:28: (*gameList[game])();
ld a, (hl)
inc hl
ld h, (hl)
ld l, a
;./bank_function_ptr.c:29: }
jp (hl)
$ sdcc -v
SDCC : z80/sm83/ez80/z80n/mos6502/mos65c02 4.6.0 #16608 (Linux)