diff --git a/examples/cube/CMakeLists.txt b/examples/cube/CMakeLists.txt new file mode 100644 index 0000000..da75b7d --- /dev/null +++ b/examples/cube/CMakeLists.txt @@ -0,0 +1,50 @@ +# +# 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. +# + + +# This is only to make my IDE happy. +# We can't actually build with it until I get llvm-mos integrated into +# toolchains. -- SCD + + +cmake_minimum_required(VERSION 3.22) +set(CMAKE_C_STANDARD 17) +project(cube) + +set(DEFINES ${CMAKE_SOURCE_DIR}/../../include) +set(F256LIB ${CMAKE_SOURCE_DIR}/../../f256lib) + +set(CUBE_SOURCE + ${F256LIB}/f256.h + ${F256LIB}/f256.c + cube.c +) + +add_executable(${CMAKE_PROJECT_NAME} + ${CUBE_SOURCE} +) + +target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC + ${CMAKE_SOURCE_DIR} + ${DEFINES} + ${F256LIB} +) diff --git a/examples/cube/build.sh b/examples/cube/build.sh new file mode 100755 index 0000000..60307e7 --- /dev/null +++ b/examples/cube/build.sh @@ -0,0 +1,51 @@ +#!/bin/bash -ex + +# +# 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. +# + + +F256=$(pwd)/../.. +LLVM=${F256}/llvm-mos +SETTINGS=${LLVM}/mos-platform/f256k/lib/settings.ld +PATH=${LLVM}/bin:${PATH} + +START=0x2000 + +echo "__f256_start = ${START};" > ${SETTINGS} + +CLANG="mos-f256k-clang -I${F256}/include -I${F256}/f256lib -Os" + +${CLANG} -c ${F256}/f256lib/f256.c +${CLANG} -c cube.c +${CLANG} -o cube cube.o f256.o + +mv -f cube cube.bin + +${F256}/header/header \ + pgz 24 \ + cube.pgz \ + ${START} \ + cube.bin ${START} + +#llvm-nm cube.elf > cube.lst +llvm-objdump -d --print-imm-hex cube.elf > cube.lst +hexdump -C cube.pgz > cube.hex diff --git a/examples/cube/cube.c b/examples/cube/cube.c new file mode 100644 index 0000000..62c62cd --- /dev/null +++ b/examples/cube/cube.c @@ -0,0 +1,196 @@ +/* + * 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. + */ + + +// Ported from https://github.com/root42/doscube + + +#include "f256.h" + + +#define FIX_PREC 9 +#define TO_FIX(x) ((int32_t)((x)*(1<> FIX_PREC) +#define fix_sqr(a) ((a * a) >> FIX_PREC) +#define fix_div(a,b) ((a << FIX_PREC) / b) + +#define SIN_SIZE 512 +#define COS_OFF 128 + + +int32_t SIN[] = { 0, 6, 12, 18, 25, 31, 37, 43, 50, 56, 62, 68, 75, 81, 87, 93, + 99, 106, 112, 118, 124, 130, 136, 142, 148, 154, 160, 166, 172, + 178, 184, 190, 195, 201, 207, 213, 218, 224, 230, 235, 241, 246, + 252, 257, 263, 268, 273, 279, 284, 289, 294, 299, 304, 310, 314, + 319, 324, 329, 334, 339, 343, 348, 353, 357, 362, 366, 370, 375, + 379, 383, 387, 391, 395, 399, 403, 407, 411, 414, 418, 422, 425, + 429, 432, 435, 439, 442, 445, 448, 451, 454, 457, 460, 462, 465, + 468, 470, 473, 475, 477, 479, 482, 484, 486, 488, 489, 491, 493, + 495, 496, 498, 499, 500, 502, 503, 504, 505, 506, 507, 508, 508, + 509, 510, 510, 511, 511, 511, 511, 511, 512, 511, 511, 511, 511, + 511, 510, 510, 509, 508, 508, 507, 506, 505, 504, 503, 502, 500, + 499, 498, 496, 495, 493, 491, 489, 488, 486, 484, 482, 479, 477, + 475, 473, 470, 468, 465, 462, 460, 457, 454, 451, 448, 445, 442, + 439, 435, 432, 429, 425, 422, 418, 414, 411, 407, 403, 399, 395, + 391, 387, 383, 379, 375, 370, 366, 362, 357, 353, 348, 343, 339, + 334, 329, 324, 319, 314, 310, 304, 299, 294, 289, 284, 279, 273, + 268, 263, 257, 252, 246, 241, 235, 230, 224, 218, 213, 207, 201, + 195, 190, 184, 178, 172, 166, 160, 154, 148, 142, 136, 130, 124, + 118, 112, 106, 99, 93, 87, 81, 75, 68, 62, 56, 50, 43, 37, 31, + 25, 18, 12, 6, 0, -6, -12, -18, -25, -31, -37, -43, -50, -56, + -62, -68, -75, -81, -87, -93, -99, -106, -112, -118, -124, -130, + -136, -142, -148, -154, -160, -166, -172, -178, -184, -190, -195, + -201, -207, -213, -218, -224, -230, -235, -241, -246, -252, -257, + -263, -268, -273, -279, -284, -289, -294, -299, -304, -310, -314, + -319, -324, -329, -334, -339, -343, -348, -353, -357, -362, -366, + -370, -375, -379, -383, -387, -391, -395, -399, -403, -407, -411, + -414, -418, -422, -425, -429, -432, -435, -439, -442, -445, -448, + -451, -454, -457, -460, -462, -465, -468, -470, -473, -475, -477, + -479, -482, -484, -486, -488, -489, -491, -493, -495, -496, -498, + -499, -500, -502, -503, -504, -505, -506, -507, -508, -508, -509, + -510, -510, -511, -511, -511, -511, -511, -512, -511, -511, -511, + -511, -511, -510, -510, -509, -508, -508, -507, -506, -505, -504, + -503, -502, -500, -499, -498, -496, -495, -493, -491, -489, -488, + -486, -484, -482, -479, -477, -475, -473, -470, -468, -465, -462, + -460, -457, -454, -451, -448, -445, -442, -439, -435, -432, -429, + -425, -422, -418, -414, -411, -407, -403, -399, -395, -391, -387, + -383, -379, -375, -370, -366, -362, -357, -353, -348, -343, -339, + -334, -329, -324, -319, -314, -310, -304, -299, -294, -289, -284, + -279, -273, -268, -263, -257, -252, -246, -241, -235, -230, -224, + -218, -213, -207, -201, -195, -190, -184, -178, -172, -166, -160, + -154, -148, -142, -136, -130, -124, -118, -112, -106, -99, -93, + -87, -81, -75, -68, -62, -56, -50, -43, -37, -31, -25, -18, -12, + -6, 0, 6, 12, 18, 25, 31, 37, 43, 50, 56, 62, 68, 75, 81, 87, 93, + 99, 106, 112, 118, 124, 130, 136, 142, 148, 154, 160, 166, 172, + 178, 184, 190, 195, 201, 207, 213, 218, 224, 230, 235, 241, 246, + 252, 257, 263, 268, 273, 279, 284, 289, 294, 299, 304, 310, 314, + 319, 324, 329, 334, 339, 343, 348, 353, 357, 362, 366, 370, 375, + 379, 383, 387, 391, 395, 399, 403, 407, 411, 414, 418, 422, 425, + 429, 432, 435, 439, 442, 445, 448, 451, 454, 457, 460, 462, 465, + 468, 470, 473, 475, 477, 479, 482, 484, 486, 488, 489, 491, 493, + 495, 496, 498, 499, 500, 502, 503, 504, 505, 506, 507, 508, 508, + 509, 510, 510, 511, 511, 511, 511, 511 +}; + +int32_t *COS = SIN + COS_OFF; + + +void draw_cube(int16_t t) { + + static const int16_t edges[] = { + 0, 1, 1, 3, 3, 2, 2, 0, + 1, 5, 0, 4, 2, 6, 3, 7, + 4, 5, 5, 7, 7, 6, 6, 4 + }; + static const int32_t cubeX[] = { + TO_FIX(-1), TO_FIX(-1), TO_FIX( 1), TO_FIX( 1), + TO_FIX(-1), TO_FIX(-1), TO_FIX( 1), TO_FIX( 1) + }; + static const int32_t cubeY[] = { + TO_FIX(-1), TO_FIX( 1), TO_FIX(-1), TO_FIX( 1), + TO_FIX(-1), TO_FIX( 1), TO_FIX(-1), TO_FIX( 1) + }; + static const int32_t cubeZ[] = { + TO_FIX(-1), TO_FIX(-1), TO_FIX(-1), TO_FIX(-1), + TO_FIX( 1), TO_FIX( 1), TO_FIX( 1), TO_FIX( 1) + }; + + int32_t cubeRotX[8]; + int32_t cubeRotY[8]; + int32_t cubeRotZ[8]; + int32_t tempY; + int32_t tempZ; + int32_t cubeProjX[8]; + int32_t cubeProjY[8]; + int16_t i; + int16_t e1; + int16_t e2; + int16_t x1; + int16_t y1; + int16_t x2; + int16_t y2; + uint16_t width; + uint16_t height; + int32_t a = TO_FIX(4); + int32_t scale = TO_FIX(40); + + bitmapGetResolution(&width, &height); + + for (i=0; i<8; ++i) { + // Rotation around Y + cubeRotX[i] = fix_mul(cubeX[i], COS[t % SIN_SIZE]) + fix_mul(cubeZ[i], SIN[t % SIN_SIZE]); + cubeRotY[i] = cubeY[i]; + cubeRotZ[i] = -fix_mul(cubeX[i], SIN[t % SIN_SIZE]) + fix_mul(cubeZ[i], COS[t % SIN_SIZE]); + // Rotation around X + tempY = fix_mul(cubeRotY[i], COS[t % SIN_SIZE]) - fix_mul(cubeRotZ[i], SIN[t % SIN_SIZE]); + tempZ = fix_mul(cubeRotY[i], SIN[t % SIN_SIZE]) + fix_mul(cubeRotZ[i], COS[t % SIN_SIZE]); + cubeRotY[i] = tempY; + cubeRotZ[i] = tempZ; + // Translate further away + cubeRotZ[i] += TO_FIX(4); + // 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]); + } + + for (i=0; i<24; i += 2) { + e1 = edges[i]; + e2 = edges[i + 1]; + x1 = TO_LONG(fix_mul(cubeProjX[e1], scale)) + (width >> 1); + y1 = TO_LONG(fix_mul(cubeProjY[e1], scale)) + (height >> 1); + x2 = TO_LONG(fix_mul(cubeProjX[e2], scale)) + (width >> 1); + y2 = TO_LONG(fix_mul(cubeProjY[e2], scale)) + (height >> 1); + bitmapLine(x1, y1, x2, y2); + } +} + +int main(void) { + int16_t t = 0; + byte p = 0; + + f256Init(); + + resetText(); + bitmapReset(); + + while(1) { + if (p) { + p = 0; + bitmapSetPage(1); + bitmapShowPage(0); + } else { + p = 1; + bitmapSetPage(0); + bitmapShowPage(1); + } + bitmapSetColor(0); + bitmapClear(); + bitmapSetColor(255); + draw_cube(t); + t += 2; + } + + return 0; +} diff --git a/examples/cube/foenixmgr.ini b/examples/cube/foenixmgr.ini new file mode 100644 index 0000000..c6ab319 --- /dev/null +++ b/examples/cube/foenixmgr.ini @@ -0,0 +1,7 @@ +[DEFAULT] +port=/dev/ttyUSB1 +labels=sample.lbl +flash_address=380000 +chunk_size=1024 +cpu=65c02 +data_rate=6000000 \ No newline at end of file diff --git a/examples/cube/run.sh b/examples/cube/run.sh new file mode 100755 index 0000000..97bc536 --- /dev/null +++ b/examples/cube/run.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# +# 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. +# + + +python ../../FoenixMgr/FoenixMgr/fnxmgr.py --run-pgz cube.pgz diff --git a/f256lib/bitmap.c b/f256lib/bitmap.c index 4f0b5e1..e5b5a9a 100644 --- a/f256lib/bitmap.c +++ b/f256lib/bitmap.c @@ -25,6 +25,9 @@ #include "dma.h" +#define EIGHTK 0x2000 + + static uint16_t _MAX_X; static uint16_t _MAX_Y; static uint32_t _PAGE_SIZE; @@ -37,18 +40,23 @@ char error; void bitmapClear(void) { -#ifndef BOOM +#ifdef BOOM dmaFill(_BITMAP_BASE[_page], _PAGE_SIZE, _color); //dma2dFill(_BITMAP_BASE[_page], _MAX_X, _MAX_Y, _MAX_X, _color); #else - uint16_t x; - uint16_t y; + byte block = _BITMAP_BASE[_page] / EIGHTK; + byte x; + uint16_t c; + volatile byte *mem = (byte *)0xa000; - for (y=0; y<_MAX_Y; y++) { - for (x=0; x<_MAX_X; x++) { - bitmapPutPixel(x, y); - } + // Clear full 8k blocks. + for (x=0; x<9; x++) { + POKE(MMU_MEM_BANK_5, block++); + for (c=0; c