diff --git a/build-f256lib.sh b/build-f256lib.sh index 91688f4..129f3b5 100755 --- a/build-f256lib.sh +++ b/build-f256lib.sh @@ -28,6 +28,7 @@ TARGET=f256lib.h cat f256lib/stddclmr.h > ${TARGET} +echo "#ifndef F256LIB_AMALGAMATED_BUILD" >> ${TARGET} echo "#define F256LIB_AMALGAMATED_BUILD" >> ${TARGET} cat f256lib/f_api.h >> ${TARGET} @@ -73,4 +74,5 @@ cat f256lib/f_sprite.c >> ${TARGET} cat f256lib/f_file.c >> ${TARGET} cat f256lib/f_platform.c >> ${TARGET} -echo "#endif" >> ${TARGET} +echo "#endif // F256LIB_IMPLEMENTATION" >> ${TARGET} +echo "#endif // F256LIB_AMALGAMATED_BUILD" >> ${TARGET} diff --git a/examples/a23d2/a2-3d/A2-3D2#066000 b/examples/a23d2/a2-3d/A2-3D2#066000 new file mode 100644 index 0000000..a3b2be1 --- /dev/null +++ b/examples/a23d2/a2-3d/A2-3D2#066000 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6086ef15bc228f0818ee834666916c25d3d18a8b3221754996bd76502702a92f +size 8443 diff --git a/examples/a23d2/build.sh b/examples/a23d2/build.sh new file mode 100755 index 0000000..2e3632b --- /dev/null +++ b/examples/a23d2/build.sh @@ -0,0 +1,75 @@ +#!/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. +# + + +PROJECT=3ddemo + +F256=$(readlink -f $(pwd)/../..) +LLVM=${F256}/llvm-mos +PATH=${LLVM}/bin:${PATH} +CLANG="mos-f256k-clang -I${F256} -I$(pwd)/src -Os" + +# Out-of-tree build to keep things tidy. +[[ -d .builddir ]] && rm -rf .builddir +mkdir -p .builddir + +# Generate overlay data. Do not use relative paths. +${F256}/overlay 5 $(pwd)/.builddir $(pwd)/src + +pushd .builddir + +# Copy Apple ][ binary library A2-3D2 and truncate it to 8k. +# The truncated bits are Apple ][ rendering code, so we don't need it. +cp ../a2-3d/A2-3D2#066000 a2-3d2.bin +truncate -s 8k a2-3d2.bin + +# Compile the 3D scene database generator and run it. +cc -I../src -I${F256} ../tools/scene.c -o scene +./scene + +# Concatinate our embedded binary data into a single file. +cat a2-3d2.bin scene.3d > embedded.bin + +# Compile our code and the A2-3D2 support library. +${CLANG} -c main.c +${CLANG} -c a23d2.c + +# Link! +${CLANG} -T ../f256.ld \ + -Wl,-Map=${PROJECT}.map \ + -o ${PROJECT} \ + main.o a23d2.o + +# Rename results to PGZ. +mv ${PROJECT} ${PROJECT}.pgz + +# Generate debugging goodness. +llvm-nm ${PROJECT}.elf > ${PROJECT}.sym +llvm-objdump --syms -d --print-imm-hex ${PROJECT}.elf > ${PROJECT}.lst +hexdump -C ${PROJECT}.pgz > ${PROJECT}.hex +python ${F256}/pgz-thunk.py ${PROJECT}.pgz + +# Put the PGZ in the main directory. +mv ${PROJECT}.pgz ../. +popd diff --git a/examples/a23d2/f256.ld b/examples/a23d2/f256.ld new file mode 100644 index 0000000..af64ebd --- /dev/null +++ b/examples/a23d2/f256.ld @@ -0,0 +1,116 @@ +/* fake C Stack */ +PROVIDE(__stack = 0xA000); +/* entry point to my program */ +PROVIDE(__f256_start = 0x300); +/* page size of a block of memory */ +PROVIDE(__BLOCK_SIZE = 0x2000); +/* swappable block address */ +PROVIDE(__SLOT_ADDR = 0xA000); + +/* f256k uses first 16 bytes of ZP for mmu control? */ +__rc0 = 0x10; +/* __rc0 = 0xc3; */ +INCLUDE imag-regs.ld +/* +ASSERT(__rc0 == 0x10, "Inconsistent zero page map.") +ASSERT(__rc31 == 0x2f, "Inconsistent zero page map.") +*/ + +MEMORY { + /* kernel uses 0xf0-0xff for parameter passing */ + /* A2-3D2 uses 0x60-0xc2 */ + zp : ORIGIN = __rc31 + 1, LENGTH = 0xF0 - (__rc31 + 1) + /* zp : ORIGIN = 0x10, LENGTH = 80 */ + ram (rw) : ORIGIN = __f256_start, LENGTH = __stack-__f256_start +} + +/* LMAs */ +__block8_lma = ( 8<<24)|__SLOT_ADDR; +__block9_lma = ( 9<<24)|__SLOT_ADDR; +__block10_lma = (10<<24)|__SLOT_ADDR; +__block11_lma = (11<<24)|__SLOT_ADDR; +__block12_lma = (12<<24)|__SLOT_ADDR; +__block13_lma = (13<<24)|__SLOT_ADDR; +__block14_lma = (14<<24)|__SLOT_ADDR; +__block15_lma = (15<<24)|__SLOT_ADDR; +__block16_lma = (16<<24)|__SLOT_ADDR; +__block17_lma = (17<<24)|__SLOT_ADDR; +__block18_lma = (18<<24)|__SLOT_ADDR; +__block19_lma = (19<<24)|__SLOT_ADDR; +__block20_lma = (20<<24)|__SLOT_ADDR; +__block21_lma = (21<<24)|__SLOT_ADDR; +__block22_lma = (22<<24)|__SLOT_ADDR; +__block23_lma = (23<<24)|__SLOT_ADDR; + +/* Stash preloaded binary data */ +__binarydata_lma = 0x54000; /* Block 42 */ +__BINARYDATA_SIZE = 0x2C000; /* Size of A2-3D2, 3D/2D data area, and 2 bitmaps. */ + +MEMORY { + block8 : ORIGIN = __block8_lma, LENGTH = __BLOCK_SIZE + block9 : ORIGIN = __block9_lma, LENGTH = __BLOCK_SIZE + block10 : ORIGIN = __block10_lma, LENGTH = __BLOCK_SIZE + block11 : ORIGIN = __block11_lma, LENGTH = __BLOCK_SIZE + block12 : ORIGIN = __block12_lma, LENGTH = __BLOCK_SIZE + block13 : ORIGIN = __block13_lma, LENGTH = __BLOCK_SIZE + block14 : ORIGIN = __block14_lma, LENGTH = __BLOCK_SIZE + block15 : ORIGIN = __block15_lma, LENGTH = __BLOCK_SIZE + block16 : ORIGIN = __block16_lma, LENGTH = __BLOCK_SIZE + block17 : ORIGIN = __block17_lma, LENGTH = __BLOCK_SIZE + block18 : ORIGIN = __block18_lma, LENGTH = __BLOCK_SIZE + block19 : ORIGIN = __block19_lma, LENGTH = __BLOCK_SIZE + block20 : ORIGIN = __block20_lma, LENGTH = __BLOCK_SIZE + block21 : ORIGIN = __block21_lma, LENGTH = __BLOCK_SIZE + block22 : ORIGIN = __block22_lma, LENGTH = __BLOCK_SIZE + block23 : ORIGIN = __block23_lma, LENGTH = __BLOCK_SIZE + binarydata : ORIGIN = __binarydata_lma, LENGTH = __BINARYDATA_SIZE +} + +REGION_ALIAS("c_writeable", ram) +REGION_ALIAS("c_readonly", ram) + +SECTIONS { + INCLUDE c.ld + .block8 : { *(.block8 .block8.*) } >block8 end_block8 = .; + .block9 : { *(.block9 .block9.*) } >block9 end_block9 = .; + .block10 : { *(.block10 .block10.*) } >block10 end_block10 = .; + .block11 : { *(.block11 .block11.*) } >block11 end_block11 = .; + .block12 : { *(.block12 .block12.*) } >block12 end_block12 = .; + .block13 : { *(.block13 .block13.*) } >block13 end_block13 = .; + .block14 : { *(.block14 .block14.*) } >block14 end_block14 = .; + .block15 : { *(.block15 .block15.*) } >block15 end_block15 = .; + .block16 : { *(.block16 .block16.*) } >block16 end_block16 = .; + .block17 : { *(.block17 .block17.*) } >block17 end_block17 = .; + .block18 : { *(.block18 .block18.*) } >block18 end_block18 = .; + .block19 : { *(.block19 .block19.*) } >block19 end_block19 = .; + .block20 : { *(.block20 .block20.*) } >block20 end_block20 = .; + .block21 : { *(.block21 .block21.*) } >block21 end_block21 = .; + .block22 : { *(.block22 .block22.*) } >block22 end_block22 = .; + .block23 : { *(.block23 .block23.*) } >block23 end_block23 = .; + .binarydata : { *(.binarydata .binarydata.*) } >binarydata end_binarydata = .; +} + +OUTPUT_FORMAT { + BYTE(0x5A) /* pgZ */ + + /* RAM Segment */ + SHORT(ORIGIN(ram)) /* where to load it, 24 bits */ + BYTE(0x00) + SHORT(__bss_start-ORIGIN(ram)) /* size to load */ + BYTE(0x00) + TRIM(ram) + + /* Overlay Segments */ + INCLUDE output.ld + + /* Binary Data */ + SHORT(ORIGIN(binarydata)) + BYTE(ORIGIN(binarydata)>>16) + SHORT(end_binarydata - __binarydata_lma) + BYTE((end_binarydata - __binarydata_lma)>>16) + TRIM(binarydata) + + /* Launch the program, at _start */ + SHORT(_start) + LONG(0) +} diff --git a/examples/a23d2/run.sh b/examples/a23d2/run.sh new file mode 100755 index 0000000..85e55ec --- /dev/null +++ b/examples/a23d2/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 3ddemo.pgz diff --git a/examples/a23d2/src/a23d2.c b/examples/a23d2/src/a23d2.c new file mode 100644 index 0000000..859de75 --- /dev/null +++ b/examples/a23d2/src/a23d2.c @@ -0,0 +1,178 @@ +/* + * 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 "a23d2.h" + +#include // For memcopy + + +cameraT *_camera = (cameraT *)0x200; // Simulation copy of camera. +cameraT *_cameraInDatabase; + +uint16_t _drawlist; +uint16_t _drawlistInDatabase; + +byte *_pointer; +uint16_t _bytes; +uint8_t _x1; +uint8_t _y1; +uint8_t _x2; +uint8_t _y2; +bool _useColor; +byte _mmu; +byte _ram; + + +#define SEGMENT_A23D2 + + +// There's a lot of global use in here. We can't use the virtual stack. + + +void a23d2Draw(void) { + + _pointer = (byte *)_drawlist; + + // Move our 3D/2D data buffer at 0x56000 into slot 4. + POKE(MMU_MEM_BANK_4, DATABASE_FAR_BLOCK); + + while (true) { + switch (*_pointer++) { + + // Line. + case (byte)LIN2D: + _x1 = (uint8_t)((int8_t)(*_pointer++) + 128); + _y1 = 255 - (uint8_t)((int8_t)(*_pointer++) + 128); + _x2 = (uint8_t)((int8_t)(*_pointer++) + 128); + _y2 = 255 - (uint8_t)((int8_t)(*_pointer++) + 128); + bitmapLine(_x1, _y1, _x2, _y2); + continue; + + // Point. + case (byte)PNT2D: + _x1 = (uint8_t)((int8_t)(*_pointer++) + 128); + _y1 = 255 - (uint8_t)((int8_t)(*_pointer++) + 128); + bitmapPutPixel(_x1, _y1); + continue; + + // Set Color. + case (byte)STCOL: + _x1 = (int8_t)(*_pointer++); + if (_useColor) bitmapSetColor(_x1); + continue; + + // Set Resolution. + case (byte)SRES: + // Eat this byte. We don't need it. + _pointer++; + continue; + + // End. + case (byte)END: + break; + + } + break; + } + + // Restore memory map. + POKE(MMU_MEM_BANK_4, 4); +} + + +void a23d2Init(void) { + // We need to manually page 0x54000 into 0x6000. + // This isn't actually large enough for A2-3D2 but what we should only + // lose Apple ][ stuff we're not using anyway. + POKE(MMU_MEM_BANK_3, A23D2_FAR_BLOCK); + + // We're going to clobber from 0x80fb to 0x8101. Back it up. + memcpy((byte *)0x2f7, (byte *)0x80fb, 0x06); + + // Initialize A2-3D2 so we can use the "fast entry point" (NXTPT) when rendering. + _bytes = 0; + _pointer = (byte *)0x80fb; // Standard location for test database in A2-3D2. + _pointer[_bytes++] = SCRSZ; // Screen size. 256x240. Center is 0,0. + _pointer[_bytes++] = 255; + _pointer[_bytes++] = 239; + _pointer[_bytes++] = 0; + _pointer[_bytes++] = 0; + _pointer[_bytes++] = END; // Setup complete! + + asm("jsr 0x606c"); // Call ENTRYS. This preserves the ZP for us. + + // Put back the RAM we clobbered. + memcpy((byte *)0x80fb, (byte *)0x2f7, 0x06); + + // Move our 3D/2D data buffer at 0x56000 into slot 4. + POKE(MMU_MEM_BANK_4, DATABASE_FAR_BLOCK); + + // Set up drawlists. + _drawlistInDatabase = DATABASE + 1; // First value after ARRAY in near memory. + POKE(DRAWLIST_P0, END); + POKE(DRAWLIST_P1, END); + + // Set up camera. + _cameraInDatabase = (cameraT *)(DATABASE + 4); // First value after EYE in near memory. + _camera->x = _cameraInDatabase->x; + _camera->y = _cameraInDatabase->y; + _camera->z = _cameraInDatabase->z; + _camera->p = _cameraInDatabase->p; + _camera->b = _cameraInDatabase->b; + _camera->h = _cameraInDatabase->h; + + // Restore memory map. + POKE(MMU_MEM_BANK_4, 4); + POKE(MMU_MEM_BANK_3, 3); +} + + +void a23d2Render(void) { + // We need to manually page 0x54000 into 0x6000. + // This isn't actually large enough for A2-3D2 but what we should only + // lose Apple ][ stuff we're not using anyway. + POKE(MMU_MEM_BANK_3, A23D2_FAR_BLOCK); + + // Move our 3D/2D data buffer at 0x56000 into slot 4. + POKE(MMU_MEM_BANK_4, DATABASE_FAR_BLOCK); + + // Update drawlist. + POKEW(_drawlistInDatabase, _drawlist); + + // Update camera position. + _cameraInDatabase->x = _camera->x; + _cameraInDatabase->y = _camera->y; + _cameraInDatabase->z = _camera->z; + _cameraInDatabase->p = _camera->p; + _cameraInDatabase->b = _camera->b; + _cameraInDatabase->h = _camera->h; + + memcpy((byte *)0x29d, (byte *)0x60, 0x62); // Save the ZP we're going to clobber. + POKEW(0x9b, DATABASE); // Set IBP. + asm("jsr 0x6118":::"a","x","y","c","v"); // Call NXTPT. + memcpy((byte *)0x60, (byte *)0x29d, 0x62); // Put the ZP back. + + // Restore memory map. + POKE(MMU_MEM_BANK_4, 4); + POKE(MMU_MEM_BANK_3, 3); +} diff --git a/examples/a23d2/src/a23d2.h b/examples/a23d2/src/a23d2.h new file mode 100644 index 0000000..c66ae2a --- /dev/null +++ b/examples/a23d2/src/a23d2.h @@ -0,0 +1,111 @@ +/* + * 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. + */ + + +#ifdef __F256K__ +#include "f256lib.h" +#else +#include +#include +typedef uint8_t byte; +#endif + + +#define A23D2_FAR_BLOCK 42 +#define DATABASE_FAR_BLOCK 43 + +#define DATABASE_FAR 0x56000 +#define DRAWLIST_P0_FAR 0x57000 +#define DRAWLIST_P1_FAR 0x57800 + +#define DATABASE 0x8000 +#define DRAWLIST_P0 0x9000 +#define DRAWLIST_P1 0x9800 + + +// A2-3D1 Commands. Commented out items are Apple ][ only. +#define PNT 0x00 // xLSB, xMSB, yLSB, yMSB, zLSB, zMSB - Define 3D Point +#define SPNT 0x01 // xLSB, xMSB, yLSB, yMSB, zLSB, zMSB - Define 3D Start Point +#define CPNT 0x02 // xLSB, xMSB, yLSB, yMSB, zLSB, zMSB - Define 3D Continue Point +#define RAY 0x03 // xLSB, xMSB, yLSB, yMSB, zLSB, zMSB - Define 3D Ray +#define CLPSW 0x04 // N - Define Clipper (0=off, 1=on) +#define EYE 0x05 // xLSB, xMSB, yLSB, yMSB, zLSB, zMSB, P, B, H - Define 3D Eye/Camera +#define LIN2D 0x06 // X1, Y1, X2, Y2 - Draw 2D Line +//#define DISP 0x07 // N - Display Select (50=set graphics, 51=set text, 52=clear mixed, 53=set mixed, 54=set page 1, 55=set page 2, 56=clear hi-res, 57=set hi-res) +//#define ERAS 0x08 // N - Erase Screen (0=erase page 1, 1=erase page 2, 2=fill page 1, 3=fill page 2) +//#define DRAW 0x09 // N - Select Draw Page (0=page 1, 1=page 2) +#define PNT2D 0x0a // X1, Y1 - Draw 2D Point +#define JMP 0x0b // LSB, MSB - Interpretive Jump +//#define LMODE 0x0c // N - Line Drawing Mode (0=solid, 1=xor) +#define ARRAY 0x0d // LSB, MSB - Enable Output Array +#define SCRSZ 0x0e // WIDTH, HEIGHT, xCENTER, yCENTER - Define Screen Size +#define FIELD 0x0f // xLSB, xMSB, yLSB, yMSB, zLSB, zMSB - Field of View Selection +#define INIT 0x10 // Easy Init +#define NOP 0x11 // No Operation + +// A2-3D2 Commands. Commented out items are Apple ][ only. +#define STCOL 0x12 // COL - Set Color +#define ICALL 0x13 // STAT, LOC, ADDR - Independent Object Call +#define SRES 0x14 // RES - Set Resolution (0=140x192, 1=280x192) +//#define HLIN 0x15 // x1L, x1H, y1, x2L, x2H, y2 - Hi-Res (280x192) Line 2D +//#define SHRB 0x16 // xL, xH, y - Set Hi-Res Bias +//#define HLIN2 0x17 // x1, y1, x2, y2 - Hi-Res (x limited) Line 2D +//#define HPNT 0x18 // xL, xH, y - Hi-Res (280x192) Point 2D +//#define HPNT2 0x19 // x, y - Hi-Res (x limited) Point 2D +#define SKIP 0x1a // SIZE, STATUS - Skip Segment +//#define PAUS 0x1b // TIME - Pause for TIME/5ths of a Second +#define SET323 0x1c // LSB, MSB - Set 3D to 3D Array Address +#define GN323 0x1d // STATUS - Set 3D to 3D Status +#define END 0x79 // End of Database + + +typedef struct cameraS { + int16_t x; + int16_t y; + int16_t z; + byte p; + byte b; + byte h; +} cameraT; + + +extern cameraT *_camera; +extern cameraT *_cameraInDatabase; + +extern uint16_t _drawlist; +extern uint16_t _drawlistInDatabase; + +extern byte *_pointer; +extern uint16_t _bytes; +extern uint8_t _x1; +extern uint8_t _y1; +extern uint8_t _x2; +extern uint8_t _y2; +extern bool _useColor; +extern byte _mmu; +extern byte _ram; + + +// NOTE: +// There are no function prototypes in this header. +// This library lives in it's own overlay segment and the overlay tool +// will generate prototypes as well as trampoline macros for us. diff --git a/examples/a23d2/src/main.c b/examples/a23d2/src/main.c new file mode 100644 index 0000000..28aed62 --- /dev/null +++ b/examples/a23d2/src/main.c @@ -0,0 +1,230 @@ +/* + * 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. + */ + +/* + * Memory Map: + * + * Far Heap (upper 448k): + * + * 0x7ffff - Top of far heap / End of bitmap page 1 + * - Bitmap page is 0x14000 (81920 bytes) + * 0x6c000 - Start of bitmap page 1 + * 0x6bfff - End of bitmap page 2 + * - Bitmap page is 0x14000 (81920 bytes) + * 0x58000 - Start of bitmap page 2 + * 0x57fff - End of A2-3D2 and data to be used in slots 3 and 2/4 below + * - ... + * 0x54000 - Start of A2-3D2 and data to be used in slots 3 and 2/4 below + * - 57344 bytes free + * 0x45fff - End of overlay code + * - ... + * 0x10000 - Bottom of far heap / Start of overlay code + * + * + * Near Heap (lower 64k): + * + * 0xffff - Top of near heap + * - ... + * 0xe000 - Microkernel + * - ... + * 0xc000 - I/O and microkernel + * - ... + * 0xa000 - Overlay code + * 0x9fff - Top of virtual stack + * - ... + * 0x8000 - Program code / 3D/2D data + * - ... + * 0x6000 - Program code / 3D library + * - ... + * 0x0300 - Start of program code + * 0x02ff - End of program arguments / data storage + * - ... (We're going to overwrite this!) + * 0x0200 - Start of program arguments / data storage + * 0x01ff - Top of CPU stack space + * - ... + * 0x0100 - Bottom of CPU stack space + * 0x00ff - End of microkernel use + * - ... + * 0x00f0 - Start of microkernel use + * - 46 bytes free + * 0x00c2 - End of A2-3D2 use + * - ... + * 0x0060 - Start of A2-3D2 use + * - 49 bytes free + * 0x002f - llvm virtual register 31 + * - ... + * 0x0010 - llvm virtual register 0 + * 0x000f - MMU_MEM_BANK_7 + * - ... + * 0x0008 - MMU_MEM_BANK_0 + * - 7 bytes free + * 0x0001 - MMU_IO_CTRL + * 0x0000 - MMU_MEM_CTRL + * + * + * Calling the 3D Renderer: + * + * The MMU splits the near heap into 8k "slots" that 8k "blocks" of far heap + * can be mapped into. f256lib, by default, sets the near heap up as + * follows: + * + * 0xe000 - Slot 7 - Microkernel + * 0xc000 - Slot 6 - I/O and Microkernel + * 0xa000 - Slot 5 - Code Overlay Region + * 0x8000 - Slot 4 - Program Code + * 0x6000 - Slot 3 - Program Code + * 0x4000 - Slot 2 - Program Code + * 0x2000 - Slot 1 - Program Code + * 0x0000 - Slot 0 - Zero Page & Program Code + * + * Our 3D library, subLOGIC's A2-3D2, was designed to be run on an Apple ][. + * The Apple ][ has two high-resolution video pages in the middle of the + * memory map and A2-3D2 loads at 0x6000 immediately after the second video + * page. This makes sense on the Apple. On the Foenix, it's in the way at + * slot 3. The library also needs a 3D scene database and outputs an array + * of 2D drawing instructions. Given the size of A2-3D2 this pushes our + * memory usage up into slot 4. This leaves slots 0 to 2 for the simulator. + * That's less than 24k. Not good. + * + * We're going to place the 3D library and related data in the far heap and + * manually swap them in using the MMU when we need to render the scene. To + * do this, we need to ensure we're not currently executing code from + * somewhere in the slot 2 to 4 range. To accomplish this, all the functions + * that deal with A2-3D2 are placed in an overlay. This ensures whatever + * code calls into slots 2 to 4 has a program counter between 0xa000 and + * 0xbfff - well out of the way of the 3D stuff. + * + * The last thing to worry about is data needed by both the simulator and + * A2-3D2. This is basically only the camera position and rotation. These + * 10 bytes will be stored directly into RAM from 0x200 to 0x20a overwriting + * any command line arguments that may have been in memory. + * + */ + + +#define WITHOUT_FILE +#define WITHOUT_SPRITE +#define WITHOUT_TILE +#define F256LIB_IMPLEMENTATION +#include "f256lib.h" + +#include "a23d2.h" + + +/* + * embedded.bin is loaded at 0x54000: + * + * 8k a2-3d2.bin @ 0x54000 + * 8k scene.3d @ 0x56000 + * + */ +EMBED(".binarydata.embedded", embedded, "embedded.bin"); + + +void runSimulation(void) { + bool pageZero; + + // Which page is visible? + pageZero = true; + + // Draw it! + while (true) { + + // Flip pages. + if (pageZero) { + // Looking at bitmap 0. + pageZero = false; + bitmapSetActive(1); + bitmapSetVisible(0, true); + bitmapSetVisible(1, false); + _drawlist = DRAWLIST_P1; + } else { + // Looking at bitmap 1. + pageZero = true; + bitmapSetActive(0); + bitmapSetVisible(1, true); + bitmapSetVisible(0, false); + _drawlist = DRAWLIST_P0; + } + + // Erase old scene. + bitmapSetColor(0); + _useColor = false; + a23d2Draw(); + + // Draw new scene. + a23d2Render(); + _useColor = true; + a23d2Draw(); + + // Move camera. + _camera->p += 1; // Change pitch angle. + _camera->b += 2; // Change bank angle. + _camera->h += 3; // Change heading angle. + } + +} + + +int main(int argc, char *argv[]) { + byte c; + byte ega[16][3] = { + { 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0xaa }, + { 0x00, 0xaa, 0x00 }, + { 0x00, 0xaa, 0xaa }, + { 0xaa, 0x00, 0x00 }, + { 0xaa, 0x00, 0xaa }, + { 0xaa, 0x55, 0x00 }, + { 0xaa, 0xaa, 0xaa }, + { 0x55, 0x55, 0x55 }, + { 0x55, 0x55, 0xff }, + { 0x55, 0xff, 0x55 }, + { 0x55, 0xff, 0xff }, + { 0xff, 0x55, 0x55 }, + { 0xff, 0x55, 0xff }, + { 0xff, 0xff, 0x55 }, + { 0xff, 0xff, 0xff } + }; + + // Load EGA palette into CLUT0. + for (c=0; c<16; c++) graphicsDefineColor(0, c, ega[c][0], ega[c][1], ega[c][2]); + + a23d2Init(); + + // Set up bitmap planes. + for (c=0; c<2; c++) { + // Clear screen. + bitmapSetActive(c); + bitmapSetColor(0); + bitmapClear(); + // 3D Viewport edge. + bitmapSetColor(14); + bitmapLine(256, 0, 256, 239); + } + bitmapSetVisible(0, true); + bitmapSetVisible(1, false); + + runSimulation(); + + return 0; +} diff --git a/examples/a23d2/tools/scene.c b/examples/a23d2/tools/scene.c new file mode 100644 index 0000000..87b75ec --- /dev/null +++ b/examples/a23d2/tools/scene.c @@ -0,0 +1,96 @@ +/* + * 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 +#include +#include "a23d2.h" + + +uint8_t db[8192] = { 0 }; +uint16_t bytes = 0; + + +void cube(void) { + int16_t i = 0; + uint8_t scene[] = { + STCOL, 0x04, // Red + SPNT, 0x00, 0xff, 0x00, 0xff, 0x00, 0x03, // Cube + CPNT, 0x00, 0x01, 0x00, 0xff, 0x00, 0x03, + CPNT, 0x00, 0x01, 0x00, 0x01, 0x00, 0x03, + CPNT, 0x00, 0xff, 0x00, 0x01, 0x00, 0x03, + CPNT, 0x00, 0xff, 0x00, 0xff, 0x00, 0x03, + CPNT, 0x00, 0xff, 0x00, 0xff, 0x00, 0x05, + CPNT, 0x00, 0x01, 0x00, 0xff, 0x00, 0x05, + RAY, 0x00, 0x01, 0x00, 0xff, 0x00, 0x03, + CPNT, 0x00, 0x01, 0x00, 0x01, 0x00, 0x05, + RAY, 0x00, 0x01, 0x00, 0x01, 0x00, 0x03, + CPNT, 0x00, 0xff, 0x00, 0x01, 0x00, 0x05, + RAY, 0x00, 0xff, 0x00, 0x01, 0x00, 0x03, + CPNT, 0x00, 0xff, 0x00, 0xff, 0x00, 0x05, + SPNT, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, // Edge Line + CPNT, 0x00, 0x00, 0x80, 0x00, 0x00, 0x03, + END + }; + + while (scene[i] != END) { + db[bytes++] = scene[i++]; + } +} + + +int main(int argc, char *argv[]) { + FILE *out; + + // All scene databases need to begin with the ARRAY and EYE records. + // The CLPSW clipping setting is up to you. :-) + + db[bytes++] = ARRAY; // Will be filled in by the program. + db[bytes++] = 0; + db[bytes++] = 0; + + db[bytes++] = EYE; // Will be filled in by the program. + db[bytes++] = 0x00; // X + db[bytes++] = 0x00; + db[bytes++] = 0x00; // Y + db[bytes++] = 0x00; + db[bytes++] = 0x00; // Z + db[bytes++] = 0x00; + db[bytes++] = 0x00; // P + db[bytes++] = 0x00; // B + db[bytes++] = 0x00; // H + + db[bytes++] = CLPSW; + db[bytes++] = 0x00; + + cube(); + + db[bytes++] = END; + + out = fopen("scene.3d", "wb"); + if (out) { + fwrite(db, 1, 8192, out); + fclose(out); + } + + return 0; +} diff --git a/examples/cube-pre/foenixmgr.ini b/examples/cube-pre/foenixmgr.ini deleted file mode 100644 index c6ab319..0000000 --- a/examples/cube-pre/foenixmgr.ini +++ /dev/null @@ -1,7 +0,0 @@ -[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/foenixmgr.ini b/examples/cube/foenixmgr.ini deleted file mode 100644 index c6ab319..0000000 --- a/examples/cube/foenixmgr.ini +++ /dev/null @@ -1,7 +0,0 @@ -[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/lines/foenixmgr.ini b/examples/lines/foenixmgr.ini deleted file mode 100644 index c6ab319..0000000 --- a/examples/lines/foenixmgr.ini +++ /dev/null @@ -1,7 +0,0 @@ -[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/overlay/foenixmgr.ini b/examples/overlay/foenixmgr.ini deleted file mode 100644 index c6ab319..0000000 --- a/examples/overlay/foenixmgr.ini +++ /dev/null @@ -1,7 +0,0 @@ -[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/pgztest/foenixmgr.ini b/examples/pgztest/foenixmgr.ini deleted file mode 100644 index c6ab319..0000000 --- a/examples/pgztest/foenixmgr.ini +++ /dev/null @@ -1,7 +0,0 @@ -[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/pgztest/pgztest.c b/examples/pgztest/pgztest.c index b42c225..7faaa41 100644 --- a/examples/pgztest/pgztest.c +++ b/examples/pgztest/pgztest.c @@ -25,6 +25,19 @@ #include "../../f256lib.h" +/* + * Add return values to overlay tool. + * Overlay tool may need to generate prototypes for multiple file programs. + * Move bitmap memory to top of far ram. + * Add cc65 support. + * Move docs to top of amalgamated build. + * Check out https://github.com/econtrerasd/VickyGraph/tree/main/Calypsi-65816-grfdemo/src + * Find way to create Windows version binaries. + * Docs! + * + */ + + void dirtest(void) { DIR *dir; diff --git a/examples/sprites/foenixmgr.ini b/examples/sprites/foenixmgr.ini deleted file mode 100644 index c6ab319..0000000 --- a/examples/sprites/foenixmgr.ini +++ /dev/null @@ -1,7 +0,0 @@ -[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/tilemap/foenixmgr.ini b/examples/tilemap/foenixmgr.ini deleted file mode 100644 index c6ab319..0000000 --- a/examples/tilemap/foenixmgr.ini +++ /dev/null @@ -1,7 +0,0 @@ -[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/f256lib/f256.c b/f256lib/f256.c index a97f3a9..57abeda 100644 --- a/f256lib/f256.c +++ b/f256lib/f256.c @@ -58,7 +58,7 @@ void f256Init(void) { #ifndef WITHOUT_KERNEL kernelReset(); #endif -#if !(defined WITHOUT_BITMAP || defined WITHOUT_TILE || defined WITHOUT_SPRITE) +#ifndef WITHOUT_GRAPHICS graphicsReset(); #endif #ifndef WITHOUT_TEXT diff --git a/f256lib/f256.h b/f256lib/f256.h index 842dbb7..fa23486 100644 --- a/f256lib/f256.h +++ b/f256lib/f256.h @@ -125,31 +125,18 @@ typedef unsigned char bool; // Near memory slot to use for far memory swapping. #ifndef SWAP_SLOT -#define SWAP_SLOT MMU_MEM_BANK_5 +#define SWAP_SLOT MMU_MEM_BANK_7 #endif -// This is an attempt to allow us to free up slot 5 and use other slots -// for swapping RAM in and out. ***TODO*** Currently, it does not work. -#if SWAP_SLOT == MMU_MEM_BANK_6 +#if SWAP_SLOT == MMU_MEM_BANK_7 -#define SWAP_IO_SETUP() \ - byte sios_mmu = PEEK(MMU_IO_CTRL); \ - byte sios_ram = PEEK(MMU_MEM_BANK_6); \ - ({ \ - asm("sei"); \ - POKE(MMU_IO_CTRL, 4); \ - }) +#define SWAP_IO_SETUP() \ + byte sios_ram = PEEK(MMU_MEM_BANK_7); \ + asm("sei"); -#define SWAP_IO_SHUTDOWN() ({ \ - POKE(MMU_MEM_BANK_6, sios_ram); \ - POKE(MMU_IO_CTRL, sios_mmu); \ - asm("cli"); \ -}) - -#elif SWAP_SLOT == MMU_MEM_BANK_7 - -#define SWAP_IO_SETUP() asm("sei"); -#define SWAP_IO_SHUTDOWN() asm("cli"); +#define SWAP_IO_SHUTDOWN() \ + POKE(MMU_MEM_BANK_7, sios_ram); \ + asm("cli"); #else @@ -168,7 +155,7 @@ typedef unsigned char bool; // Things not in the Merlin defs. -#define EIGHTK 0x2000 +#define EIGHTK 0x2000 #define TEXT_MATRIX 0xc000 // I/O Page 2 @@ -202,6 +189,25 @@ typedef struct colorS { } colorT; +// Allow embedding binary data into program +#define IBSTR2(x) #x +#define IBSTR(x) IBSTR2(x) +#define EMBED(INCBIN_SECTION, name, file) \ + __asm__(".section " INCBIN_SECTION ",\"aR\" \n" \ + ".global incbin_" IBSTR(name) "_start\n" \ + ".balign 16\n" \ + "incbin_" IBSTR(name) "_start:\n" \ + ".incbin \"" file "\"\n" \ + \ + ".global incbin_" IBSTR(name) "_end\n" \ + ".balign 1\n" \ + "incbin_" IBSTR(name) "_end:\n" \ + ".byte 0\n" \ + ); \ + extern __attribute__((aligned(16))) const char incbin_ ## name ## _start[]; \ + extern const char incbin_ ## name ## _end[] + + // Single-byte #define PEEK(addy) ((byte)*(volatile byte *)(addy)) #define POKE(addy, value) (*(volatile byte *)(addy) = (value)) @@ -219,8 +225,8 @@ typedef struct colorS { #define POKED(addy,value) (*(volatile uint32_t *)(addy) = (value)) // Bit fun. -#define LOW_BYTE(v) ((byte)(x)) -#define HIGH_BYTE(v) ((byte)(((uint16_t)(x)) >> 8)) +#define LOW_BYTE(x) ((byte)(x)) +#define HIGH_BYTE(x) ((byte)(((uint16_t)(x)) >> 8)) #define SWAP_NIBBLES(x) ((x & 0x0F) << 4 | (x & 0xF0) >> 4) #define SWAP_UINT16(x) (((x) >> 8) | ((x) << 8)) #define CHECK_BIT(x, pos) (x & (1UL << pos)) diff --git a/f256lib/f_bitmap.c b/f256lib/f_bitmap.c index fe833a4..f2c1f7d 100644 --- a/f256lib/f_bitmap.c +++ b/f256lib/f_bitmap.c @@ -36,10 +36,17 @@ 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 _active; // Current drawing page. +static byte _active; // Current drawing page. +// uint32_t address = _BITMAP_BASE[_active] + (y * _MAX_X + (int32_t)x); \ -#define bitmapPutPixelIOSet(x, y) FAR_POKE((_BITMAP_BASE[_active] + mathUnsignedAddition(mathUnsignedMultiply(y, _MAX_X), (int32_t)x)), _color) +#define bitmapPutPixelIOSet(x, y) ({ \ + uint32_t address = _BITMAP_BASE[_active] + mathUnsignedAddition(mathUnsignedMultiply(y, _MAX_X), (int32_t)x); \ + byte block = address / EIGHTK; \ + address &= 0x1FFF; \ + POKE(SWAP_SLOT, block); \ + POKE(SWAP_ADDR + address, _color); \ +}) void bitmapClear(void) { @@ -64,7 +71,6 @@ void bitmapClear(void) { for (c=0; c<5120; c++) mem[c] = _color; SWAP_RESTORE_SLOT(); - SWAP_IO_SHUTDOWN(); #endif } @@ -137,7 +143,6 @@ void bitmapLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) { } SWAP_RESTORE_SLOT(); - SWAP_IO_SHUTDOWN(); } @@ -166,11 +171,12 @@ void bitmapReset(void) { // Fractional pageBlock. Round up. pageBlocks++; } - realSize = mathUnsignedMultiply(pageBlocks, EIGHTK); + realSize = mathUnsignedMultiply(pageBlocks, EIGHTK); // Works out to 80k or 0x14000. - _BITMAP_BASE[0] = 0x10000; - _BITMAP_BASE[1] = mathUnsignedAddition(_BITMAP_BASE[0], realSize); // Page 2 = 0x24000 - _BITMAP_BASE[2] = mathUnsignedAddition(_BITMAP_BASE[1], realSize); // Page 3 = 0x38000 + // Bitmaps start at the top of far memory and work downwards for each additional page. + _BITMAP_BASE[0] = 0x080000 - realSize; // Page 1 = 0x6c000 + _BITMAP_BASE[1] = _BITMAP_BASE[0] - realSize; // Page 2 = 0x58000 + _BITMAP_BASE[2] = _BITMAP_BASE[1] - realSize; // Page 3 = 0x44000 /* textPrint("\nbase0 = "); textPrintInt(_BITMAP_BASE[0]); diff --git a/f256lib/f_dma.c b/f256lib/f_dma.c index 87d39e4..954146f 100644 --- a/f256lib/f_dma.c +++ b/f256lib/f_dma.c @@ -33,27 +33,39 @@ static void dmaWait(void); void dmaFill(uint32_t start, uint32_t length, byte value) { + while (PEEKW(RAST_ROW_L) != 482); // Wait for VBL. + POKE(DMA_CTRL, DMA_CTRL_FILL | DMA_CTRL_ENABLE); POKE(DMA_FILL_VAL, value); POKEA(DMA_DST_ADDR, start); POKEA(DMA_COUNT, length); POKE(DMA_CTRL, PEEK(DMA_CTRL) | DMA_CTRL_START); - dmaWait(); +// dmaWait(); } void dma2dFill(uint32_t start, uint16_t width, uint16_t height, uint16_t stride, byte value) { - POKE(DMA_CTRL, DMA_CTRL_2D | DMA_CTRL_ENABLE); + while (PEEKW(RAST_ROW_L) != 482); // Wait for VBL. + + asm("sei"); + POKE(DMA_CTRL, DMA_CTRL_2D | DMA_CTRL_FILL | DMA_CTRL_ENABLE); POKE(DMA_FILL_VAL, value); POKEA(DMA_DST_ADDR, start); POKEW(DMA_WIDTH, width); POKEW(DMA_HEIGHT, height); POKEW(DMA_STRIDE_DST, stride); POKE(DMA_CTRL, PEEK(DMA_CTRL) | DMA_CTRL_START); + asm("nop"); + asm("nop"); + asm("nop"); + asm("nop"); + asm("nop"); + asm("nop"); + asm("cli"); - dmaWait(); +// dmaWait(); } diff --git a/f256lib/f_text.c b/f256lib/f_text.c index 126ea6d..df741f5 100644 --- a/f256lib/f_text.c +++ b/f256lib/f_text.c @@ -30,6 +30,7 @@ #endif +//***FIX*** IIgs colors aren't as useful as EGA colors. colorT textColors[16] = { { 0x00, 0x00, 0x00 }, // 0 Black { 0xdd, 0x00, 0x33 }, // 1 Deep Red diff --git a/tools/overlay/overlay.c b/tools/overlay/overlay.c index 6f3dd8e..bca43cb 100644 --- a/tools/overlay/overlay.c +++ b/tools/overlay/overlay.c @@ -47,6 +47,8 @@ void trimEnd(char *string); void findBank(char *name) { int x; + printf("Found Segment: %s\n", name); + // Is this the MAIN segment? if (strcmp(name, "MAIN") == 0) { _currentBank = 0; @@ -83,6 +85,7 @@ void parseCFile(char *filename, char *targetFile, FILE *trampoline, char *trampo char *b; bool found; int x; + int line = 1; int comments = 0; bool inComment = false; int brackets = 0; @@ -102,6 +105,9 @@ void parseCFile(char *filename, char *targetFile, FILE *trampoline, char *trampo * Someone should fix it. :-) */ + // Always start in the lower 64k. + _currentBank = 0; + in = fopen(filename, "rt"); if (in == NULL) { fclose(trampoline); @@ -132,10 +138,10 @@ void parseCFile(char *filename, char *targetFile, FILE *trampoline, char *trampo if ((c == '/') && (pos > 0) && (buffer[pos-1] == '/')) inComment = true; // Look for '/*' comment start. - if ((c == '*') && (pos > 0) && (buffer[pos-1] == '/')) comments++; + if ((c == '*') && (pos > 0) && (buffer[pos-1] == '/') && !inComment) comments++; // Look for '*/' comment end. - if ((c == '/') && (pos > 0) && (buffer[pos-1] == '*')) comments--; + if ((c == '/') && (pos > 0) && (buffer[pos-1] == '*') && !inComment) comments--; } // Count brackets so we know if we're inside a function or not. @@ -150,6 +156,8 @@ void parseCFile(char *filename, char *targetFile, FILE *trampoline, char *trampo // End of line? if ((c == 13) || (c == 10)) { + line++; + inComment = false; crSinceStart++; @@ -191,6 +199,8 @@ void parseCFile(char *filename, char *targetFile, FILE *trampoline, char *trampo *b = '('; // Write out new function definition. fprintf(out, "%s%cFAR%d_%s {\n", buffer, found ? '*' : ' ', _currentBank, start); + // Create trampoline prototype. + fprintf(trampoline, "%s%cFAR%d_%s;\n", buffer, found ? '*' : ' ', _currentBank, start); // Create trampoline macro. fprintf(trampoline, "#define %s(...) ({ \\\n" "\t\tunsigned char ___mmu = (unsigned char)*(volatile unsigned char *)%#06x; \\\n"