From a558f1a472717c36f34afeec9cb6962d87ef2454 Mon Sep 17 00:00:00 2001 From: Scott Duensing Date: Tue, 9 Jan 2024 21:46:37 -0600 Subject: [PATCH] Lots of refactoring to get tiles and sprites supported. --- examples/cube/cube.c | 25 ++++--- examples/pgztest/pgztest.c | 1 - f256lib/bitmap.c | 130 ++++++++++++++++++++++--------------- f256lib/bitmap.h | 4 +- f256lib/dma.c | 2 +- f256lib/f256.c | 41 ++---------- f256lib/f256.h | 30 ++++----- f256lib/graphics.c | 82 +++++++++++++++++++++++ f256lib/graphics.h | 63 ++++++++++++++++++ f256lib/kernel.c | 42 ++++++++++++ f256lib/kernel.h | 57 ++++++++++++++++ f256lib/math.c | 42 +++++++++++- f256lib/math.h | 7 +- f256lib/random.c | 41 ++++++++++++ f256lib/random.h | 46 +++++++++++++ f256lib/text.c | 36 +++++----- f256lib/tile.c | 26 ++++++++ f256lib/tile.h | 43 ++++++++++++ 18 files changed, 579 insertions(+), 139 deletions(-) create mode 100644 f256lib/graphics.c create mode 100644 f256lib/graphics.h create mode 100644 f256lib/kernel.c create mode 100644 f256lib/kernel.h create mode 100644 f256lib/random.c create mode 100644 f256lib/random.h create mode 100644 f256lib/tile.c create mode 100644 f256lib/tile.h diff --git a/examples/cube/cube.c b/examples/cube/cube.c index f4abe19..848a6c1 100644 --- a/examples/cube/cube.c +++ b/examples/cube/cube.c @@ -27,15 +27,13 @@ #include "f256.h" -int16_t _remainder; - #define FIX_PREC 9 #define TO_FIX(x) ((int32_t)((x)*(1<>FIX_PREC) // ((x)/(1<> FIX_PREC) #define fix_sqr(am) (mathSignedMultiply(am, am) >> FIX_PREC) -#define fix_div(num,den) (mathSignedMultiply(mathUnSignedDivision(0x8000, (den >> 1), (uint16_t *)&_remainder), num) >> 7) // ((a << FIX_PREC) / b) +#define fix_div(num,den) (mathSignedMultiply(mathUnsignedDivision(0x8000, (den >> 1)), num) >> 7) // ((a << FIX_PREC) / b) #define SIN_SIZE 512 #define COS_OFF 128 @@ -103,8 +101,8 @@ typedef struct lineS { } lineT; int16_t *COS = SIN + COS_OFF; -uint16_t width; -uint16_t height; +uint16_t widthOffset; +uint16_t heightOffset; int32_t a = TO_FIX(4); int32_t scale = TO_FIX(40); lineT past[12][2]; @@ -158,8 +156,8 @@ void draw_cube(byte p, int16_t t) { // Projection to screen space cubeProjX[i] = fix_div(fix_mul(a, cubeRotX[i]), cubeRotZ[i]); cubeProjY[i] = fix_div(fix_mul(a, cubeRotY[i]), cubeRotZ[i]); - cubeProjX[i] = TO_LONG(fix_mul(cubeProjX[i], scale)) + width; - cubeProjY[i] = TO_LONG(fix_mul(cubeProjY[i], scale)) + height; + cubeProjX[i] = TO_LONG(fix_mul(cubeProjX[i], scale)) + widthOffset; + cubeProjY[i] = TO_LONG(fix_mul(cubeProjY[i], scale)) + heightOffset; } l = 0; @@ -183,9 +181,16 @@ int main(void) { textSetCursor(0); // No cursor. - bitmapGetResolution(&width, &height); - width = width >> 1; - height = height >> 1; + // Clear two graphics pages. + bitmapSetColor(0); + bitmapSetPage(0); + bitmapClear(); + bitmapSetPage(1); + bitmapClear(); + + bitmapGetResolution(&widthOffset, &heightOffset); + widthOffset = widthOffset >> 1; + heightOffset = heightOffset >> 1; while(1) { if (p) { diff --git a/examples/pgztest/pgztest.c b/examples/pgztest/pgztest.c index 29f8673..fcda9b3 100644 --- a/examples/pgztest/pgztest.c +++ b/examples/pgztest/pgztest.c @@ -97,6 +97,5 @@ int main(void) { f256Init(); text(); bitmap(); - //bitmapReset(); // BOOM! return 0; } diff --git a/f256lib/bitmap.c b/f256lib/bitmap.c index c37250d..d9bc20f 100644 --- a/f256lib/bitmap.c +++ b/f256lib/bitmap.c @@ -32,8 +32,10 @@ static uint16_t _MAX_X; static uint16_t _MAX_Y; static uint32_t _PAGE_SIZE; static uint32_t _BITMAP_BASE[3]; // Maximum of 3 pages possible. +static byte _BITMAP_CLUT[3]; static byte _color; -static byte _page; +static byte _page; // Current drawing page. +static byte _pages; // Number of active pages. void bitmapClear(void) { @@ -44,36 +46,20 @@ void bitmapClear(void) { byte block = _BITMAP_BASE[_page] / EIGHTK; byte x; uint16_t c; - volatile byte *mem = (byte *)0xa000; + volatile byte *mem = (byte *)SWAP_ADDR; // Clear full 8k blocks. for (x=0; x<9; x++) { - POKE(MMU_MEM_BANK_5, block++); + POKE(SWAP_SLOT, block++); for (c=0; cmember) -#define EVENT(member) (size_t)(&((struct events *)0)->member) -#define CALL(fn) \ - asm("jsr %[addy] \n" \ - "stz %[err] \n" \ - "ror %[err]" \ - : [err] "+m"(error) \ - : [addy] "i"(VECTOR(fn)) \ - : "a", "x", "y", "c", "v"); - - -extern struct event_t event; // The event struct is allocated in crt0. -extern char error; - void f256Init(void); -uint16_t randomRead(void); -void randomSeed(uint16_t seed); -void waitVerticalBlank(void); -#include "text.h" -#include "bitmap.h" +#include "kernel.h" #include "dma.h" #include "math.h" +#include "random.h" +#include "text.h" +#include "bitmap.h" +#include "tile.h" +#include "graphics.h" #ifdef __cplusplus diff --git a/f256lib/graphics.c b/f256lib/graphics.c new file mode 100644 index 0000000..4571034 --- /dev/null +++ b/f256lib/graphics.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2024 Scott Duensing, scott@kangaroopunch.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +#include "graphics.h" + + + +void graphicsDefineColor(uint16_t clut, byte slot, byte r, byte g, byte b) { + byte mmu = PEEK(MMU_IO_CTRL); // Get current MMU state. + byte *write; + + POKE(MMU_IO_CTRL, MMU_IO_PAGE_1); // Swap I/O page 1 into bank 6. + + write = (byte *)mathUnsignedAddition(clut, mathUnsignedMultiply(slot, 4)); + *write++ = b; + *write++ = g; + *write++ = r; + *write++ = 0xff; + + POKE(MMU_IO_CTRL, mmu); // Restore MMU state. +} + + +void graphicsReset() { + int16_t x; + byte y; + uint16_t cluts[] = { GRAPHICS_CLUT_0, GRAPHICS_CLUT_1, GRAPHICS_CLUT_2, GRAPHICS_CLUT_3 }; + + // Set palettes to a gradient so there's at least *something*. + for (y=0; y<4; y++) { + for (x=0; x<256; x++) { + graphicsDefineColor(cluts[y], x, x, x, x); + } + } + + graphicsSetLayerType(0, GRAPHICS_BITMAP_0); + graphicsSetLayerType(1, GRAPHICS_BITMAP_1); + graphicsSetLayerType(2, GRAPHICS_BITMAP_2); +} + + +void graphicsSetLayerType(byte layer, byte what) { + switch (layer) { + case 0: + POKE(VKY_LAYER_CTRL_0, (PEEK(VKY_LAYER_CTRL_0) & 0xf0) | what); + break; + case 1: + POKE(VKY_LAYER_CTRL_0, (PEEK(VKY_LAYER_CTRL_0) & 0x0f) | (what << 4)); + break; + case 2: + POKE(VKY_LAYER_CTRL_1, what); + break; + } +} + + +void graphicsWaitVerticalBlank(void) { + //***TODO*** This assumes we're 60hz with graphics enabled. + while (PEEKW(RAST_ROW_L) != 482) + // Spin our wheels. + ; +} diff --git a/f256lib/graphics.h b/f256lib/graphics.h new file mode 100644 index 0000000..6c6e3ac --- /dev/null +++ b/f256lib/graphics.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2024 Scott Duensing, scott@kangaroopunch.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +#ifndef GRAPHICS_H +#define GRAPHICS_H + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +#include "f256.h" + + +// Names to match the library. +#define GRAPHICS_CLUT_0 VKY_GR_CLUT_0 +#define GRAPHICS_CLUT_1 VKY_GR_CLUT_1 +#define GRAPHICS_CLUT_2 VKY_GR_CLUT_2 +#define GRAPHICS_CLUT_3 VKY_GR_CLUT_3 + +#define GRAPHICS_BITMAP_0 0 +#define GRAPHICS_BITMAP_1 1 +#define GRAPHICS_BITMAP_2 2 + +#define GRAPHICS_TILE_0 4 +#define GRAPHICS_TILE_1 5 +#define GRAPHICS_TILE_2 6 + + +void graphicsDefineColor(uint16_t clut, byte slot, byte r, byte g, byte b); +void graphicsReset(); +void graphicsSetLayerType(byte layer, byte what); +void graphicsWaitVerticalBlank(void); + + +#ifdef __cplusplus +} +#endif + + +#endif // GRAPHICS_H diff --git a/f256lib/kernel.c b/f256lib/kernel.c new file mode 100644 index 0000000..28fcc82 --- /dev/null +++ b/f256lib/kernel.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2024 Scott Duensing, scott@kangaroopunch.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +#include "kernel.h" + + +char error; + + +/* +RTC_BUFFER .dstruct kernel.time_t + +kGetTimeStamp + lda #RTC_BUFFER + sta kernel.args.buf+1 + lda #size(kernel.time_t) + sta kernel.args.buflen + jsr kernel.Clock.GetTime + rts +*/ diff --git a/f256lib/kernel.h b/f256lib/kernel.h new file mode 100644 index 0000000..1c789c4 --- /dev/null +++ b/f256lib/kernel.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2024 Scott Duensing, scott@kangaroopunch.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +#ifndef KERNEL_H +#define KERNEL_H + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +#include "f256.h" + + +#define VECTOR(member) (size_t)(&((struct call *)0xff00)->member) +#define EVENT(member) (size_t)(&((struct events *)0)->member) +#define CALL(fn) \ + asm("jsr %[addy] \n" \ + "stz %[err] \n" \ + "ror %[err]" \ + : [err] "+m"(error) \ + : [addy] "i"(VECTOR(fn)) \ + : "a", "x", "y", "c", "v"); + + +extern struct event_t event; // The event struct is allocated in crt0. Or is it? +extern char error; + + +#ifdef __cplusplus +} +#endif + + +#endif // KERNEL_H diff --git a/f256lib/math.c b/f256lib/math.c index 958c7c6..9dac46e 100644 --- a/f256lib/math.c +++ b/f256lib/math.c @@ -24,7 +24,31 @@ #include "math.h" -int16_t mathSignedDivision(int16_t a, int16_t b, int16_t *remainder) { +int16_t mathSignedDivision(int16_t a, int16_t b) { + byte signA = 0; // Zero indicates positive. + byte signB = 0; + int16_t r; + + if (a < 0) { + signA = 1; + a = -a; + } + if (b < 0) { + signB = 1; + b = -b; + } + + POKEW(DIVU_NUM_L, a); + POKEW(DIVU_DEN_L, b); + r = PEEKW(QUOU_LL); + + if (signA + signB == 1) r = -r; + + return r; +} + + +int16_t mathSignedDivisionRemainder(int16_t a, int16_t b, int16_t *remainder) { byte signA = 0; // Zero indicates positive. byte signB = 0; int16_t r; @@ -73,7 +97,21 @@ int32_t mathSignedMultiply(int16_t a, int16_t b) { } -uint16_t mathUnSignedDivision(uint16_t a, uint16_t b, uint16_t *remainder) { +uint32_t mathUnsignedAddition(uint32_t a, uint32_t b) { + POKED(ADD_A_LL, a); + POKED(ADD_B_LL, b); + return PEEKD(ADD_R_LL); +} + + +uint16_t mathUnsignedDivision(uint16_t a, uint16_t b) { + POKEW(DIVU_NUM_L, a); + POKEW(DIVU_DEN_L, b); + return PEEKW(QUOU_LL); +} + + +uint16_t mathUnsignedDivisionRemainder(uint16_t a, uint16_t b, uint16_t *remainder) { POKEW(DIVU_NUM_L, a); POKEW(DIVU_DEN_L, b); *remainder = PEEKW(REMU_HL); diff --git a/f256lib/math.h b/f256lib/math.h index c3e9a66..641f9f9 100644 --- a/f256lib/math.h +++ b/f256lib/math.h @@ -34,9 +34,12 @@ extern "C" #include "f256.h" -int16_t mathSignedDivision(int16_t a, int16_t b, int16_t *remainder); +int16_t mathSignedDivision(int16_t a, int16_t b); +int16_t mathSignedDivisionRemainder(int16_t a, int16_t b, int16_t *remainder); int32_t mathSignedMultiply(int16_t a, int16_t b); -uint16_t mathUnSignedDivision(uint16_t a, uint16_t b, uint16_t *remainder); +uint32_t mathUnsignedAddition(uint32_t a, uint32_t b); +uint16_t mathUnsignedDivision(uint16_t a, uint16_t b); +uint16_t mathUnsignedDivisionRemainder(uint16_t a, uint16_t b, uint16_t *remainder); uint32_t mathUnsignedMultiply(uint16_t a, uint16_t b); diff --git a/f256lib/random.c b/f256lib/random.c new file mode 100644 index 0000000..3425f4a --- /dev/null +++ b/f256lib/random.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2024 Scott Duensing, scott@kangaroopunch.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +#include "random.h" + + +uint16_t randomRead(void) { + uint16_t result; + + POKE(VKY_RND_CTRL, 1); // Enable. + result = PEEKW(VKY_RNDL); + + return result; +} + + +void randomSeed(uint16_t seed) { + POKEW(VKY_SEEDL, seed); + POKE(VKY_RND_CTRL, 3); // Enable, load seed. +} + diff --git a/f256lib/random.h b/f256lib/random.h new file mode 100644 index 0000000..76cd555 --- /dev/null +++ b/f256lib/random.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024 Scott Duensing, scott@kangaroopunch.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +#ifndef RANDOM_H +#define RANDOM_H + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +#include "f256.h" + + +uint16_t randomRead(void); +void randomSeed(uint16_t seed); + + +#ifdef __cplusplus +} +#endif + + +#endif // RANDOM_H diff --git a/f256lib/text.c b/f256lib/text.c index 512d74b..7aba65c 100644 --- a/f256lib/text.c +++ b/f256lib/text.c @@ -22,6 +22,7 @@ #include "text.h" +#include "math.h" colorT textColors[16] = { @@ -55,16 +56,17 @@ static byte _ccolor = 240; // Clear screen to current text attributes. void textClear(void) { - byte mmu = PEEK(MMU_IO_CTRL); // Get current MMU state. - int i; - volatile byte *vram = (byte *)TEXT_MATRIX; + byte mmu = PEEK(MMU_IO_CTRL); // Get current MMU state. + int16_t i; + int16_t count = mathUnsignedMultiply(_MAX_COL, _MAX_ROW); + volatile byte *vram = (byte *)TEXT_MATRIX; POKE(MMU_IO_CTRL, MMU_IO_TEXT); // Swap I/O page 2 into bank 6. - for (i = 0; i < _MAX_COL * _MAX_ROW; i++) *vram++ = 32; + for (i=0; i 9) textPrintInt(value / 10); + if (value > 9) textPrintInt(mathUnsignedDivision(value, 10)); c[0] = '0' + (value % 10); c[1] = 0; @@ -186,8 +188,7 @@ void textReset(void) { _bcolor = 0; _ccolor = 240; - POKE(VKY_CRSR_CTRL, 3); // Enable cursor, 1/2s flash. - POKE(VKY_CRSR_CHAR, '_'); // Set cursor shape. (199 = Checkerboard) + textSetCursor('_'); // Set up default text colors. for (x=0; x