gbdk-2020 | GameBoy Development Kit |
| download: https://git.y1.nz/archives/gbdk.tar.gz | |
| README | Files | Log | Refs | LICENSE |
commit 5fc17b21b7140485f8aa05eaf331f9b9fd8e0f15 parent b6dba7a9c1b968b1f8436c9ea327a2072cb7e68f Author: Toxa <untoxa@mail.ru> Date: Fri, 20 Aug 2021 17:11:57 +0300 SMS/GG: far_ptr.h support Diffstat:
15 files changed, 319 insertions(+), 55 deletions(-)
diff --git a/gbdk-lib/examples/ap/banks_farptr/bank2code.c b/gbdk-lib/examples/ap/banks_farptr/bank2code.c @@ -1,11 +1,11 @@ #pragma bank 2 -#include <gb/gb.h> +#include <gbdk/platform.h> #include <stdint.h> #include <stdio.h> static int local_bank2_proc(int param1, int param2) { - printf(" sum: %d (bank=%d)\n", param1 + param2, (int)_current_bank); + printf(" sum: %d (bank=%d)\n", param1 + param2, (int)CURRENT_BANK); return (param1 + param2) << 1; } diff --git a/gbdk-lib/examples/ap/banks_farptr/banks_farptr.c b/gbdk-lib/examples/ap/banks_farptr/banks_farptr.c @@ -1,8 +1,7 @@ -#include <gb/gb.h> #include <stdint.h> -#include <gb/far_ptr.h> - #include <stdio.h> +#include <gbdk/platform.h> +#include <gbdk/far_ptr.h> // functions from bank2code.c BANKREF_EXTERN(some_bank2_proc0) @@ -20,9 +19,9 @@ int res; void run() { // compose far pointer at runtime - farptr_var0 = to_far_ptr(some_bank2_proc1, BANK(some_bank2_proc1)); + farptr_var0 = to_far_ptr(some_bank2_proc1, BANK(some_bank2_proc1)); farptr_var1 = to_far_ptr(some_bank2_proc1, BANK(some_bank2_proc1)); - farptr_var2 = to_far_ptr(some_bank2_proc0, BANK(some_bank2_proc0)); + farptr_var2 = to_far_ptr(some_bank2_proc0, BANK(some_bank2_proc0)); // output far pointers (must be identical) printf("FAR PTR0: %x:%x\n", (int)FAR_SEG(farptr_var0), (int)FAR_OFS(farptr_var0)); @@ -42,8 +41,8 @@ void run() { } void main() { - ENABLE_RAM_MBC1; - printf("START (bank=%d)\n", (int)_current_bank); + ENABLE_RAM; + printf("START (bank=%d)\n", (int)CURRENT_BANK); run(); - printf("DONE! (bank=%d)\n", (int)_current_bank); + printf("DONE! (bank=%d)\n", (int)CURRENT_BANK); } diff --git a/gbdk-lib/examples/gb/banks_farptr/bank2code.c b/gbdk-lib/examples/gb/banks_farptr/bank2code.c @@ -1,11 +1,11 @@ #pragma bank 2 -#include <gb/gb.h> +#include <gbdk/platform.h> #include <stdint.h> #include <stdio.h> static int local_bank2_proc(int param1, int param2) { - printf(" sum: %d (bank=%d)\n", param1 + param2, (int)_current_bank); + printf(" sum: %d (bank=%d)\n", param1 + param2, (int)CURRENT_BANK); return (param1 + param2) << 1; } diff --git a/gbdk-lib/examples/gb/banks_farptr/banks_farptr.c b/gbdk-lib/examples/gb/banks_farptr/banks_farptr.c @@ -1,8 +1,7 @@ -#include <gb/gb.h> #include <stdint.h> -#include <gb/far_ptr.h> - #include <stdio.h> +#include <gbdk/platform.h> +#include <gbdk/far_ptr.h> // functions from bank2code.c BANKREF_EXTERN(some_bank2_proc0) @@ -20,9 +19,9 @@ int res; void run() { // compose far pointer at runtime - farptr_var0 = to_far_ptr(some_bank2_proc1, BANK(some_bank2_proc1)); + farptr_var0 = to_far_ptr(some_bank2_proc1, BANK(some_bank2_proc1)); farptr_var1 = to_far_ptr(some_bank2_proc1, BANK(some_bank2_proc1)); - farptr_var2 = to_far_ptr(some_bank2_proc0, BANK(some_bank2_proc0)); + farptr_var2 = to_far_ptr(some_bank2_proc0, BANK(some_bank2_proc0)); // output far pointers (must be identical) printf("FAR PTR0: %x:%x\n", (int)FAR_SEG(farptr_var0), (int)FAR_OFS(farptr_var0)); @@ -42,8 +41,8 @@ void run() { } void main() { - ENABLE_RAM_MBC1; - printf("START (bank=%d)\n", (int)_current_bank); + ENABLE_RAM; + printf("START (bank=%d)\n", (int)CURRENT_BANK); run(); - printf("DONE! (bank=%d)\n", (int)_current_bank); + printf("DONE! (bank=%d)\n", (int)CURRENT_BANK); } diff --git a/gbdk-lib/examples/gg/banks_farptr/Makefile b/gbdk-lib/examples/gg/banks_farptr/Makefile @@ -0,0 +1,30 @@ +CC = ../../../bin/lcc -mz80:gg -Wm-yoA -Wa-l -Wl-j + +BINS = banks_farptr.gg + +all: $(BINS) + +ASRC = $(wildcard *.s) +CSRC = $(wildcard *.c) + +OBJS = $(CSRC:%.c=%.o) $(ASRC:%.s=%.o) + +compile.bat: Makefile + @echo "REM Automatically generated from Makefile" > compile.bat + @make -sn | sed y/\\//\\\\/ | grep -v make >> compile.bat + +# Compile and link single file in one pass + +%.o: %.c + $(CC) -c -o $@ $< + +%.o: %.s + $(CC) -c -o $@ $< + +$(BINS): $(OBJS) + $(CC) -Wm-yS -o $@ $^ + rm -f *.map *.noi *.ihx *.lst + +clean: + rm -f *.o *.lst *.map *.gg *~ *.rel *.cdb *.ihx *.lnk *.sym *.asm *.noi + diff --git a/gbdk-lib/examples/gg/banks_farptr/bank2code.c b/gbdk-lib/examples/gg/banks_farptr/bank2code.c @@ -0,0 +1,21 @@ +#pragma bank 2 + +#include <gbdk/platform.h> +#include <stdint.h> +#include <stdio.h> + +static int local_bank2_proc(int param1, int param2) { + printf(" sum: %d (bank=%d)\n", param1 + param2, (int)CURRENT_BANK); + return (param1 + param2) << 1; +} + +BANKREF(some_bank2_proc0) +void some_bank2_proc0() __banked { + printf("some_bank2_proc0\n"); +} + +BANKREF(some_bank2_proc1) +int some_bank2_proc1(int param1, int param2) __banked { + printf("some_bank2_proc1\n"); + return local_bank2_proc(param1, param2); +} diff --git a/gbdk-lib/examples/gg/banks_farptr/banks_farptr.c b/gbdk-lib/examples/gg/banks_farptr/banks_farptr.c @@ -0,0 +1,48 @@ +#include <stdint.h> +#include <stdio.h> +#include <gbdk/platform.h> +#include <gbdk/far_ptr.h> + +// functions from bank2code.c +BANKREF_EXTERN(some_bank2_proc0) +extern void some_bank2_proc0() __banked; + +BANKREF_EXTERN(some_bank2_proc1) +extern int some_bank2_proc1(int param1, int param2) __banked; +typedef int (*some_bank2_proc_t)(int, int) __banked; // define type for some_bank2_proc1() function + +// far pointers +FAR_PTR farptr_var0, farptr_var1, farptr_var2; + +// result of a function call +int res; + +void run() { + // compose far pointer at runtime + farptr_var0 = to_far_ptr(some_bank2_proc1, BANK(some_bank2_proc1)); + farptr_var1 = to_far_ptr(some_bank2_proc1, BANK(some_bank2_proc1)); + farptr_var2 = to_far_ptr(some_bank2_proc0, BANK(some_bank2_proc0)); + + // output far pointers (must be identical) + printf("FAR PTR0: %x:%x\n", (int)FAR_SEG(farptr_var0), (int)FAR_OFS(farptr_var0)); + printf("FAR PTR1: %x:%x\n", (int)FAR_SEG(farptr_var1), (int)FAR_OFS(farptr_var1)); + + // try calling far function by far pointer without params + FAR_CALL(farptr_var2, void (*)(void)); + + // try calling far function directly + res = some_bank2_proc1(100, 50); + printf("CALL DIR: %d\n", res); + + // try calling far function by far pointer + res = FAR_CALL(farptr_var1, some_bank2_proc_t, 100, 50); + + printf("CALL IND: %d\n", res); +} + +void main() { + ENABLE_RAM; + printf("START (bank=%d)\n", (int)CURRENT_BANK); + run(); + printf("DONE! (bank=%d)\n", (int)CURRENT_BANK); +} + diff --git a/gbdk-lib/examples/sms/banks_farptr/Makefile b/gbdk-lib/examples/sms/banks_farptr/Makefile @@ -0,0 +1,30 @@ +CC = ../../../bin/lcc -mz80:sms -Wm-yoA -Wa-l -Wl-j + +BINS = banks_farptr.sms + +all: $(BINS) + +ASRC = $(wildcard *.s) +CSRC = $(wildcard *.c) + +OBJS = $(CSRC:%.c=%.o) $(ASRC:%.s=%.o) + +compile.bat: Makefile + @echo "REM Automatically generated from Makefile" > compile.bat + @make -sn | sed y/\\//\\\\/ | grep -v make >> compile.bat + +# Compile and link single file in one pass + +%.o: %.c + $(CC) -c -o $@ $< + +%.o: %.s + $(CC) -c -o $@ $< + +$(BINS): $(OBJS) + $(CC) -Wm-yS -o $@ $^ + rm -f *.map *.noi *.ihx *.lst + +clean: + rm -f *.o *.lst *.map *.sms *~ *.rel *.cdb *.ihx *.lnk *.sym *.asm *.noi + diff --git a/gbdk-lib/examples/sms/banks_farptr/bank2code.c b/gbdk-lib/examples/sms/banks_farptr/bank2code.c @@ -0,0 +1,21 @@ +#pragma bank 2 + +#include <gbdk/platform.h> +#include <stdint.h> +#include <stdio.h> + +static int local_bank2_proc(int param1, int param2) { + printf(" sum: %d (bank=%d)\n", param1 + param2, (int)CURRENT_BANK); + return (param1 + param2) << 1; +} + +BANKREF(some_bank2_proc0) +void some_bank2_proc0() __banked { + printf("some_bank2_proc0\n"); +} + +BANKREF(some_bank2_proc1) +int some_bank2_proc1(int param1, int param2) __banked { + printf("some_bank2_proc1\n"); + return local_bank2_proc(param1, param2); +} diff --git a/gbdk-lib/examples/sms/banks_farptr/banks_farptr.c b/gbdk-lib/examples/sms/banks_farptr/banks_farptr.c @@ -0,0 +1,48 @@ +#include <stdint.h> +#include <stdio.h> +#include <gbdk/platform.h> +#include <gbdk/far_ptr.h> + +// functions from bank2code.c +BANKREF_EXTERN(some_bank2_proc0) +extern void some_bank2_proc0() __banked; + +BANKREF_EXTERN(some_bank2_proc1) +extern int some_bank2_proc1(int param1, int param2) __banked; +typedef int (*some_bank2_proc_t)(int, int) __banked; // define type for some_bank2_proc1() function + +// far pointers +FAR_PTR farptr_var0, farptr_var1, farptr_var2; + +// result of a function call +int res; + +void run() { + // compose far pointer at runtime + farptr_var0 = to_far_ptr(some_bank2_proc1, BANK(some_bank2_proc1)); + farptr_var1 = to_far_ptr(some_bank2_proc1, BANK(some_bank2_proc1)); + farptr_var2 = to_far_ptr(some_bank2_proc0, BANK(some_bank2_proc0)); + + // output far pointers (must be identical) + printf("FAR PTR0: %x:%x\n", (int)FAR_SEG(farptr_var0), (int)FAR_OFS(farptr_var0)); + printf("FAR PTR1: %x:%x\n", (int)FAR_SEG(farptr_var1), (int)FAR_OFS(farptr_var1)); + + // try calling far function by far pointer without params + FAR_CALL(farptr_var2, void (*)(void)); + + // try calling far function directly + res = some_bank2_proc1(100, 50); + printf("CALL DIR: %d\n", res); + + // try calling far function by far pointer + res = FAR_CALL(farptr_var1, some_bank2_proc_t, 100, 50); + + printf("CALL IND: %d\n", res); +} + +void main() { + ENABLE_RAM; + printf("START (bank=%d)\n", (int)CURRENT_BANK); + run(); + printf("DONE! (bank=%d)\n", (int)CURRENT_BANK); +} + diff --git a/gbdk-lib/include/gb/far_ptr.h b/gbdk-lib/include/gbdk/far_ptr.h diff --git a/gbdk-lib/libc/targets/z80/__sdcc_bcall.s b/gbdk-lib/libc/targets/z80/__sdcc_bcall.s @@ -1,10 +1,10 @@ .include "global.s" - .area _CODE + .area _CODE - .globl ___sdcc_bcall - .globl ___sdcc_bcall_abc - .globl ___sdcc_bcall_ehl + .globl ___sdcc_bcall + .globl ___sdcc_bcall_abc + .globl ___sdcc_bcall_ehl ; ; trampoline to call banked functions ; used when legacy banking is enabled only @@ -14,15 +14,15 @@ ; .dw <function_bank> ; ___sdcc_bcall:: - ex (sp), hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, (hl) - inc hl - inc hl - ex (sp), hl + ex (sp), hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, (hl) + inc hl + inc hl + ex (sp), hl ; ; trampoline to call banked functions with __z88dk_fastcall calling convention ; Usage: @@ -31,23 +31,23 @@ ___sdcc_bcall:: ; call ___sdcc_bcall_abc ; ___sdcc_bcall_abc:: - push hl - ld l, a - ld a, (#.MAP_FRAME1) - ld h, a - ld a, l + push hl + ld l, a + ld a, (#.MAP_FRAME1) + ld h, a + ld a, l + ld (#.MAP_FRAME1), a + ex (sp), hl + inc sp + call ___sdcc_bjump_abc + dec sp + pop af ld (#.MAP_FRAME1), a - ex (sp), hl - inc sp - call ___sdcc_bjump_abc - dec sp - pop af - ld (#.MAP_FRAME1), a ret ; ___sdcc_bjump_abc: - push bc - ret + push bc + ret ; ; default trampoline to call banked functions ; Usage: @@ -56,13 +56,13 @@ ___sdcc_bjump_abc: ; call ___sdcc_bcall_ehl ; ___sdcc_bcall_ehl:: - ld a, (#.MAP_FRAME1) - push af - inc sp - ld a, e - ld (#.MAP_FRAME1), a - CALL_HL - dec sp - pop af - ld (#.MAP_FRAME1), a + ld a, (#.MAP_FRAME1) + push af + inc sp + ld a, e + ld (#.MAP_FRAME1), a + CALL_HL + dec sp + pop af + ld (#.MAP_FRAME1), a ret diff --git a/gbdk-lib/libc/targets/z80/far_ptr.s b/gbdk-lib/libc/targets/z80/far_ptr.s @@ -0,0 +1,64 @@ +;-------------------------------------------------------------------------- +; far_ptr.s +; +; Copyright (C) 2020, Tony Pavlov +; +; This library is free software; you can redistribute it and/or modify it +; under the terms of the GNU General Public License as published by the +; Free Software Foundation; either version 2, or (at your option) any +; later version. +; +; This library is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this library; see the file COPYING. If not, write to the +; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, +; MA 02110-1301, USA. +; +; As a special exception, if you link this library with other files, +; some of which are compiled with SDCC, to produce an executable, +; this library does not by itself cause the resulting executable to +; be covered by the GNU General Public License. This exception does +; not however invalidate any other reasons why the executable file +; might be covered by the GNU General Public License. +;-------------------------------------------------------------------------- + + .module far_ptr + + .include "global.s" + + .area _HOME + +___call__banked:: + + ld a, (#.MAP_FRAME1) + push af + inc sp + ld a, (___call_banked_bank) + ld (#.MAP_FRAME1), a + ld hl, (___call_banked_addr) + CALL_HL + dec sp + pop af + ld (#.MAP_FRAME1), a + ret + +_to_far_ptr:: + pop bc + pop hl + pop de + push de + push hl + push bc + ret + + .area _BSS + +___call_banked_ptr:: +___call_banked_addr:: + .ds 0x02 ; far pointer offset +___call_banked_bank:: + .ds 0x02 ; far pointer segment diff --git a/gbdk-lib/libc/targets/z80/gg/Makefile b/gbdk-lib/libc/targets/z80/gg/Makefile @@ -20,6 +20,7 @@ ASSRC = outi.s vmemcpy.s \ int.s nmi.s \ mode.s \ memset_small.s \ + far_ptr.s \ __sdcc_bcall.s \ crt0.s diff --git a/gbdk-lib/libc/targets/z80/sms/Makefile b/gbdk-lib/libc/targets/z80/sms/Makefile @@ -20,6 +20,7 @@ ASSRC = outi.s vmemcpy.s \ int.s nmi.s \ mode.s \ memset_small.s \ + far_ptr.s \ __sdcc_bcall.s \ crt0.s
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.