Skip to content

Commit 460a72c

Browse files
committed
nullbios: implement fix_clear and lsp_1st BIOS calls
1 parent 8c0bae6 commit 460a72c

File tree

3 files changed

+107
-2
lines changed

3 files changed

+107
-2
lines changed

nullbios/biosstart.S

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,9 @@ _unused_jmptable_slots:
115115
jmp bios_noop.l
116116
.endr
117117
bios_fix_clear:
118-
jmp not_implemented.l
118+
jmp impl_fix_clear.l
119119
bios_lsp_1st:
120-
jmp not_implemented.l
120+
jmp impl_lsp_1st.l
121121
bios_mess_out:
122122
jmp not_implemented.l
123123
bios_controller_setup:

nullbios/gfx.c

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* controllers management for BIOS
3+
* Copyright (c) 2025 Damien Ciabrini
4+
* This file is part of ngdevkit
5+
*
6+
* ngdevkit is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU Lesser General Public License as
8+
* published by the Free Software Foundation, either version 3 of the
9+
* License, or (at your option) any later version.
10+
*
11+
* ngdevkit is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with ngdevkit. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
20+
#include <ngdevkit/bios-backup-ram.h>
21+
#include <ngdevkit/registers.h>
22+
#include "utils.h"
23+
24+
// Note: when gcc determines that a variable holds a constant rvalues,
25+
// it skips register assignment and generate instructions with
26+
// immediate addressing mode instead, which can be suboptimal.
27+
//
28+
// In the functions below, we use asm block to assign variables for
29+
// which gcc must not perform constant optimizations. This yields
30+
// better performance:
31+
// - peephole generates faster loops that use the "dbra" opcode
32+
// - the memory writes in the loop have a smaller code size
33+
34+
// BIOS public API
35+
36+
#define OPAQUE_TILE 0x20
37+
#define TRANSPARENT_TILE 0xff
38+
39+
void impl_fix_clear() {
40+
s16 loop;
41+
u16 tile;
42+
43+
volatile u16 *vram;
44+
// VRAM access: beginning of tile map, 1 byte per write (next tile down)
45+
*REG_VRAMADDR = ADDR_FIXMAP;
46+
*REG_VRAMMOD = 1;
47+
SET_CONST_ADDR(vram, REG_VRAMRW);
48+
49+
// left column
50+
SET_CONST_W(loop, 32-1);
51+
SET_CONST_W(tile, OPAQUE_TILE);
52+
do { *vram = tile; } while(--loop != -1);
53+
// full center tilemap
54+
SET_CONST_W(loop, 32*38-1);
55+
SET_CONST_W(tile, TRANSPARENT_TILE);
56+
do { *vram = tile; } while(--loop != -1);
57+
// right column
58+
SET_CONST_W(loop, 32-1);
59+
SET_CONST_W(tile, OPAQUE_TILE);
60+
do { *vram = tile; } while(--loop != -1);
61+
}
62+
63+
64+
#define SCB2_VAL(zx, zy) (((zx)<<8) | (zy))
65+
#define SCB3_VAL(y, sticky, size) ((((y))<<7) | ((sticky)<<6) | (size))
66+
#define SCB4_VAL(x) ((x)<<7)
67+
68+
void impl_lsp_1st() {
69+
s16 loop;
70+
u16 val;
71+
72+
volatile u16 *vram;
73+
// VRAM access: sprite attributes, 1 byte per write (to next sprite)
74+
*REG_VRAMADDR = ADDR_SCB2;
75+
*REG_VRAMMOD = 1;
76+
SET_CONST_ADDR(vram, REG_VRAMRW);
77+
78+
// current VRAM pointer: SCB2
79+
// reset shrink coefficient: max x (0xf) | max y (0xff)
80+
SET_CONST_W(loop, 512-1);
81+
SET_CONST_W(val, SCB2_VAL(0xf, 0xff));
82+
do { *vram = val; } while(--loop != -1);
83+
// current VRAM pointer: SCB3
84+
// reset vertical position: topmost (0)
85+
SET_CONST_W(loop, 512-1);
86+
SET_CONST_W(val, SCB3_VAL(0, 0, 0));
87+
do { *vram = val; } while(--loop != -1);
88+
// current VRAM pointer: SCB4
89+
// reset horizontal position: leftmost (0)
90+
SET_CONST_W(loop, 512-1);
91+
SET_CONST_W(val, SCB4_VAL(380));
92+
do { *vram = val; } while(--loop != -1);
93+
// special case: configure all tiles of 1st sprite to be transparent
94+
*REG_VRAMADDR = ADDR_SCB1;
95+
*REG_VRAMMOD = 2;
96+
SET_CONST_W(loop, 32-1);
97+
SET_CONST_W(val, TRANSPARENT_TILE);
98+
do { *vram = val; } while(--loop != -1);
99+
}

nullbios/utils.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,10 @@
4444
: "d" ((y)) \
4545
: "cc")
4646

47+
#define SET_CONST_W(var, cst) \
48+
__asm__ ("move.w %1, %0" : "=r" (var) : "i" (cst) :);
49+
50+
#define SET_CONST_ADDR(var, cst) \
51+
__asm__ ("movea.l %1, %0" : "=r" (var) : "i" (cst) :);
52+
4753
#endif /* __NULLBIOS_UTILS_H__ */

0 commit comments

Comments
 (0)