libws libws
WSwan hardware library for the Wonderful toolchain
Loading...
Searching...
No Matches
display.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022, 2023 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
23#ifndef LIBWS_DISPLAY_H_
24#define LIBWS_DISPLAY_H_
25
26#ifndef __ASSEMBLER__
27#include <stdbool.h>
28#include <stdint.h>
29#endif
30#include <wonderful.h>
31#include "memory.h"
32#include "ports.h"
33
37
42
43#define WS_DISPLAY_WIDTH_TILES 28
44#define WS_DISPLAY_HEIGHT_TILES 18
45#define WS_DISPLAY_WIDTH_PIXELS (WS_DISPLAY_WIDTH_TILES * WS_DISPLAY_TILE_WIDTH)
46#define WS_DISPLAY_HEIGHT_PIXELS (WS_DISPLAY_HEIGHT_TILES * WS_DISPLAY_TILE_HEIGHT)
47
48#define WS_DISPLAY_TILE_WIDTH 8
49#define WS_DISPLAY_TILE_HEIGHT 8
53#define WS_DISPLAY_TILE_SIZE 16
57#define WS_DISPLAY_TILE_SIZE_4BPP 32
58
59#ifndef WS_DISPLAY_VTOTAL
63#define WS_DISPLAY_VTOTAL 159
64#endif
65
66#ifndef __ASSEMBLER__
67typedef struct {
70
71typedef struct {
74#endif
75
79#define WS_SCREEN_ATTR_TILE(x) (x)
80#define WS_SCREEN_ATTR_TILE_MASK (0x1FF)
84#define WS_SCREEN_ATTR_PALETTE(x) ((x) << 9)
85#define WS_SCREEN_ATTR_PALETTE_MASK (0xF << 9)
89#define WS_SCREEN_ATTR_BANK(x) ((x) << 13)
90#define WS_SCREEN_ATTR_BANK_MASK (0x2000)
94#define WS_SCREEN_ATTR_TILE_EX(x) (((x) & 0x1FF) | (((x) >> 13) << 13))
95#define WS_SCREEN_ATTR_TILE_EX_MASK (0x21FF)
96
100#define WS_SCREEN_ATTR_FLIP_H 0x4000
104#define WS_SCREEN_ATTR_FLIP_V 0x8000
108#define WS_SCREEN_ATTR_FLIP 0xC000
109#define WS_SCREEN_ATTR_FLIP_MASK 0xC000
110
111#define WS_SCREEN_WIDTH_TILES 32
112#define WS_SCREEN_HEIGHT_TILES 32
113#define WS_SCREEN_WIDTH_PIXELS (WS_SCREEN_WIDTH_TILES * WS_DISPLAY_TILE_WIDTH)
114#define WS_SCREEN_HEIGHT_PIXELS (WS_SCREEN_HEIGHT_TILES * WS_DISPLAY_TILE_HEIGHT)
115
116#ifndef __ASSEMBLER__
117typedef struct {
118 uint16_t attr;
119 uint8_t y;
120 uint8_t x;
122#endif
123
127#define WS_SPRITE_ATTR_PALETTE(x) ((x) << 9)
128#define WS_SPRITE_ATTR_PALETTE_MASK (0x7 << 9)
132#define WS_SPRITE_ATTR_OUTSIDE 0x1000
136#define WS_SPRITE_ATTR_PRIORITY 0x2000
140#define WS_SPRITE_ATTR_FLIP_H 0x4000
144#define WS_SPRITE_ATTR_FLIP_V 0x8000
148#define WS_SPRITE_ATTR_FLIP 0xC000
149#define WS_SPRITE_ATTR_FLIP_MASK 0xC000
150
151#define WS_SPRITE_MAX_COUNT 128
152
160#define WS_RGB(r, g, b) (((r) << 8) | ((g) << 4) | (b))
161
165#define WS_DISPLAY_MONO_PALETTE(c0, c1, c2, c3) ((c0) | ((c1) << 4) | ((c2) << 8) | ((c3) << 12))
166
167#ifndef __ASSEMBLER__
168
174#define WS_TILE_MEM(i) ((ws_display_tile_t ws_iram *) (0x2000 + ((i) << 4)))
175
181#define WS_TILE_4BPP_MEM(i) ((ws_display_tile_4bpp_t ws_iram *) (0x4000 + ((i) << 5)))
182
189#define WS_TILE_BANKED_MEM(b, i) ((ws_display_tile_t ws_iram *) (0x2000 + (!!(b) << 13) + ((i) << 4)))
190
197#define WS_TILE_4BPP_BANKED_MEM(b, i) ((ws_display_tile_4bpp_t ws_iram *) (0x4000 + (!!(b) << 14) + ((i) << 5)))
198
204#define WS_DISPLAY_COLOR_MEM(i) ((uint16_t ws_iram *) (0xFE00 + ((i) << 5)))
205
211#define WS_SCREEN_COLOR_MEM WS_DISPLAY_COLOR_MEM
212
218#define WS_SPRITE_COLOR_MEM(i) ((uint16_t ws_iram *) (0xFF00 + ((i) << 5)))
219
220#define WS_DISPLAY_SHADE_LUT(c0, c1, c2, c3, c4, c5, c6, c7) \
221 (((uint32_t)(c0)) | (((uint32_t)(c1)) << 4) | (((uint32_t)(c2)) << 8) | (((uint32_t)(c3)) << 12) | \
222 (((uint32_t)(c4)) << 16) | (((uint32_t)(c5)) << 20) | (((uint32_t)(c6)) << 24) | (((uint32_t)(c7)) << 28))
223#define WS_DISPLAY_SHADE_LUT_DEFAULT WS_DISPLAY_SHADE_LUT(0, 2, 4, 6, 9, 11, 13, 15)
224
225// TODO: Add ws_display_set_backdrop (has to consider mono/color modes have different values)
226
233static inline void ws_display_set_screen_addresses(const void __wf_iram* scr1_addr, const void __wf_iram* scr2_addr) {
234 outportb(WS_SCR_BASE_PORT, WS_SCR_BASE_ADDR1(scr1_addr) | WS_SCR_BASE_ADDR2(scr2_addr));
235}
236
243static inline void ws_display_set_screen_address(uint8_t screen, const void __wf_iram* address) {
244 outportb(WS_SCR_BASE_PORT, (inportb(WS_SCR_BASE_PORT) & (0xF0 >> (screen * 4))) | (WS_SCR_BASE_ADDR1(address) << (screen * 4)));
245}
246
252#define ws_display_set_screen1_address(address) ws_display_set_screen_address(0, (address))
253
259#define ws_display_set_screen2_address(address) ws_display_set_screen_address(1, (address))
260
266static inline void ws_display_set_sprite_address(const void __wf_iram* address) {
267 outportb(WS_SPR_BASE_PORT, WS_SPR_BASE_ADDR(address));
268}
269
278static inline void ws_display_set_screen2_window(uint8_t x, uint8_t y, uint8_t width, uint8_t height) {
279 outportw(WS_SCR2_WIN_X1_PORT, x | (y << 8));
280 outportw(WS_SCR2_WIN_X2_PORT, ((x + width - 1) & 0xFF) | ((y + height - 1) << 8));
281}
282
291static inline void ws_display_set_screen2_window_corners(uint8_t left, uint8_t top, uint8_t right, uint8_t bottom) {
292 outportw(WS_SCR2_WIN_X1_PORT, left | (top << 8));
293 outportw(WS_SCR2_WIN_X2_PORT, right | (bottom << 8));
294}
295
304static inline void ws_display_set_sprite_window(uint8_t x, uint8_t y, uint8_t width, uint8_t height) {
305 outportw(WS_SPR_WIN_X1_PORT, x | (y << 8));
306 outportw(WS_SPR_WIN_X2_PORT, ((x + width - 1) & 0xFF) | ((y + height - 1) << 8));
307}
308
317static inline void ws_display_set_sprite_window_corners(uint8_t left, uint8_t top, uint8_t right, uint8_t bottom) {
318 outportw(WS_SPR_WIN_X1_PORT, left | (top << 8));
319 outportw(WS_SPR_WIN_X2_PORT, right | (bottom << 8));
320}
321
329static inline void ws_display_scroll_screen_to(uint8_t screen, uint8_t x, uint8_t y) {
330 outportw(WS_SCR1_SCRL_X_PORT + (screen * 2), x | (y << 8));
331}
332
339#define ws_display_scroll_screen1_to(x, y) ws_display_scroll_screen_to(0, (x), (y))
340
347#define ws_display_scroll_screen2_to(x, y) ws_display_scroll_screen_to(1, (x), (y))
348
356void ws_display_scroll_screen_by(uint8_t screen, int16_t x, int16_t y);
357
365static inline uint8_t ws_display_get_current_line(void) {
366 return inportb(WS_DISPLAY_LINE_PORT);
367}
368
375static inline void ws_display_scroll_screen1_by(uint8_t x, uint8_t y) {
376 __asm (
377 "in $0x10, %%ax\nadd %0, %%al\nadd %1, %%ah\nout %%ax, $0x10"
378 : : "g"(x), "g"(y) : "a", "cc"
379 );
380}
381
388static inline void ws_display_scroll_screen2_by(uint8_t x, uint8_t y) {
389 __asm (
390 "in $0x12, %%ax\nadd %0, %%al\nadd %1, %%ah\nout %%ax, $0x12"
391 : : "g"(x), "g"(y) : "a", "cc"
392 );
393}
394
406static inline void ws_display_set_icons(uint8_t mask) {
407 outportb(WS_LCD_ICON_PORT, mask);
408}
409
421static inline void ws_display_show_icons(uint8_t mask) {
422 outportb(WS_LCD_ICON_PORT, inportb(WS_LCD_ICON_PORT) | mask);
423}
424
436static inline void ws_display_hide_icons(uint8_t mask) {
437 outportb(WS_LCD_ICON_PORT, inportb(WS_LCD_ICON_PORT) & ~mask);
438}
439
451static inline void ws_display_toggle_icons(uint8_t mask) {
452 outportb(WS_LCD_ICON_PORT, inportb(WS_LCD_ICON_PORT) ^ mask);
453}
454
462__attribute__((no_assume_ds_data, no_assume_ss_data, save_all))
463void ws_display_set_shade_lut(uint32_t lut);
464
475static inline void ws_screen_put_tiles(void ws_iram *dest, const void __far *src, uint16_t x, uint16_t y, uint16_t width, uint16_t height) {
476 void __libws_screen_put_tiles(void ws_iram *dest, const void __far *src, uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t pitch);
477 __libws_screen_put_tiles(dest, src, x, y, width, height, width);
478}
479
494static inline void ws_screen_put_tiles_ex(void ws_iram *dest, const void __far *src, uint16_t sx, uint16_t sy, uint16_t pitch, uint16_t dx, uint16_t dy, uint16_t width, uint16_t height) {
495 void __libws_screen_put_tiles(void ws_iram *dest, const void __far *src, uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t pitch);
496 __libws_screen_put_tiles(dest, ((const uint16_t __far*) src) + (sy * pitch) + sx, dx, dy, width, height, pitch);
497}
498
509void ws_screen_get_tiles(void __far *dest, const void ws_iram *src, uint16_t x, uint16_t y, uint16_t width, uint16_t height);
510
521void ws_screen_fill_tiles(void ws_iram *dest, uint16_t src, uint16_t x, uint16_t y, uint16_t width, uint16_t height);
522
534void ws_screen_modify_tiles(void ws_iram *dest, uint16_t mask, uint16_t value, uint16_t x, uint16_t y, uint16_t width, uint16_t height);
535
544static inline void ws_screen_put_tile(void ws_iram *dest, uint16_t src, uint16_t x, uint16_t y) {
545 ((uint16_t ws_iram*) dest)[((y & 0x1F) << 5) | (x & 0x1F)] = src;
546}
547
555static inline uint16_t ws_screen_get_tile(void ws_iram *src, uint16_t x, uint16_t y) {
556 return ((uint16_t ws_iram*) src)[((y & 0x1F) << 5) | (x & 0x1F)];
557}
558
559#endif
560
562
563#endif /* LIBWS_DISPLAY_H_ */
static void ws_display_scroll_screen1_by(uint8_t x, uint8_t y)
Scroll screen 1 by a specified number of pixels.
Definition display.h:375
static void ws_display_set_screen2_window(uint8_t x, uint8_t y, uint8_t width, uint8_t height)
Set the position and size of the screen 2 window.
Definition display.h:278
static void ws_screen_put_tiles_ex(void ws_iram *dest, const void __far *src, uint16_t sx, uint16_t sy, uint16_t pitch, uint16_t dx, uint16_t dy, uint16_t width, uint16_t height)
Place a map of tiles on the screen. This varianta llows specifying the source X position,...
Definition display.h:494
static void ws_display_toggle_icons(uint8_t mask)
Toggle specified LCD icons.
Definition display.h:451
static void ws_display_set_sprite_address(const void __wf_iram *address)
Set the base addresses of the sprite table.
Definition display.h:266
static void ws_display_scroll_screen2_by(uint8_t x, uint8_t y)
Scroll screen 2 by a specified number of pixels.
Definition display.h:388
void ws_display_scroll_screen_by(uint8_t screen, int16_t x, int16_t y)
Scroll the specified screen by a specified number of pixels.
static void ws_screen_put_tile(void ws_iram *dest, uint16_t src, uint16_t x, uint16_t y)
Put a tile on the screen.
Definition display.h:544
static void ws_display_set_icons(uint8_t mask)
Set the list of displayed LCD icons, clearing any unspecified icons.
Definition display.h:406
static void ws_display_set_screen_address(uint8_t screen, const void __wf_iram *address)
Set the base addresses of the specified screen.
Definition display.h:243
void ws_screen_fill_tiles(void ws_iram *dest, uint16_t src, uint16_t x, uint16_t y, uint16_t width, uint16_t height)
Fill an area on the screen with a given tile.
static void ws_display_scroll_screen_to(uint8_t screen, uint8_t x, uint8_t y)
Scroll the specified screen to a specified location.
Definition display.h:329
static void ws_display_set_screen2_window_corners(uint8_t left, uint8_t top, uint8_t right, uint8_t bottom)
Set the corners of the screen 2 window.
Definition display.h:291
static void ws_display_hide_icons(uint8_t mask)
Hide specified LCD icons.
Definition display.h:436
static uint16_t ws_screen_get_tile(void ws_iram *src, uint16_t x, uint16_t y)
Get a tile on the screen.
Definition display.h:555
void ws_screen_get_tiles(void __far *dest, const void ws_iram *src, uint16_t x, uint16_t y, uint16_t width, uint16_t height)
Copy a map of tiles from the screen.
static void ws_display_show_icons(uint8_t mask)
Show specified LCD icons.
Definition display.h:421
static void ws_screen_put_tiles(void ws_iram *dest, const void __far *src, uint16_t x, uint16_t y, uint16_t width, uint16_t height)
Place a map of tiles on the screen.
Definition display.h:475
static void ws_display_set_sprite_window(uint8_t x, uint8_t y, uint8_t width, uint8_t height)
Set the position and size of the sprite window.
Definition display.h:304
void ws_screen_modify_tiles(void ws_iram *dest, uint16_t mask, uint16_t value, uint16_t x, uint16_t y, uint16_t width, uint16_t height)
Modify an area on the screen with given data.
static void ws_display_set_screen_addresses(const void __wf_iram *scr1_addr, const void __wf_iram *scr2_addr)
Set the base addresses of screens 1 and 2.
Definition display.h:233
void ws_display_set_shade_lut(uint32_t lut)
Configure the shade LUT.
static uint8_t ws_display_get_current_line(void)
Get the line currently being drawn to the line buffer.
Definition display.h:365
#define WS_DISPLAY_TILE_HEIGHT
Definition display.h:49
static void ws_display_set_sprite_window_corners(uint8_t left, uint8_t top, uint8_t right, uint8_t bottom)
Set the corners of the sprite window.
Definition display.h:317
#define WS_SCR2_WIN_X2_PORT
Definition ports.h:242
#define WS_SPR_BASE_PORT
Definition ports.h:209
#define WS_SPR_BASE_ADDR(n)
Definition ports.h:210
#define WS_SPR_WIN_X1_PORT
Definition ports.h:252
#define WS_DISPLAY_LINE_PORT
Definition ports.h:199
#define WS_SCR1_SCRL_X_PORT
Definition ports.h:272
#define WS_SCR_BASE_ADDR1(n)
Definition ports.h:226
#define WS_SCR_BASE_ADDR2(n)
Definition ports.h:227
#define WS_SPR_WIN_X2_PORT
Definition ports.h:262
#define WS_LCD_ICON_PORT
Definition ports.h:325
#define WS_SCR2_WIN_X1_PORT
Definition ports.h:232
#define WS_SCR_BASE_PORT
Definition ports.h:225
#define ws_iram
Definition memory.h:55
uint32_t row[WS_DISPLAY_TILE_HEIGHT]
Definition display.h:72
uint16_t row[WS_DISPLAY_TILE_HEIGHT]
Definition display.h:68
uint8_t x
Definition display.h:120
uint8_t y
Definition display.h:119
uint16_t attr
Definition display.h:118