9 # error This is a userspace-only header, not allowed by the current build.
12 #include <sifteo/abi.h>
13 #include <sifteo/macros.h>
14 #include <sifteo/math.h>
31 template <
unsigned tW
idth,
unsigned tHeight,
unsigned tBitsPerPixel>
33 _SYSAttachedVideoBuffer sys;
53 return vec(tWidth, tHeight);
61 return 1 << tBitsPerPixel;
76 return tWidth * tHeight * tBitsPerPixel / 8;
83 return tWidth * tHeight * tBitsPerPixel / 16;
97 ASSERT(pos.
x <= tWidth && pos.
y <= tHeight);
99 const unsigned pixelsPerByte = 8 / tBitsPerPixel;
100 const unsigned bytesPerLine = tWidth / pixelsPerByte;
101 const unsigned xByte = pos.
x / pixelsPerByte;
102 const unsigned xBit = (pos.
x % pixelsPerByte) * tBitsPerPixel;
103 const unsigned byteAddr = xByte + pos.
y * bytesPerLine;
104 const unsigned pixelMask = ((1 << tBitsPerPixel) - 1) << xBit;
106 uint8_t byte = _SYS_vbuf_peekb(&sys.vbuf, byteAddr);
108 byte |= colorIndex << xBit;
109 _SYS_vbuf_pokeb(&sys.vbuf, byteAddr, byte);
121 switch (tBitsPerPixel) {
122 case 1:
return colorIndex ? 0xFFFF : 0x0000;
123 case 2: colorIndex |= colorIndex << 2;
124 case 4: colorIndex |= colorIndex << 4;
125 case 8: colorIndex |= colorIndex << 8;
126 case 16:
return colorIndex;
139 ASSERT(pos.
x <= tWidth && width <= tWidth &&
140 (pos.
x + width) <= tWidth && pos.
y < tHeight);
142 const unsigned pixelsPerWord = 16 / tBitsPerPixel;
143 const unsigned wordsPerLine = tWidth / pixelsPerWord;
144 const unsigned colorWord =
expand16(colorIndex);
148 unsigned addr = pos.
x / pixelsPerWord + pos.
y * wordsPerLine;
149 int start = (pos.
x % pixelsPerWord) * tBitsPerPixel;
150 int end = start + width * tBitsPerPixel;
153 if (start <= 0 && end >= 16) {
156 unsigned count = end / 16;
157 _SYS_vbuf_fill(&sys.vbuf, addr, colorWord, count);
159 unsigned bits = count * 16;
166 unsigned mask = bitRange<uint16_t>(start, end);
167 unsigned word = _SYS_vbuf_peek(&sys.vbuf, addr);
169 word |= colorWord & mask;
170 _SYS_vbuf_poke(&sys.vbuf, addr, word);
187 span(topLeft, size.
x, colorIndex);
209 ASSERT(pos.
x <= tWidth && width <= tWidth &&
210 (pos.
x + width) <= tWidth && pos.
y < tHeight);
212 const unsigned pixelsPerByte = 8 / tBitsPerPixel;
213 const unsigned bytesPerLine = tWidth / pixelsPerByte;
216 unsigned addr = pos.
x / pixelsPerByte + pos.
y * bytesPerLine;
219 unsigned shift = (pos.
x % pixelsPerByte) * tBitsPerPixel;
220 unsigned invShift = 8 - shift;
224 int end = start + width * tBitsPerPixel;
230 uint8_t source = *data;
234 unsigned mask = (0xFF << shift) & bitRange<uint16_t>(start, end);
235 unsigned byte = _SYS_vbuf_peekb(&sys.vbuf, addr);
237 byte |= (source << shift) & mask;
238 _SYS_vbuf_pokeb(&sys.vbuf, addr, byte);
246 unsigned mask = (0xFF >> invShift) & bitRange<uint16_t>(start, end);
247 unsigned byte = _SYS_vbuf_peekb(&sys.vbuf, addr);
249 byte |= (source >> invShift) & mask;
250 _SYS_vbuf_pokeb(&sys.vbuf, addr, byte);
282 void set(
const uint16_t *data) {
283 _SYS_vbuf_write(&sys.vbuf, 0, data,
sizeInWords());
322 _SYSAttachedVideoBuffer sys;
332 ASSERT((pixelSize.
x & 1) == 0 &&
333 pixelSize.
x * pixelSize.
y <= 1536 &&
334 pixelSize.
x <= 128 &&
337 _SYS_vbuf_poke(&sys.vbuf,
offsetof(_SYSVideoRAM, stamp_pitch)/2,
338 (pixelSize.
x >> 1) | (pixelSize.
y << 8));
351 template <
unsigned tW
idth,
unsigned tHeight>
368 template <
unsigned tW
idth,
unsigned tHeight>
373 return getFB<tWidth, tHeight>();
385 _SYS_vbuf_poke(&sys.vbuf,
offsetof(_SYSVideoRAM, stamp_x)/2,
386 firstColumn | (numColumns << 8));
397 _SYS_vbuf_poke(&sys.vbuf,
offsetof(_SYSVideoRAM, first_line)/2,
398 topLeft.
y | (size.
y << 8));
409 _SYS_vbuf_pokeb(&sys.vbuf,
offsetof(_SYSVideoRAM, stamp_key), index);