gbdk-2020 | GameBoy Development Kit |
| download: https://git.y1.nz/archives/gbdk.tar.gz | |
| README | Files | Log | Refs | LICENSE |
gbdk-lib/include/gbdk/far_ptr.h
1 /** @file gbdk/far_ptr.h
2
3 Far pointers include a segment (bank) selector so they are
4 able to point to addresses (functions or data) outside
5 of the current bank (unlike normal pointers which are not
6 bank-aware).
7
8 See the `banks_farptr` example project included with gbdk.
9
10 @todo Add link to a discussion about banking (such as, how to assign code and variables to banks)
11 */
12
13 #ifndef __FAR_PTR_H_INCLUDE
14 #define __FAR_PTR_H_INCLUDE
15
16 #include <types.h>
17 #include <stdint.h>
18
19 /** Macro to obtain a far pointer at compile-time
20 @param ofs Memory address within the given Segment (Bank)
21 @param seg Segment (Bank) number
22
23 @returns A far pointer (type @ref FAR_PTR)
24 */
25 #define TO_FAR_PTR(ofs, seg) (((FAR_PTR)seg << 16) | (FAR_PTR)ofs)
26
27 /** Macro to get the Segment (Bank) number of a far pointer
28 @param ptr A far pointer (type @ref FAR_PTR)
29
30 @returns Segment (Bank) of the far pointer (type uint16_t)
31 */
32 #define FAR_SEG(ptr) (((union __far_ptr *)&ptr)->segofs.seg)
33
34 /** Macro to get the Offset (address) of a far pointer
35 @param ptr A far pointer (type @ref FAR_PTR)
36
37 @returns Offset (address) of the far pointer (type void *)
38 */
39 #define FAR_OFS(ptr) (((union __far_ptr *)&ptr)->segofs.ofs)
40
41 #define FAR_FUNC(ptr, typ) ((typ)(((union __far_ptr *)&ptr)->segfn.fn))
42
43 /** Macro to call a function at far pointer __ptr__ of type __typ__
44 @param ptr Far pointer of a function to call (type @ref FAR_PTR)
45 @param typ Type to cast the function far pointer to.
46 @param ... VA Args list of parameters for the function
47
48 __type__ should match the definition of the function being called. For example:
49 \code{.c}
50 // A function in bank 2
51 #pragma bank 2
52 uint16_t some_function(uint16_t param1, uint16_t param2) __banked { return 1; };
53
54 ...
55 // Code elsewhere, such as unbanked main()
56 // This type declaration should match the above function
57 typedef uint16_t (*some_function_t)(uint16_t, uint16_t) __banked;
58
59 // Using FAR_CALL() with the above as *ptr*, *typ*, and two parameters.
60 result = FAR_CALL(some_function, some_function_t, 100, 50);
61 \endcode
62
63 @returns Value returned by the function (if present)
64 */
65 #define FAR_CALL(ptr, typ, ...) (__call_banked_ptr=ptr,((typ)(&__call__banked))(__VA_ARGS__))
66
67 /** Type for storing a FAR_PTR
68 */
69 typedef uint32_t FAR_PTR;
70
71 /** Union for working with members of a FAR_PTR
72 */
73 union __far_ptr {
74 FAR_PTR ptr;
75 struct {
76 void * ofs;
77 uint16_t seg;
78 } segofs;
79 struct {
80 void (*fn)(void);
81 uint16_t seg;
82 } segfn;
83 };
84
85 extern volatile FAR_PTR __call_banked_ptr;
86 extern volatile void * __call_banked_addr;
87 extern volatile uint8_t __call_banked_bank;
88
89 void __call__banked(void);
90
91 /** Obtain a far pointer at runtime
92 @param ofs Memory address within the given Segment (Bank)
93 @param seg Segment (Bank) number
94
95 @returns A far pointer (type @ref FAR_PTR)
96 */
97 uint32_t to_far_ptr(void* ofs, uint16_t seg);
98
99 #endif
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.