libws libws
WSwan hardware library for the Wonderful toolchain
Loading...
Searching...
No Matches
memory.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022 Adrian "asie" Siekierka
3 *
4 * This software is provided 'as-is', without any express or implied
5 * warranty. In no event will the authors be held liable for any damages
6 * arising from the use of this software.
7 *
8 * Permission is granted to anyone to use this software for any purpose,
9 * including commercial applications, and to alter it and redistribute it
10 * freely, subject to the following restrictions:
11 *
12 * 1. The origin of this software must not be misrepresented; you must not
13 * claim that you wrote the original software. If you use this software
14 * in a product, an acknowledgment in the product documentation would be
15 * appreciated but is not required.
16 *
17 * 2. Altered source versions must be plainly marked as such, and must not be
18 * misrepresented as being the original software.
19 *
20 * 3. This notice may not be removed or altered from any source distribution.
21 */
22
26
27#ifndef LIBWS_MEMORY_H_
28#define LIBWS_MEMORY_H_
29
30#ifndef __ASSEMBLER__
31#include <stdbool.h>
32#include <stdint.h>
33#include <wonderful.h>
34#include "ports.h"
35#include "util.h"
36#endif
37
42
43#define WS_IRAM_SEGMENT 0x0000
44#define WS_SRAM_SEGMENT 0x1000
45#define WS_ROM0_SEGMENT 0x2000
46#define WS_ROM1_SEGMENT 0x3000
47
48#ifndef __ASSEMBLER__
49
55#define ws_iram __wf_iram
56
62#define ws_sram __wf_sram
63
71#define ws_rom __wf_rom
72
76#define ws_far __far
77
81#define ws_ptr_offset(x) ((uint16_t) (x))
82
86#define ws_ptr_segment(x) FP_SEG(x)
87
91#define ws_ptr_far(seg, ofs) MK_FP(seg, ofs)
92
96static inline uint32_t ws_ptr_to_linear(const void ws_far *src) {
97 return ((((uint32_t) src) >> 12) & 0xFFFF0) + ((uint16_t) ((uint32_t) src));
98}
99
103static inline const void ws_far *ws_ptr_from_linear(uint32_t src) {
104 return ws_ptr_far(src >> 4, src & 0xF);
105}
106
110#define WS_IRAM_MEM ((uint8_t ws_iram*) 0x00000000)
114#define WS_SRAM_MEM ((uint8_t ws_sram*) 0x10000000)
118#define WS_ROM0_MEM ((uint8_t __far*) 0x20000000)
122#define WS_ROM1_MEM ((uint8_t __far*) 0x30000000)
123
124#ifdef LIBWS_USE_EXTBANK
125typedef uint16_t ws_bank_t;
126
128static inline ws_bank_t _ws_bank_save(uint8_t port, ws_bank_t new_bank) {
129 asm volatile("" ::: "memory");
130 volatile ws_bank_t old_bank = inportw(port);
131 outportw(port, new_bank);
132 asm volatile("" ::: "memory");
133 return old_bank;
134}
135
136static inline ws_bank_t _ws_bank_get(uint8_t port) {
137 asm volatile("" ::: "memory");
138 volatile ws_bank_t old_bank = inportw(port);
139 asm volatile("" ::: "memory");
140 return old_bank;
141}
142
143static inline void _ws_bank_set(uint8_t port, ws_bank_t new_bank) {
144 asm volatile("" ::: "memory");
145 outportw(port, new_bank);
146 asm volatile("" ::: "memory");
147}
148
149#define _ws_bank_ram_port WS_CART_EXTBANK_RAM_PORT
150#define _ws_bank_rom0_port WS_CART_EXTBANK_ROM0_PORT
151#define _ws_bank_rom1_port WS_CART_EXTBANK_ROM1_PORT
152#define _ws_bank_roml_port WS_CART_EXTBANK_ROML_PORT
154#else
155typedef uint8_t ws_bank_t;
156
158static inline ws_bank_t _ws_bank_save(uint8_t port, ws_bank_t new_bank) {
159 asm volatile("" ::: "memory");
160 volatile ws_bank_t old_bank = inportb(port);
161 outportb(port, new_bank);
162 asm volatile("" ::: "memory");
163 return old_bank;
164}
165
166static inline ws_bank_t _ws_bank_get(uint8_t port) {
167 asm volatile("" ::: "memory");
168 volatile ws_bank_t old_bank = inportb(port);
169 asm volatile("" ::: "memory");
170 return old_bank;
171}
172
173static inline void _ws_bank_set(uint8_t port, ws_bank_t new_bank) {
174 asm volatile("" ::: "memory");
175 outportb(port, new_bank);
176 asm volatile("" ::: "memory");
177}
178
179#define _ws_bank_ram_port WS_CART_BANK_RAM_PORT
180#define _ws_bank_rom0_port WS_CART_BANK_ROM0_PORT
181#define _ws_bank_rom1_port WS_CART_BANK_ROM1_PORT
182#define _ws_bank_roml_port WS_CART_BANK_ROML_PORT
184#endif
185
187#define ws_bank_within_(var, loc, prev_bank, ...) \
188 { \
189 extern const void __bank_ ## var; \
190 __attribute__((cleanup(ws_bank_ ## loc ## _cleanup_))) \
191 ws_bank_t prev_bank = ws_bank_ ## loc ## _save((unsigned int) (&__bank_ ## var)); \
192 __VA_ARGS__ \
193 }
194
195#define ws_bank_with_(var, loc, prev_bank, ...) \
196 { \
197 __attribute__((cleanup(ws_bank_ ## loc ## _cleanup_))) \
198 ws_bank_t prev_bank = ws_bank_ ## loc ## _save((unsigned int) var); \
199 __VA_ARGS__ \
200 }
202
209#define ws_bank_ram_save(new_bank) _ws_bank_save(_ws_bank_ram_port, (new_bank))
210
216#define ws_bank_ram_get() _ws_bank_get(_ws_bank_ram_port)
217
223#define ws_bank_ram_set(new_bank) _ws_bank_set(_ws_bank_ram_port, (new_bank))
224#define ws_bank_ram_restore ws_bank_ram_set
226static inline void ws_bank_ram_cleanup_(ws_bank_t __wf_cstack* bank) { ws_bank_ram_restore(*bank); }
228
243#define ws_bank_within_ram(var, ...) ws_bank_within_(var, ram WF_MACRO_CONCAT(_wf_bank_, __COUNTER__), __VA_ARGS__)
244
258#define ws_bank_with_ram(bank, ...) ws_bank_with_(bank, ram, WF_MACRO_CONCAT(_wf_bank_, __COUNTER__), __VA_ARGS__)
259
265#define ws_bank_rom0_get() _ws_bank_get(_ws_bank_rom0_port)
266
273#define ws_bank_rom0_save(new_bank) _ws_bank_save(_ws_bank_rom0_port, (new_bank))
274
280#define ws_bank_rom0_set(new_bank) _ws_bank_set(_ws_bank_rom0_port, (new_bank))
281#define ws_bank_rom0_restore ws_bank_rom0_set
283static inline void ws_bank_rom0_cleanup_(ws_bank_t __wf_cstack* bank) { ws_bank_rom0_restore(*bank); }
285
300#define ws_bank_within_rom0(var, ...) ws_bank_within_(var, rom0, WF_MACRO_CONCAT(_wf_bank_, __COUNTER__), __VA_ARGS__)
301
315#define ws_bank_with_rom0(bank, ...) ws_bank_with_(bank, rom0, WF_MACRO_CONCAT(_wf_bank_, __COUNTER__), __VA_ARGS__)
316
323#define ws_bank_rom1_save(new_bank) _ws_bank_save(_ws_bank_rom1_port, (new_bank))
324
330#define ws_bank_rom1_get() _ws_bank_get(_ws_bank_rom1_port)
331
337#define ws_bank_rom1_set(new_bank) _ws_bank_set(_ws_bank_rom1_port, (new_bank))
338#define ws_bank_rom1_restore ws_bank_rom1_set
340static inline void ws_bank_rom1_cleanup_(ws_bank_t __wf_cstack* bank) { ws_bank_rom1_restore(*bank); }
342
357#define ws_bank_within_rom1(var, ...) ws_bank_within_(var, rom1, WF_MACRO_CONCAT(_wf_bank_, __COUNTER__), __VA_ARGS__)
358
372#define ws_bank_with_rom1(bank, ...) ws_bank_with_(bank, rom1, WF_MACRO_CONCAT(_wf_bank_, __COUNTER__), __VA_ARGS__)
373
380#define ws_bank_roml_save(new_bank) _ws_bank_save(_ws_bank_roml_port, (new_bank))
381
387#define ws_bank_roml_get() _ws_bank_get(_ws_bank_roml_port)
388
394#define ws_bank_roml_set(new_bank) _ws_bank_set(_ws_bank_roml_port, (new_bank))
395#define ws_bank_roml_restore ws_bank_roml_set
397static inline void ws_bank_roml_cleanup_(ws_bank_t __wf_cstack* bank) { ws_bank_roml_restore(*bank); }
399
414#define ws_bank_within_roml(var, ...) ws_bank_within_(var, roml, WF_MACRO_CONCAT(_wf_bank_, __COUNTER__), __VA_ARGS__)
415
429#define ws_bank_with_roml(bank, ...) ws_bank_with_(bank, roml, WF_MACRO_CONCAT(_wf_bank_, __COUNTER__), __VA_ARGS__)
430
432static inline void ws_bank_flash_cleanup_(volatile uint8_t __wf_cstack* val) { outportb(WS_CART_BANK_FLASH_PORT, *val); }
433
434#define ws_bank_with_flash_(var, prev_bank, ...) \
435 { \
436 __attribute__((cleanup(ws_bank_flash_cleanup_))) \
437 volatile uint8_t prev_bank = inportb(WS_CART_BANK_FLASH_PORT); \
438 outportb(WS_CART_BANK_FLASH_PORT, var); \
439 __VA_ARGS__ \
440 }
442
449#define ws_bank_with_flash(val, ...) ws_bank_with_flash_(val, WF_MACRO_CONCAT(_wf_bank_, __COUNTER__), __VA_ARGS__)
450
451#endif
452
454
455#endif /* LIBWS_MEMORY_H_ */
static void outportw(uint8_t port, uint16_t value)
Write a word to the given port.
Definition ia16.h:307
static void outportb(uint8_t port, uint8_t value)
Write a byte to the given port.
Definition ia16.h:293
static uint8_t inportb(uint8_t port)
Read a byte from the given port.
Definition ia16.h:261
static uint16_t inportw(uint8_t port)
Read a word from the given port.
Definition ia16.h:277
#define WS_CART_BANK_FLASH_PORT
Definition ports.h:39
static const void ws_far * ws_ptr_from_linear(uint32_t src)
Definition memory.h:103
#define ws_far
Definition memory.h:76
#define ws_bank_ram_restore
Definition memory.h:224
uint8_t ws_bank_t
Type indicating a bank index.
Definition memory.h:155
#define ws_bank_rom0_restore
Definition memory.h:281
static uint32_t ws_ptr_to_linear(const void ws_far *src)
Definition memory.h:96
#define ws_ptr_far(seg, ofs)
Definition memory.h:91
#define ws_bank_rom1_restore
Definition memory.h:338
#define ws_bank_roml_restore
Definition memory.h:395